Meta Ads
GET Ads Insights with ads_read. Spend is a decimal string on a date range.
What you can track
Impressions, clicks and spend for an ad account, campaign, ad set or ad, from the Insights edge. The default GET is one row for a date range (date_start and date_stop in the sample), not one row per day. Stamp that row with the fetch day (omit extract.date) and treat it as “the range total as of this morning”, or narrow the request to a single day. Do not chart date_start as if it were a daily series.
time_increment was not on the page checked here. Do not add it unless test_job shows daily rows.
Credential
A user or system access token with ads_read for that ad account. ads_read is the read permission for Insights. ads_management can also read but can change ads; do not ask for it. App Review applies when the app reads an account the app’s own user does not own. That review flow was not walked for this playbook.
Host: graph.facebook.com. Suggested name: META_TOKEN. The official example puts the token in the query string as access_token.
Where to get it
Meta for Developers → the app → Graph API explorer or a system user token, with ads_read. Ad account ids look like act_ plus digits. Permissions.
tlly job
The docs example uses Graph v26.0 (another snippet on the same docs set showed v25.0). Use the version the current insights page shows, and expect it to move.
{"series":"meta_spend","cron":"0 7 * * *","request":{"url":"https://graph.facebook.com/v26.0/act_AD_ACCOUNT_ID/insights?fields=spend,impressions,clicks&date_preset=yesterday&access_token={{secret:META_TOKEN}}"},"extract":{"format":"json","value":"data[0].spend"}}
spend in the sample is a decimal string ("5339.5"), major units, not cents. Omit extract.date so the point is the fetch day.
Gotchas
- Insights rate limits are a load budget, not a fixed number this playbook will quote. Daily is enough. Best practices: insights best practices.
- The token in the query string is still a secret reference ({{secret:…}}), never the raw token in the job.
- Paging uses cursors. tlly will not follow them. One object’s insights for a short range fits in one response.
- A long breakdown (age, gender, placement) is many rows. That is not one series unless you filter to a single row.
Alert ideas
Red when yesterday’s spend is above the cap. Yellow when clicks are zero while impressions are not (tracking broke).
Verification
Checked 2026-10-26: Insights is a GET edge /{ad-account-id}/insights (and campaign, ad set, ad). Sample response includes date_start, date_stop, impressions, spend as strings. ads_read is the permission named for Insights. Graph version in the worked example was v26.0 on the search snippet of that page and v25.0 in another; treat the version as current-docs, not permanent. time_increment unverified.