Skip to content

Metric.query

Read what your ads, posts and emails did, across every connected account.

Action class
None
Approval
Runs on its own
Emits
Metric.queried
Price
Free
POST https://api.sb/{your-domain}/metrics/query

Reads a number from your Events as a trend, funnel, retention curve or path, split by any property. The hub’s definition of Metric.query.

Inputs

NameTypeDefaultMeaning
metricMetricnullThe Metric to read; omitted, the query names Events directly.
shapestringRequiredThe analysis to run.
breakdownstringnullThe property to split by, such as an Organization or a Motion. Unset: one row for the whole window.
windowstring'30d'The time range, such as 30d. Unset: the last 30 days.

Outputs

FieldTypeWhat null means
rowsjsonNever null: empty when nothing in the window matches.
metricMetricNull when the query names Events directly.
rows[].valuenumber, in the Metric’s unitNo reading: the source sent nothing for that split. Zero is a reading, never null.
rows[].seriesnumber[]Null unless shape is trend: then one value per day of the window, oldest first.
rows[].readablebooleanNever null: false when the counts are too small to rank this row against the others.

Effects

Action class

None: no approval rule names it, so it runs within its seat’s Permissions and Limits

Modes
  • try: Runs the query and returns real rows: it reads, so try and do return the same.
  • do: Runs the query and returns the rows.
Idempotency

Yes: a read changes nothing, so a repeat returns the rows as they stand then.

Saved or shared

Nothing is saved. Spend and results read from your own accounts are never shared with other startups.

Emits

Metric.queried with { metric, shape, breakdown, window }

Performed by

Analyst

Price

Free on your own account: the platform charges nothing for the call.

On each Venue

Bing

Through Bing Webmaster.

Our fieldBing Webmaster’s field
Metric.breakdownquery or page
  • The key. 8 to 128 characters of letters, digits and dashes, in a file on your Domain; a missing file turns pushes away with needs-reauth.
Responsive search ad

Facebook

Through Facebook.

  • Your role on the page. Posting needs a role that can post; a role removed in Meta’s settings ends the connection with needs-reauth.
Feed image ad, 1440 × 1800, 4:5

Through Google Ads.

Google Search: Responsive search ad YouTube: Video

Google Analytics

Through Google Analytics.

Our fieldGoogle Analytics’s field
Metric.breakdowndimensions (sessionSource, sessionMedium, landingPage and the rest)
Metric.metricmetrics (sessions, activeUsers, keyEvents)
Metric.windowdateRanges
  • Realtime. Covers the last 30 minutes; anything older reads from the day’s reports.

Google Business Profile

Through Google Business Profile.

Google Search Console

Through Google Search Console.

Our fieldGoogle Search Console’s field
Metric.breakdowndimensions (query, page, country, device or date)
Metric.windowstartDate and endDate
Metric.metricclicks, impressions, ctr or position
  • Search data. Settles about 2 days behind, so a readout of yesterday reads the last settled day.
  • Request indexing. Has no API: for a key page still out of the index after a week, the browser agent presses it in Search Console, signed in as you.

Instagram

Through Instagram.

  • Account type. A professional account; a personal account refuses with account-not-connected until it switches.
Feed image, 320 to 1,440 pixels wide, 4:5 to 1.91:1 Carousel Reel, 9:16 Story, 9:16

LinkedIn

Through LinkedIn Ads.

  • Results. Read through the reporting API each morning; a day’s numbers settle overnight, so a stop rule fires on yesterday’s.
Feed post Single image ad, 1200 × 628, 1200 × 1200 or 720 × 900 Document ad

Facebook and Instagram

Through Meta Ads.

Facebook: Feed image ad, 1440 × 1800, 4:5 Instagram: Feed image, 320 to 1,440 pixels wide, 4:5 to 1.91:1 Instagram: Carousel Instagram: Reel, 9:16 Instagram: Story, 9:16

Bing

Through Microsoft Ads.

Responsive search ad

Reddit

Through Reddit Ads.

  • Comments on a promoted post. Stay open; each one reaches you as a Message, and your agent drafts the answer.
Text or link post Comment Promoted post

TikTok

Through TikTok Ads.

Video Spark Ad

TikTok

Through TikTok.

Video Spark Ad

X

Through X Ads.

Standard post Promoted post

X

Through X account.

  • Replies to strangers. Only to posts that describe your problem, and never twice in one thread without an answer back.
Standard post Promoted post

YouTube

Through YouTube.

  • Comments. Read every 30 minutes, since YouTube sends no webhook for comments.
Video

What try does

AccountWhat try does
Bing WebmasterReturns the URLs IndexNow would receive and the key file it would check; nothing is pushed.
FacebookReturns the post as your page will show it, with the time it goes live; nothing is posted or scheduled.
Google AdsSends every change with validate_only set: Google Ads checks the whole build and returns any error, and creates nothing.
Google AnalyticsReads run for real, because a report changes nothing; try stores no rows, builds no audience and marks no event.
Google Business ProfileReturns the update or the answer as it will show on your profile; nothing posts.
Google Search ConsoleReads run for real, because a read changes nothing in Search Console; try stores no rows and submits no sitemap.
InstagramChecks each image and video against Instagram’s specs and returns the post as it will show; no container is staged and nothing publishes.
LinkedIn AdsReads your ad account, the matched count of each audience and the targeting facets, and checks the campaign against LinkedIn’s budget minimums; LinkedIn has no validate-only call, so nothing is sent to it and nothing is created.
Meta AdsSends the whole build with Meta’s validate_only execution option: Meta runs every check and creates nothing, and the response names any field it would reject.
Microsoft AdsReturns what the import would bring over, term by term with the budget it would set, and the steps the browser agent would take; no session opens and nothing changes.
Reddit AdsReturns the campaign and the promoted post as Ads Manager will hold them, with the steps the browser agent would take; no session opens and nothing is created.
TikTok AdsReturns the Spark Ad and its ad group as Ads Manager will hold them, checked against TikTok’s budget floors, with the steps the browser agent would take; nothing is created.
TikTokChecks the clip and caption against what your account reports it allows, and returns the post as it will show; nothing reaches your inbox.
X AdsReturns the promotion as X Ads will hold it, with the steps the browser agent would take; no session opens and nothing is promoted.
X accountRenders each post at X’s weighted count, with links at 23 characters, and returns the price X would bill; nothing is posted and nothing is billed.
YouTubeChecks the file, title, description and tags against YouTube’s limits and returns the video page as it will read; nothing uploads and no quota is spent.

Refuses when

CheckErrorFixThen call
A revenue figure from any source but a live-mode Stripe querystripe-revenueQuery the revenue from live-mode Stripe, then compile the log.Metric.query

Every call through an account can also meet the shared account refusals: grant-missing, needs-reauth, account-not-connected, over-mandate, quota-reached, venue-rejected.

The stripe-revenue payload
JSON
{
  "type": "https://startupbuilder.dev/errors/stripe-revenue",
  "title": "Revenue not from Stripe",
  "status": 422,
  "detail": "A revenue figure from any source but a live-mode Stripe query.",
  "fix": "Query the revenue from live-mode Stripe, then compile the log.",
  "next": {
    "verb": "Metric.query",
    "input": {}
  },
  "instance": "https://api.sb/leaseline.app/actions/action_1"
}

When it waits

Returns in one response; nothing waits.

Example

Text
Which of the three LinkedIn test ads brought a lead in its first week?

To retry, send the same Idempotency-Key: the retry returns the first answer for $0. A new key reads again.

Test values

A sk_test_ key answers these the same way every time, at $0 (every test value).

Test valueAlways returnsWhat it is for
metric: 'test-flat'{"rows":[{"value":7,"series":[1,1,1,1,1,1,1],"readable":true}]}One a day for seven days, every time, so a readout or a stop rule can be tested against a known line.
maxCost: 0.0001Refuses with max-costAny priced call with a maxCost of 0.0001 is refused before it spends: the price is above the cap.
rate-limited.testRefuses with rate-limitedAny call naming this hostname answers 429 with Retry-After, so your retry logic runs.
sources-busy.testRefuses with sources-busyAny call naming this hostname answers 503 as if every route were busy, and nothing is spent.

Used by

None.