# Facebook Ads Insights API: Fields, Breakdowns, Limits

How to call the Facebook Ads Insights API: fields, level, breakdowns, date ranges, attribution windows, async report runs, and data retention limits.

Canonical page: https://www.tryadeli.com/blog/facebook-ads-insights-api
Last updated: 2026-10-26

By Mika Reyes, Co-founder, Adeli. Published 2026-10-26.

## The short answer

The Facebook Ads Insights API is the insights edge on every Marketing API ad object: GET /act_{id}/insights, or the same edge on a campaign, ad set, or ad. Choose fields, a level, breakdowns, and a date_preset or time_range. Large queries run as async report runs. Data goes back 37 months, and Meta removed 7-day and 28-day view attribution in January 2026. Adeli returns daily spend per ad account in one call.

The Facebook Ads Insights API is the `insights` edge of Meta's Marketing API. You call `GET /act_{ad-account-id}/insights`, or the same edge on a campaign, ad set, or ad, and choose four things: the **fields** (metrics), the **level** to aggregate at, any **breakdowns**, and a **date range**. Big queries run as asynchronous report runs, data goes back **37 months**, and Meta removed the 7-day and 28-day view attribution windows on **January 12, 2026**.

This guide covers each parameter, the async workflow, and the retention and rate limits that break reporting jobs. It's part of our [Meta Ads API](https://www.tryadeli.com/blog/meta-ads-api) series, and it's about paid ads. For organic Page metrics, see the [Facebook Page Insights API](https://www.tryadeli.com/blog/facebook-page-insights-api).

## What do you need before you start?

- **A token with ad account access.** Meta's [Insights API guide](https://developers.facebook.com/docs/marketing-api/insights) lists `ads_read`. An app that holds `ads_management` can read the accounts it manages too.
- **An ad account ID** in `act_<digits>` form, or the ID of a campaign, ad set, or ad.
- **Conversion tracking**, if you want results beyond clicks. Purchases and leads only show up when the Meta Pixel, the Conversions API, or instant forms record them.

## How do I call the Facebook Ads Insights API?

**Send a GET to the `insights` edge of any ad object with a `fields` list.** Without parameters, Meta returns basic metrics for roughly the last 30 days.

```bash
curl -G "https://graph.facebook.com/v26.0/act_$AD_ACCOUNT_ID/insights" \
  --data-urlencode "fields=campaign_name,spend,impressions,reach,clicks,ctr,cpm,actions" \
  --data-urlencode "level=campaign" \
  --data-urlencode "date_preset=last_7d" \
  --data-urlencode "access_token=$ACCESS_TOKEN"
```

The response has a `data` array with one row per object at the requested level, each with `date_start` and `date_stop`, plus cursor `paging`. Metric values come back as strings, so parse `spend` as a decimal before you add it up.

The four edges, from Meta's guide:

| Edge | Returns |
|---|---|
| `/act_{ad-account-id}/insights` | The whole account, or any level below it with `level` |
| `/{campaign-id}/insights` | One campaign |
| `/{ad-set-id}/insights` | One ad set |
| `/{ad-id}/insights` | One ad |

## How do level and breakdowns work?

**`level` sets which object each row represents, and `breakdowns` split each row by a dimension such as age or placement.** Use `level` on the account edge to get every campaign, ad set, or ad in one call instead of looping over IDs.

- **`level`** takes `account`, `campaign`, `adset`, or `ad`.
- **`breakdowns`** split rows by audience or delivery: `age`, `gender`, `country`, `region`, `publisher_platform`, `platform_position`, `device_platform`, and hourly options. Only some combinations work together; Meta's [breakdowns page](https://developers.facebook.com/docs/marketing-api/insights/breakdowns) lists them.
- **`action_breakdowns`** split the `actions` field, by `action_type` by default.
- **`filtering`** keeps only rows that match, such as `[{"field":"ad.impressions","operator":"GREATER_THAN","value":0}]` to skip ads that never delivered.

Hourly breakdowns don't support unique fields: `reach` and `frequency` return 0 when you use them.

## How do I set the date range?

**Use `date_preset` for a relative window or `time_range` for exact dates, and `time_increment` to split the window into days.** From the [ad account insights reference](https://developers.facebook.com/docs/marketing-api/reference/ad-account/insights/):

| Parameter | Format | Notes |
|---|---|---|
| `date_preset` | `today`, `yesterday`, `last_7d`, `last_28d`, `last_30d`, `last_90d`, `this_month`, `maximum`, and more | Default `last_30d`. Ignored if `time_range` is set. |
| `time_range` | `{"since":"2026-10-01","until":"2026-10-25"}` | Dates only, no Unix timestamps. |
| `time_ranges` | A list of `time_range` objects | One result set per range. Overrides the other three. |
| `time_increment` | `1` to `90`, `monthly`, or `all_days` | `1` gives one row per day. Default `all_days`. |

Insights are reported in the **ad account's time zone**, so "yesterday" depends on where the account is set, not where your server runs.

## Which attribution windows still work?

**The default attribution window is 7-day click plus 1-day view, and the 7-day and 28-day view windows return no data since January 12, 2026.** Meta's [out-of-cycle changelog](https://developers.facebook.com/documentation/ads-commerce/marketing-api/out-of-cycle-changes/occ-2025) announced the removal on October 13, 2025, for all API versions.

- **`action_attribution_windows`** still accepts `1d_click`, `7d_click`, `28d_click`, `1d_view`, and `1d_ev` (engaged view), among others.
- **`use_unified_attribution_setting=true`** reports each ad set's own attribution setting, which is what Ads Manager shows. Since June 10, 2025, Meta applies this behavior to attributed values regardless of the parameter.

If your reports used `7d_view` or `28d_view`, conversion counts fell on January 12, 2026, when those windows started returning no data. Attribution also explains other mismatches with your own data:

> "Ads Manager results can include multiple conversions by the same person."
> Jon Loomer, Meta ads consultant, [How Meta Ads Attribution Works in 2026](https://www.jonloomer.com/meta-ads-attribution-2026/) (March 10, 2026)

Put that next to any conversion count you show your customers, so a figure higher than their CRM's doesn't read as an error.

## How do async report runs work?

**For large queries, POST to the same `insights` edge, poll the report run until it completes, then read its results.** Meta recommends trying a synchronous call first and switching to async when it times out. The steps, from Meta's [limits and best practices page](https://developers.facebook.com/docs/marketing-api/insights/best-practices):

1. **Start the job.** `POST /act_{id}/insights` with the same parameters returns a `report_run_id`.
2. **Poll the run.** `GET /{report_run_id}` until `async_status` is `Job Completed` and `async_percent_completion` is `100`. Other statuses include `Job Failed` and `Job Skipped`, which means resubmit.
3. **Read the results.** `GET /{report_run_id}/insights`, paging with the cursors.

```bash
curl -X POST "https://graph.facebook.com/v26.0/act_$AD_ACCOUNT_ID/insights" \
  -F "level=ad" \
  -F "fields=ad_id,spend,impressions,clicks,actions" \
  -F 'time_range={"since":"2026-01-01","until":"2026-09-30"}' \
  -F "time_increment=1" \
  -F "access_token=$ACCESS_TOKEN"
```

An async job can take **up to an hour**, and a `report_run_id` expires after **30 days**, so don't store it as a permanent reference.

## What are the data retention and rate limits?

**Meta keeps 37 months of ads insights, less for some breakdowns, and throttles by app and by ad account.** Plan your backfills and nightly syncs around these:

| Limit | Value |
|---|---|
| Overall history | 37 months; older start dates return error 3018 |
| Unique-count fields with breakdowns, hourly breakdowns | 13 months |
| `frequency_value` breakdown | 6 months |
| `reach` with breakdowns, older than 13 months | Omitted from standard queries; async jobs allow 10 such requests per ad account per day |
| Freshness | Refreshes every 15 minutes; final 28 days after reporting |
| Rate limit error | Code 4; subcode 1504022 under heavy global load |
| Too much data in one call | Code 100, subcode 1487534 |

Watch the `x-fb-ads-insights-throttle` header on every response. It reports `app_id_util_pct` and `acc_id_util_pct`, and Meta's advice is to back off well before either reaches 100. Its tips for the data-per-call error: shorten the date range, request fewer fields, and avoid account-level queries with high-cardinality breakdowns. Our [Meta Ads API](https://www.tryadeli.com/blog/meta-ads-api) guide covers the access tiers that set these limits.

## Is there a faster way to do this?

**Adeli returns one row per day of spend, impressions, clicks, and conversions for a customer's ad account, or any campaign, ad set, or ad in it, from one call.** Adeli holds the Meta app and its reviews and manages each customer's token, so you skip the permissions and throttle headers above. The endpoint is [daily insights](https://www.tryadeli.com/docs/api/ads/get-insights):

```bash
curl -G "https://app.tryadeli.com/api/v1/ads/insights" \
  -H "Authorization: Bearer $ADELI_API_KEY" \
  --data-urlencode "accountId=$ACCOUNT_ID" \
  --data-urlencode "adAccountId=act_1234567890" \
  --data-urlencode "objectId=120210000000000001" \
  --data-urlencode "since=2026-10-01" \
  --data-urlencode "until=2026-10-25"
```

Leave out `objectId` for the whole account, and leave out the dates for the last 28 days. For a dashboard, [campaign tree](https://www.tryadeli.com/docs/api/ads/get-campaign-tree) returns every campaign, ad set, and ad with `spend`, `impressions`, `reach`, `clicks`, `ctr`, `cpc`, and `cpm` rolled up at each level, and an object that didn't deliver reports zeroes instead of disappearing.

Adeli stores no campaign structure or metrics, so every figure is as fresh as Meta's response. When Meta throttles an ad account, Adeli returns `429 rate_limited` with a `Retry-After` header. The same API key reads [organic analytics](https://www.tryadeli.com/social-media-analytics-api) for Instagram, Facebook, TikTok, and YouTube, so paid and organic numbers can sit in one report. [Pricing](https://www.tryadeli.com/pricing) is per customer profile.

## Frequently asked questions

### What is the difference between ads_read and ads_management for insights?

Meta's Insights guide lists ads_read as the permission for reading ad performance. The ads_management permission also covers reading the ad accounts a person can manage, so an app that already manages campaigns can read their insights with it. Both need Advanced Access for customers' ad accounts.

### Why don't my Ads Insights API numbers match Ads Manager?

The usual causes are the attribution setting, the time zone, and freshness. Set use_unified_attribution_setting to true to use each ad set's attribution, compare in the ad account's time zone, and remember that recent days can still change, because Meta keeps updating insights for up to 28 days.

### How often does Facebook ads insights data update?

Meta says insights refresh every 15 minutes and stop changing 28 days after they're reported. Metrics can keep moving for a couple of days after an ad finishes, so a nightly sync should re-read at least the last 28 days.

### How far back can I query Facebook ads insights?

37 months. A time range that starts further back returns error 3018. Breakdowns of unique metrics and hourly breakdowns keep 13 months, and the frequency_value breakdown keeps 6 months.

## Related Adeli pages

- [Social Media Analytics API](https://www.tryadeli.com/social-media-analytics-api.md): Adeli's analytics API: Instagram, TikTok, Facebook Page, and YouTube insights endpoints, plus per-post engagement on every post an account has made.
- [Social Media and Ads API for AI Marketing Platforms](https://www.tryadeli.com/use-cases/ai-marketing-platforms.md): Run posting, analytics, inbox, and Meta ads for your customers' accounts through one API, without months of platform reviews.
- [All posts on the Adeli blog](https://www.tryadeli.com/blog.md)

## About the author

Mika Reyes is the CEO behind Adeli and a tech and AI content creator. She was previously co-founder and CEO of Parallax, which was acquired by Phantom, and a product lead at LinkedIn. She is a Forbes 30 Under 30 honoree.
