Get campaign tree
Shows your campaigns with their ad sets and ads nested inside, with spend and results rolled up at every 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.
History: when an ad account connects, Zernio imports its last 90 days of metrics, so the
metrics hold no data for days before that. When accountId or adAccountId resolves to a
Meta ad account, a range reaching further back answers 202 with backfillPending: true and the
covered part while the older days (up to 730 days back) are imported in the background;
repeat the request until it returns 200.
A request scoped to no Meta account never returns 202.
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.
Authorization
bearerAuth API key authentication: send your Zernio API key in the Authorization header, prefixed with Bearer.
In: header
Query Parameters
Page number (1-based)
1 <= value1Campaigns per page
1 <= value <= 10020all (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.
"all"Value in
- "zernio"
- "all"
Value in
- "facebook"
- "instagram"
- "tiktok"
- "linkedin"
- "pinterest"
- "google"
- "twitter"
- "openai"
- "reddit"
Filter by derived campaign status (post-aggregation)
Value in
- "active"
- "paused"
- "pending_review"
- "rejected"
- "completed"
- "cancelled"
- "error"
One or more platform ad account IDs to scope the tree to (agency profiles connect a whole Business Manager but a team usually cares about a subset). Comma-separate for multiple (?adAccountId=act_1,act_2,act_3); single value keeps its old shape. Max 50 accounts per request; the plural aliases adAccountIds and platformAdAccountIds are rejected with a 400 to stop them from silently returning the unfiltered fleet.
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.
Account ID
Profile ID
Restrict the tree to one or more campaigns by platform campaign id (the id the platform assigns, e.g. Meta's numeric campaign id). Comma-separate up to 100 ids (?campaignId=123,456). Filters the campaign set itself, so it works regardless of account size and pagination. Pass this when you already hold campaign ids (for example from an ad.status_changed webhook) instead of paging the whole tree.
Return only campaigns with a change stored since this time (ISO 8601 with offset, e.g. 2026-09-30T10:00:00Z): a new ad, or a change to any ad's status, review status, name, budget or creative. Each matching campaign comes back whole (every ad set and ad). Metrics are not a change: to refresh numbers, filter with hasDelivery=true and a date range instead. Combines with every other filter (with hasDelivery/minSpend a campaign must match both).
date-timeCase-insensitive substring match on campaign, ad set and ad names (_, % and spaces match literally), or an exact platform campaign, ad set or ad id. A campaign whose name matches returns with all its ad sets and ads; a match on an ad set or ad name returns only the matching branch. Filters the campaign set itself, so pagination.total counts only matching campaigns.
length <= 500Start of the METRICS date range (YYYY-MM-DD). On its own it affects only the spend/impression numbers overlaid on each node, not which campaigns are returned. Pass hasDelivery or minSpend to also filter the campaign set to this window. Defaults to 90 days ago.
dateEnd of metrics date range (YYYY-MM-DD). Defaults to today. Max 730-day range.
dateReturn only campaigns that delivered between fromDate and toDate: spend above zero, or impressions served at zero spend. Unlike status, which reads a campaign's CURRENT state, this filters on what happened inside the window, so a campaign that spent then and is paused today is still returned. Filters the campaign set itself, so pagination.total counts only matching campaigns.
Return only campaigns whose spend between fromDate and toDate reaches this amount. Expressed in each campaign's OWN currency (the currency field on the campaign node): spend is stored per ad account in its native currency and one response can span several. Implies hasDelivery; minSpend=0 applies no filter.
0 <= valueCampaign-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.
"newest"Value in
- "newest"
- "oldest"
- "spend_desc"
- "spend_asc"
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.
Value in
- 1
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.
"campaign"Value in
- "campaign"
- "adset"
- "ad"
Response Body
application/json
application/json
application/json
import Zernio from '@zernio/node';const zernio = new Zernio({ apiKey: process.env.ZERNIO_API_KEY });const { data } = await zernio.adcampaigns.getAdTree();console.log(data);{ "campaigns": [ { "platformCampaignId": "string", "platform": "facebook", "campaignName": "string", "createdTime": "2019-08-24T14:15:22Z", "status": "active", "reviewStatus": "in_review", "platformCampaignStatus": "string", "campaignIssuesInfo": [ {} ], "adCount": 0, "adSetCount": 0, "budget": { "amount": 0, "type": "daily" }, "campaignBudget": { "amount": 0, "type": "daily" }, "budgetLevel": "campaign", "isBudgetScheduleEnabled": false, "currency": "string", "metrics": { "spend": 0, "impressions": 0, "reach": 0, "clicks": 0, "ctr": 0, "cpc": 0, "cpm": 0, "engagement": 0, "conversions": 0, "allConversions": 0, "costPerConversion": 0, "actions": { "property1": 0, "property2": 0 }, "actionValues": { "property1": 0, "property2": 0 }, "purchaseValue": 0, "roas": 0, "costPerAction": { "property1": 0, "property2": 0 }, "outboundClicks": 0, "outboundClicksCtr": 0, "inlineLinkClicks": 0, "inlineLinkClickCtr": 0, "uniqueClicks": 0, "uniqueCtr": 0, "videoPlayActions": 0, "video30SecWatchedActions": 0, "videoThruplayWatchedActions": 0, "videoP25WatchedActions": 0, "videoP50WatchedActions": 0, "videoP75WatchedActions": 0, "videoP95WatchedActions": 0, "videoP100WatchedActions": 0, "video2SecWatchedActions": 0, "video6SecWatchedActions": 0, "video6SecFocusedViews": 0, "videoAvgTimeWatchedActions": 0, "costPerThruplay": 0, "funnel": { "landingPageViews": 0, "contentViews": 0, "searches": 0, "wishlistAdds": 0, "cartAdds": 0, "checkoutsInitiated": 0, "paymentInfoAdds": 0, "purchases": 0, "leads": 0, "registrationsCompleted": 0, "appInstalls": 0, "messagingConversationsStarted": 0, "messagingFirstReplies": 0 }, "engagementBreakdown": { "postEngagement": 0, "pageEngagement": 0, "reactions": 0, "comments": 0, "shares": 0, "saves": 0, "pageLikes": 0, "videoViews": 0, "linkClicks": 0 }, "lastSyncedAt": "2019-08-24T14:15:22Z" }, "platformAdAccountId": "string", "platformAdAccountName": "string", "accountId": "string", "profileId": "string", "isSmartPlus": true, "advertisingChannelType": "string", "platformObjective": "string", "optimizationGoal": "string", "bidStrategy": "LOWEST_COST_WITHOUT_CAP", "bidAmount": 0, "roasAverageFloor": 0, "promotedObject": { "custom_event_type": "string", "pixel_id": "string", "page_id": "string" }, "adSets": [ { "platformAdSetId": "string", "adSetName": "string", "status": "active", "createdTime": "2019-08-24T14:15:22Z", "adCount": 0, "isSmartPlus": true, "budget": { "amount": 0, "type": "daily", "daily": 0, "lifetime": 0, "pacing": "string" }, "adSetBudget": { "amount": 0, "type": "daily", "daily": 0, "lifetime": 0, "pacing": "string" }, "metrics": { "spend": 0, "impressions": 0, "reach": 0, "clicks": 0, "ctr": 0, "cpc": 0, "cpm": 0, "engagement": 0, "conversions": 0, "allConversions": 0, "costPerConversion": 0, "actions": { "property1": 0, "property2": 0 }, "actionValues": { "property1": 0, "property2": 0 }, "purchaseValue": 0, "roas": 0, "costPerAction": { "property1": 0, "property2": 0 }, "outboundClicks": 0, "outboundClicksCtr": 0, "inlineLinkClicks": 0, "inlineLinkClickCtr": 0, "uniqueClicks": 0, "uniqueCtr": 0, "videoPlayActions": 0, "video30SecWatchedActions": 0, "videoThruplayWatchedActions": 0, "videoP25WatchedActions": 0, "videoP50WatchedActions": 0, "videoP75WatchedActions": 0, "videoP95WatchedActions": 0, "videoP100WatchedActions": 0, "video2SecWatchedActions": 0, "video6SecWatchedActions": 0, "video6SecFocusedViews": 0, "videoAvgTimeWatchedActions": 0, "costPerThruplay": 0, "funnel": { "landingPageViews": 0, "contentViews": 0, "searches": 0, "wishlistAdds": 0, "cartAdds": 0, "checkoutsInitiated": 0, "paymentInfoAdds": 0, "purchases": 0, "leads": 0, "registrationsCompleted": 0, "appInstalls": 0, "messagingConversationsStarted": 0, "messagingFirstReplies": 0 }, "engagementBreakdown": { "postEngagement": 0, "pageEngagement": 0, "reactions": 0, "comments": 0, "shares": 0, "saves": 0, "pageLikes": 0, "videoViews": 0, "linkClicks": 0 }, "lastSyncedAt": "2019-08-24T14:15:22Z" }, "optimizationGoal": "string", "bidStrategy": "LOWEST_COST_WITHOUT_CAP", "bidAmount": 0, "roasAverageFloor": 0, "costType": "string", "servingStatuses": [ "string" ], "promotedObject": { "custom_event_type": "string", "pixel_id": "string", "page_id": "string" }, "ads": [ { "_id": "string", "name": "string", "platform": "facebook", "profileId": "string", "status": "active", "configuredStatus": "string", "reviewStatus": "in_review", "adType": "boost", "creativeType": "carousel", "goal": "engagement", "isExternal": true, "budget": { "amount": 0, "type": "daily", "daily": 0, "lifetime": 0, "pacing": "string" }, "metrics": { "spend": 0, "impressions": 0, "reach": 0, "clicks": 0, "ctr": 0, "cpc": 0, "cpm": 0, "engagement": 0, "conversions": 0, "allConversions": 0, "costPerConversion": 0, "actions": { "property1": 0, "property2": 0 }, "actionValues": { "property1": 0, "property2": 0 }, "purchaseValue": 0, "roas": 0, "costPerAction": { "property1": 0, "property2": 0 }, "outboundClicks": 0, "outboundClicksCtr": 0, "inlineLinkClicks": 0, "inlineLinkClickCtr": 0, "uniqueClicks": 0, "uniqueCtr": 0, "videoPlayActions": 0, "video30SecWatchedActions": 0, "videoThruplayWatchedActions": 0, "videoP25WatchedActions": 0, "videoP50WatchedActions": 0, "videoP75WatchedActions": 0, "videoP95WatchedActions": 0, "videoP100WatchedActions": 0, "video2SecWatchedActions": 0, "video6SecWatchedActions": 0, "video6SecFocusedViews": 0, "videoAvgTimeWatchedActions": 0, "costPerThruplay": 0, "funnel": { "landingPageViews": 0, "contentViews": 0, "searches": 0, "wishlistAdds": 0, "cartAdds": 0, "checkoutsInitiated": 0, "paymentInfoAdds": 0, "purchases": 0, "leads": 0, "registrationsCompleted": 0, "appInstalls": 0, "messagingConversationsStarted": 0, "messagingFirstReplies": 0 }, "engagementBreakdown": { "postEngagement": 0, "pageEngagement": 0, "reactions": 0, "comments": 0, "shares": 0, "saves": 0, "pageLikes": 0, "videoViews": 0, "linkClicks": 0 }, "lastSyncedAt": "2019-08-24T14:15:22Z" }, "platformAdId": "string", "platformAdAccountId": "string", "platformCampaignId": "string", "platformAdSetId": "string", "campaignName": "string", "adSetName": "string", "platformObjective": "string", "optimizationGoal": "string", "costType": "string", "servingStatuses": [ "string" ], "platformAdAccountName": "string", "platformCreatedAt": "2019-08-24T14:15:22Z", "bidStrategy": "LOWEST_COST_WITHOUT_CAP", "bidAmount": 0, "roasAverageFloor": 0, "promotedObject": { "custom_event_type": "string", "pixel_id": "string", "page_id": "string", "application_id": "string", "product_set_id": "string" }, "creative": { "assetGroup": { "name": "string", "finalUrl": "http://example.com", "headlines": [ "string", "string", "string" ], "longHeadline": "string", "descriptions": [ "string", "string" ], "businessName": "string", "images": { "landscape": [ "http://example.com" ], "square": [ "http://example.com" ], "logo": [ "http://example.com" ] }, "youtubeVideoId": "string" }, "assetGroupResourceName": "string", "headlines": [ { "text": "string", "pinnedField": "HEADLINE_1" }, { "text": "string", "pinnedField": "HEADLINE_1" }, { "text": "string", "pinnedField": "HEADLINE_1" } ], "descriptions": [ { "text": "string", "pinnedField": "DESCRIPTION_1" }, { "text": "string", "pinnedField": "DESCRIPTION_1" } ], "finalUrls": [ "http://example.com" ], "thumbnailUrl": "string", "imageUrl": "string", "assetResourceName": "string", "assets": { "marketingImages": [ { "resourceName": "string" } ], "squareMarketingImages": [ { "resourceName": "string" } ] }, "videoId": "string", "videoUrl": "string", "creativeId": "string", "creativeFeatures": { "property1": "OPT_IN", "property2": "OPT_IN" }, "catalog": { "productSetId": "string", "format": "single_image", "formatTransformationSpec": [ { "format": "string", "data_source": [ "string" ] } ] }, "objectType": "string", "objectStoryId": "string", "effectiveObjectStoryId": "string", "pageId": "string", "effectiveInstagramMediaId": "string", "instagramUserId": "string", "instagramPermalinkUrl": "string", "mediaUrls": [ "string" ], "carouselCards": [ { "imageUrl": "string", "imageHash": "string", "headline": "string", "description": "string", "linkUrl": "string", "callToAction": "string", "videoId": "string" } ], "isServing": true, "adFormat": "string", "servingHoldReasons": [ "string" ], "body": "string", "googleHeadline": "string", "googleDescription": "string", "youtubeVideoIds": [ "string" ], "linkUrl": "string", "whatsappPhoneNumber": "string", "pinterestImageUrl": "string", "pinterestTitle": "string", "pinterestDescription": "string" }, "targeting": {}, "schedule": { "startDate": "2019-08-24T14:15:22Z", "endDate": "2019-08-24T14:15:22Z" }, "rejectionReason": "string", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z" } ], "daily": [ { "spend": 0, "impressions": 0, "reach": 0, "clicks": 0, "ctr": 0, "cpc": 0, "cpm": 0, "engagement": 0, "conversions": 0, "allConversions": 0, "costPerConversion": 0, "actions": { "property1": 0, "property2": 0 }, "actionValues": { "property1": 0, "property2": 0 }, "purchaseValue": 0, "roas": 0, "costPerAction": { "property1": 0, "property2": 0 }, "outboundClicks": 0, "outboundClicksCtr": 0, "inlineLinkClicks": 0, "inlineLinkClickCtr": 0, "uniqueClicks": 0, "uniqueCtr": 0, "videoPlayActions": 0, "video30SecWatchedActions": 0, "videoThruplayWatchedActions": 0, "videoP25WatchedActions": 0, "videoP50WatchedActions": 0, "videoP75WatchedActions": 0, "videoP95WatchedActions": 0, "videoP100WatchedActions": 0, "video2SecWatchedActions": 0, "video6SecWatchedActions": 0, "video6SecFocusedViews": 0, "videoAvgTimeWatchedActions": 0, "costPerThruplay": 0, "funnel": { "landingPageViews": 0, "contentViews": 0, "searches": 0, "wishlistAdds": 0, "cartAdds": 0, "checkoutsInitiated": 0, "paymentInfoAdds": 0, "purchases": 0, "leads": 0, "registrationsCompleted": 0, "appInstalls": 0, "messagingConversationsStarted": 0, "messagingFirstReplies": 0 }, "engagementBreakdown": { "postEngagement": 0, "pageEngagement": 0, "reactions": 0, "comments": 0, "shares": 0, "saves": 0, "pageLikes": 0, "videoViews": 0, "linkClicks": 0 }, "lastSyncedAt": "2019-08-24T14:15:22Z", "date": "2019-08-24" } ] } ], "daily": [ { "spend": 0, "impressions": 0, "reach": 0, "clicks": 0, "ctr": 0, "cpc": 0, "cpm": 0, "engagement": 0, "conversions": 0, "allConversions": 0, "costPerConversion": 0, "actions": { "property1": 0, "property2": 0 }, "actionValues": { "property1": 0, "property2": 0 }, "purchaseValue": 0, "roas": 0, "costPerAction": { "property1": 0, "property2": 0 }, "outboundClicks": 0, "outboundClicksCtr": 0, "inlineLinkClicks": 0, "inlineLinkClickCtr": 0, "uniqueClicks": 0, "uniqueCtr": 0, "videoPlayActions": 0, "video30SecWatchedActions": 0, "videoThruplayWatchedActions": 0, "videoP25WatchedActions": 0, "videoP50WatchedActions": 0, "videoP75WatchedActions": 0, "videoP95WatchedActions": 0, "videoP100WatchedActions": 0, "video2SecWatchedActions": 0, "video6SecWatchedActions": 0, "video6SecFocusedViews": 0, "videoAvgTimeWatchedActions": 0, "costPerThruplay": 0, "funnel": { "landingPageViews": 0, "contentViews": 0, "searches": 0, "wishlistAdds": 0, "cartAdds": 0, "checkoutsInitiated": 0, "paymentInfoAdds": 0, "purchases": 0, "leads": 0, "registrationsCompleted": 0, "appInstalls": 0, "messagingConversationsStarted": 0, "messagingFirstReplies": 0 }, "engagementBreakdown": { "postEngagement": 0, "pageEngagement": 0, "reactions": 0, "comments": 0, "shares": 0, "saves": 0, "pageLikes": 0, "videoViews": 0, "linkClicks": 0 }, "lastSyncedAt": "2019-08-24T14:15:22Z", "date": "2019-08-24" } ] } ], "pagination": { "page": 0, "limit": 0, "total": 0, "pages": 0 }, "backfillPending": true}Get inbox messaging volume
Daily inbox messaging volume + breakdowns. Folds the raw messaging events into three projections so the client can render the volume chart, KPI strip, and per-platform stacked bar from a single call. Max date range is 365 days.
Get daily account metrics
Returns an ads account's spend, results and other metrics day by day, ready for a daily performance chart. Returns daily aggregate metrics across all ads in a SocialAccount as a single time series, one row per calendar day and currency in the requested range (one row per day unless the account's ad accounts bill in different currencies). Use this for dashboards that draw a daily-spend or daily-conversions chart, instead of calling `/v1/ads/tree` once per day. `accountId` is required. The lookup is sibling-expanded so passing the `metaads` ID also includes ads under the linked `facebook` / `instagram` posting account (and vice-versa), the same convention as `/v1/ads/tree` and `/v1/ads`. Date range defaults to the last 90 days. Capped at 730 days. History: when an ad account connects, Zernio imports its last 90 days of metrics, so `rows` hold no data for days before that. When `accountId` or `adAccountId` resolves to a Meta ad account, a range reaching further back answers `202` with `backfillPending: true` and the covered part while the older days (up to 730 days back) are imported in the background; repeat the request until it returns 200. Other platforms never return `202`. With adAccountId set to a Google customer id this is the customer-level performance report (clicks, cost, impressions, conversions, all conversions per day).