Get campaign analytics
Returns performance analytics for a whole campaign in one call: summary metrics, a daily
timeline over the requested date range (summed across the campaign's ads), and optional
demographic breakdowns. Breakdowns are fetched live from Meta at the campaign level (one call
per dimension, no per-ad fan-out), so an agency dashboard gets campaign-level age/gender/etc.
without summing thousands of per-ad reads. campaignId is the platform campaign id; pass
platform when a campaign id could be ambiguous across platforms. If no date range is provided,
defaults to the last 90 days. Date range is capped at 730 days max.
API key authentication - use your Zernio API key as a Bearer token
In: header
Path Parameters
Platform campaign id (platformCampaignId).
Query Parameters
Disambiguate when the campaign id exists across platforms (e.g. facebook, instagram).
Start of date range (YYYY-MM-DD). Defaults to 90 days ago.
dateEnd of date range (YYYY-MM-DD). Defaults to today. Max 730-day range.
dateComma-separated breakdown dimensions.
Meta: age, gender, country, publisher_platform, device_platform, region, platform_position, impression_device, video_asset, image_asset, body_asset, title_asset.
LinkedIn (firmographics): job_title, job_function, seniority, industry,
company, company_size, country, region. Rows carry the raw pivot value
plus a resolved name. LinkedIn serves these aggregated over the whole
range, delays the data 12-24h, and omits segments with fewer than 3 events.
Response Body
application/json
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.adinsights.getCampaignAnalytics({ path: { campaignId: 'campaign_abc123', },});console.log(data);{
"campaign": {
"id": "string",
"name": "string",
"platform": "string",
"status": "string",
"currency": "string"
},
"backfillPending": true,
"analytics": {
"summary": {
"spend": 0,
"impressions": 0,
"reach": 0,
"clicks": 0,
"ctr": 0,
"cpc": 0,
"cpm": 0,
"engagement": 0,
"conversions": 0,
"costPerConversion": 0,
"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
},
"purchaseValue": 0,
"roas": 0,
"videoPlayActions": 0,
"video30SecWatchedActions": 0,
"videoThruplayWatchedActions": 0,
"videoP25WatchedActions": 0,
"videoP50WatchedActions": 0,
"videoP75WatchedActions": 0,
"videoP95WatchedActions": 0,
"videoP100WatchedActions": 0,
"videoAvgTimeWatchedActions": 0,
"lastSyncedAt": "2019-08-24T14:15:22Z"
},
"daily": [
{
"spend": 0,
"impressions": 0,
"reach": 0,
"clicks": 0,
"ctr": 0,
"cpc": 0,
"cpm": 0,
"engagement": 0,
"conversions": 0,
"costPerConversion": 0,
"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
},
"purchaseValue": 0,
"roas": 0,
"videoPlayActions": 0,
"video30SecWatchedActions": 0,
"videoThruplayWatchedActions": 0,
"videoP25WatchedActions": 0,
"videoP50WatchedActions": 0,
"videoP75WatchedActions": 0,
"videoP95WatchedActions": 0,
"videoP100WatchedActions": 0,
"videoAvgTimeWatchedActions": 0,
"lastSyncedAt": "2019-08-24T14:15:22Z",
"date": "2019-08-24"
}
],
"breakdowns": {
"property1": [
{}
],
"property2": [
{}
]
}
}
}{
"error": "string",
"type": "invalid_request_error",
"code": "string",
"param": "string",
"platform": "string",
"platformError": {},
"details": {}
}{
"error": "Unauthorized"
}{
"error": "Not found"
}Poll an async insights report run GET
Status and results for a report run created via POST /v1/ads/insights/reports. While the job runs, returns `status` and `percentCompletion`. Once `status` is "Job Completed" the response also carries a `data` page, cursor-paginated via `limit` / `after`.
Flexible live insights query GET
Live, flexible insights query against Meta's Graph API. Unlike GET /v1/ads/{adId}/analytics (fixed metric set, cached), this forwards caller-chosen `fields`, `breakdowns` and `filtering` to any Meta insights node and returns Meta's rows verbatim. `objectId` selects the node: an ad account, campaign, ad set or ad platform id. `level` sets row granularity independently of the node. Semantic validation is Meta's: an unknown field or invalid breakdown combination returns a 400 carrying Meta's message. For long ranges or agency-scale accounts prefer the async variant (POST /v1/ads/insights/reports).