v2

latestOpenAPI 3.1.02026-08-075421692.0 MB
Ad Campaigns

Get campaign tree

Returns a nested Campaign > Ad Set > Ad hierarchy with rolled-up metrics at each level. Uses a two-stage aggregation: ads are grouped into ad sets, then ad sets into campaigns. Metrics are computed over an optional date range, then rolled up from ad level to ad set and campaign levels. Pagination is at the campaign level. Ads without a campaign or ad set ID are grouped into synthetic "Ungrouped" buckets. If no date range is provided, defaults to the last 90 days. Date range is capped at 730 days max.

Pass timeIncrement=1 to also get a daily breakdown: each node gains a daily[] array of per-day metrics (same fields as the aggregated metrics) in the same call. Use dailyLevel (campaign default, or adset / ad) to choose which levels carry the series. This replaces calling the tree once per day for per-campaign daily trends.

Deleted objects stay in the tree. Deleting an ad or a campaign is a soft delete: the Ad documents move to status: cancelled and are kept indefinitely, so their historical spend still counts toward the metrics of any date range they fall in. There is no pruning job and no retention window. Filter on status if your view should hide them, but do that after reading the totals, not before.

get/v1/ads/tree

Query parameters

pageinteger

Page number (1-based)

limitinteger

Campaigns per page

source'zernio' | 'all'

all (default) returns both Zernio-created ads and those discovered from the platform's ad manager — matches the web UI's default view. Pass zernio to restrict to isExternal=false only. Status is NOT filtered by default — use the status param for that.

platform'facebook' | 'instagram' | 'tiktok' | 'linkedin' | 'pinterest' | 'google' | 'twitter' | 'openai'
status'active' | 'paused' | 'pending_review' | 'rejected' | 'completed' | 'cancelled' | 'error'

Filter by derived campaign status (post-aggregation)

adAccountIdstring

Platform ad account ID

pageIdstring

Meta only: Facebook Page ID. Prunes the tree to ads whose creative is backed by this Page — campaigns and ad sets with no ad on the Page drop out, and rolled-up metrics cover only the Page's ads. Mirrors the same filter on /v1/ads and /v1/ads/campaigns.

accountIdstring

Social account ID

profileIdstring

Profile ID

campaignIdstring

Restrict the tree to a single campaign by its platform campaign id (the id the platform assigns, e.g. Meta's numeric campaign id). Filters the campaign set itself, so it works regardless of account size and pagination — pass this when you already hold a campaign id instead of paging the tree to find it. Mirrors the campaignId filter on GET /v1/ads.

fromDatestring date

Start of the METRICS date range (YYYY-MM-DD). Affects only the spend/impression numbers overlaid on each node, NOT which campaigns are returned. Defaults to 90 days ago.

toDatestring date

End of metrics date range (YYYY-MM-DD). Defaults to today. Max 730-day range.

sort'newest' | 'oldest' | 'spend_desc' | 'spend_asc'

Campaign-level sort order. newest (default) / oldest order by the campaign's newest-ad createdAt. spend_desc / spend_asc order by aggregated spend in the requested date range; campaigns with no spend land at the end.

timeIncrement1

Set to 1 to also return a daily breakdown. Mirrors Meta Insights' time_increment=1: each node gains a daily[] array of per-day metrics (same fields as the aggregated metrics) alongside the range total, so you get per-entity daily trends in ONE call instead of calling the tree once per day. Only 1 (daily) is supported. The daily series covers the same date range and uses the same source data as metrics, except reach on Meta and TikTok: the range total is the platform's de-duplicated value, so daily reach does not sum to it. See dailyLevel to control which levels carry it.

dailyLevel'campaign' | 'adset' | 'ad'

Which tree levels get the daily[] series when timeIncrement=1. campaign (default) attaches it on campaign nodes only — the common per-campaign-trend case, and the smallest payload. adset adds it on ad sets too; ad adds it on every ad in ads[] as well (heaviest — a long range × up to 100 ads per ad set). Scope with campaignId to keep ad-level responses small. Ignored when timeIncrement is unset.

Response

Nested campaign tree with pagination

backfillPendingboolean

Present and true only on 202 responses: part of the requested date range is still being backfilled from the platform in the background. Retry the same request shortly; it returns 200 once the range is fully ingested.

Example response

{
  "campaigns": [
    {
      "metrics": {
        "actions": {
          "link_click": 160,
          "post_engagement": 300,
          "offsite_conversion.fb_pixel_purchase": 42
        },
        "actionValues": {
          "offsite_conversion.fb_pixel_purchase": 2456.78,
          "offsite_conversion.fb_pixel_add_to_cart": 980.5
        }
      },
      "adSets": [
        {
          "metrics": {
            "actions": {
              "link_click": 160,
              "post_engagement": 300,
              "offsite_conversion.fb_pixel_purchase": 42
            },
            "actionValues": {
              "offsite_conversion.fb_pixel_purchase": 2456.78,
              "offsite_conversion.fb_pixel_add_to_cart": 980.5
            }
          },
          "servingStatuses": [
            "RUNNABLE"
          ],
          "ads": [
            {
              "configuredStatus": "ACTIVE",
              "creativeType": "video",
              "metrics": {
                "actions": {
                  "link_click": 160,
                  "post_engagement": 300,
                  "offsite_conversion.fb_pixel_purchase": 42
                },
                "actionValues": {
                  "offsite_conversion.fb_pixel_purchase": 2456.78,
                  "offsite_conversion.fb_pixel_add_to_cart": 980.5
                }
              },
              "platformObjective": "OUTCOME_SALES",
              "optimizationGoal": "OFFSITE_CONVERSIONS",
              "costType": "CPC",
              "servingStatuses": [
                "ACCOUNT_TOTAL_BUDGET_HOLD"
              ],
              "platformAdAccountName": "Zernio - previously Late",
              "bidAmount": 5,
              "roasAverageFloor": 2,
              "promotedObject": {
                "custom_event_type": "PURCHASE"
              },
              "creative": {
                "servingHoldReasons": [
                  "UNDER_REVIEW"
                ]
              }
            }
          ],
          "daily": [
            {
              "actions": {
                "link_click": 160,
                "post_engagement": 300,
                "offsite_conversion.fb_pixel_purchase": 42
              },
              "actionValues": {
                "offsite_conversion.fb_pixel_purchase": 2456.78,
                "offsite_conversion.fb_pixel_add_to_cart": 980.5
              }
            }
          ]
        }
      ],
      "daily": [
        {
          "actions": {
            "link_click": 160,
            "post_engagement": 300,
            "offsite_conversion.fb_pixel_purchase": 42
          },
          "actionValues": {
            "offsite_conversion.fb_pixel_purchase": 2456.78,
            "offsite_conversion.fb_pixel_add_to_cart": 980.5
          }
        }
      ]
    }
  ]
}