List insights
Gives aggregated metric rows for your organization: what an ad account, a campaign, an ad group or an ad spent over a date range, and what it returned.
Each row carries the metrics you name in select. The default metrics are spend and impressions. Each row also carries a currency.
Date range
A date range is required. Send since, and optionally until, both written YYYY-MM-DD. Or send relative: last_7_days, last_15_days or last_month. A request with neither is refused with a 422.
Set interval to day, week or month to get one row for each period, each carrying a date. A week is dated by its Monday, a month by its first day. Omit interval to get one row for the whole range.
Filters and groups
advertiserId, entityId, entityType and provider are filters: they decide which rows are read. breakdown is separate: it decides how the rows are grouped, and which columns name the group.
breakdown |
Rows | Each row also carries |
|---|---|---|
| omitted | one, for everything that matched | nothing else |
provider |
one for each ad platform | provider |
advertiser |
one for each ad account | provider, advertiserId |
| an entity type | one for each entity of that type | provider, advertiserId, entityId, type |
An entity type is the name its provider uses — campaign, adset at Meta, ad_group at TikTok and Google Ads, ad, and so on.
A breakdown deeper than campaign needs a provider or an entity filter, because the levels below a campaign differ per platform. breakdown=adset with no provider is refused with a 422 that names the breakdowns that are available.
Money
Money comes back in the account currency of the rows it came from, and each row says which in its currency. A group that mixes two account currencies answers currency: null — the money in it was added across currencies and cannot be compared.
Send currency — an ISO 4217 code such as USD — to make them comparable. AdCrunch converts each day at the European Central Bank rate of that day, before adding the rows up, and every row then answers that currency.
Advertisers
Omit advertiserId to read every advertiser of your organization in one call. Send it to read one, and AdCrunch then also makes sure your organization owns it. An advertiserId your organization does not own answers an empty list, not a failure.
/observe/insightsAuthorizationBearer token · headerrequiredSend Authorization: Bearer <credential>. Two credentials work.
An API key (acr_…) is what a server integration uses. Create one in the AdCrunch console under Settings → API keys — see https://docs.adcrunch.dev/account/api-keys. A key is bound to the organization that was active when you created it, and it keeps acting on that organization whatever you do later. It carries the permissions of the member who created it.
A session issued by the AdCrunch sign-in flow also works, which is how the console calls this service from the browser.
Either way the organization comes from the credential. There is no organization parameter.
advertiserIdstringFilter rows to a single advertiser. Short-circuits the per-org advertiser fan-out and verifies the advertiser belongs to the caller's organization.
breakdownstringGroup results by this level. Use a provider-native entity type (campaign, adset, ad_group, line_item, asset_group, keyword, ad, …) or provider/advertiser. Omit to aggregate every matching row into one result.
provideradvertisercampaignadsetadgroupad_groupad_group_adinsertion_orderline_itemasset_groupkeywordaudiencelisting_groupadcreativecurrencystringDisplay currency (ISO 4217, e.g. USD). When provided, monetary metrics are converted from each row’s account currency using the ECB reference rate of the row’s own date, before any aggregation. Omit to get unconverted account-currency values — pass it whenever the organization has advertisers in more than one currency.
entityIdstringFilter to a single entity (any type), or — combined with an entity-type breakdown — scope the breakdown to that entity’s subtree.
entityTypestringFilter rows to a single provider-native entity type.
intervalstringBucket the time series at this granularity. Omit to collapse to a single row per group.
dayweekmonthlimitnumberPage size. Clamped to 100.
offsetnumberPagination offset.
providerstringRestrict to a single provider. Ignored when an entity filter (advertiserId, etc.) is provided — that filter already pins the provider.
relativestringselectstring | string[]Metric columns to include on each row, as a comma-separated string (e.g. spend,clicks,ctr) or repeated values. Defaults to spend,impressions.
sincestringuntilstringThe matching rows. An empty array means nothing matched.
objectadvertiserIdstringThe ad account this row belongs to, prefixed acc_. Present when breakdown is advertiser or an entity type.
currencystring | nullrequiredThe ISO 4217 currency the money in this row is expressed in. It is the account currency when every row in the group shares one, the currency you asked for when you sent currency, and null when the group mixes two or more account currencies. A null here means the money in this row was added up across currencies and cannot be compared — send currency to make it comparable.
datestringThe first day of the period, YYYY-MM-DD. Present only when you send interval. A week is dated by its Monday, a month by its first day.
entityIdstringThe entity this row belongs to, as the bare id its provider gives it. Present when breakdown is an entity type.
providerstringThe ad platform: meta, tiktok, gads, snapchat or dv360. Present when breakdown is set to anything.
typestringThe provider entity type of entityId, for example campaign, adset, ad_group or ad. Present when breakdown is an entity type.
spendnumberMoney spent, in the row’s currency.
clicksnumberClicks.
impressionsnumberImpressions.
ctrnumberClick-through rate, as a percentage: clicks ÷ impressions × 100. A ctr of 1.5 means 1.5%.
cpcnumberCost per click: spend ÷ clicks.
cpmnumberCost per thousand impressions: spend ÷ impressions × 1000.
cppnumberCost per thousand people reached: spend ÷ reach × 1000. Google Ads reports no reach, so this reads 0 there.
cpanumberCost per conversion: spend ÷ conversions.
roasnumberReturn on ad spend: conversion value ÷ spend.
reachnumberPeople reached. Google Ads does not report it, so it reads 0 there.
frequencynumberImpressions ÷ reach. Google Ads reports no reach, so this reads 0 there.
conversionsnumberConversions, as the provider counts them.
conversion_valuenumberThe value attributed to those conversions, as money.
action_add_to_cartnumberAdd-to-cart actions. Meta only; other providers read 0.
action_add_to_cart_valuenumberThe value attributed to those add-to-cart actions. Meta only.
action_purchasenumberPurchases. Meta only; other providers read 0.
action_purchase_valuenumberThe value attributed to those purchases. Meta only.
action_initiate_checkoutnumberCheckouts started. Meta only; other providers read 0.
action_initiate_checkout_valuenumberThe value attributed to those checkouts. Meta only.
No credential, or one that does not resolve. Send an API key or a session. See the security scheme. error is unauthorized.
errorstringrequiredA stable code for the failure. This is the field to branch on. It does not change for a given failure.
unauthorizedmessagestringrequiredA sentence to show a person. Written to say what to do next. Reworded whenever it can be said better, so never branch on it.
The caller does not hold observe:read. error is forbidden.
errorstringrequiredA stable code for the failure. This is the field to branch on. It does not change for a given failure.
forbiddenmessagestringrequiredA sentence to show a person. Written to say what to do next. Reworded whenever it can be said better, so never branch on it.
The request did not match this operation’s schema. This is the framework’s own shape, not the error/message one.
errorsobject[]requiredOne entry per failing field.
foundanyrequiredWhat was sent.
messagestringrequiredonstringrequiredWhich part of the request failed: body, query or params.
propertystringrequiredThe field that failed.
typestringrequiredvalidation