List campaigns
Lists your campaigns with spend, impressions and clicks summed across their ads, plus each campaign's status and budget.
Returns campaigns as virtual aggregations over ad documents grouped by platform campaign ID. Metrics (spend, impressions, clicks, etc.) are summed across all ads in each campaign. Campaign status is derived from child ad statuses (active > pending_review > paused > error > completed > cancelled > rejected). Google campaign budgets include amountMicros, explicitlyShared, resourceName and deliveryMethod after the next successful sync. This endpoint does not fetch Google live.
Status freshness. status, configuredStatus, platformStatus, platformAdSetStatus
and platformCampaignStatus are the values Zernio last stored. Background sync refreshes
them, typically within 15 to 60 minutes (Google up to about 3 hours), and ended or
long-paused objects may be refreshed less often. Zernio's own status writes re-read the
switches they change. A change made in the platform's own ads manager therefore shows up
here only after the next sync. Controllers that act on a switch should pass live=true,
which reads the switches from the platform now, stores them, and returns statusReadAt
(null when the read failed and the stored values were returned).
With live=true (which needs limit of 20 or less) each returned campaign's own switch
(platformCampaignStatus) is read live. Live reads cover TikTok, Meta, Google, OpenAI and Reddit.
The rolled-up status is not re-derived by a live read.
Budgets here are SYNCED, never read live, including with live=true. To read the
current budgets (and status) of every campaign and ad set of a Meta ad account live in
one call, for example as a pre-write spend gate, use GET /v1/ads/accounts/live.
Authorization
bearerAuth API key authentication: send your Zernio API key in the Authorization header, prefixed with Bearer.
In: header
Query Parameters
Meta only. Campaign reads aggregate over ad documents, so a campaign with ZERO ads is normally invisible here, the state the two-step create (campaign, then ads via existingCampaignId) leaves behind whenever Meta rejects the ad step. Set true to list those too, with adCount: 0 and zeroed metrics. Requires accountId and adAccountId, since an empty campaign has no ad row to resolve a token or ad account from.
Page number (1-based)
1 <= value11 <= 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"
Platform ad account ID (e.g. act_123 for Meta)
Platform campaign ID (the platformCampaignId on each returned campaign). Returns only that campaign, or an empty list when it is not visible to the caller. Mirrors the same filter on /v1/ads and /v1/ads/tree.
Meta only: Facebook Page ID. Campaigns have no Page of their own, so this keeps campaigns having at least one ad backed by this Page, with adCount and metrics computed over those ads only. Mirrors the same filter on /v1/ads and /v1/ads/tree.
Account ID
Profile ID
Start of metrics date range (YYYY-MM-DD, inclusive). Defaults to 90 days ago when both date params are omitted.
dateEnd of metrics date range (YYYY-MM-DD, inclusive). 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. Filters the campaign set itself, so pagination.total counts only matching campaigns. Mirrors the same filter on /v1/ads/tree.
Return only campaigns whose spend between fromDate and toDate reaches this amount, in each campaign's OWN currency (the currency field on the campaign). Implies hasDelivery; minSpend=0 applies no filter. Mirrors the same filter on /v1/ads/tree.
0 <= valueRead the on/off switches live from the platform instead of returning the synced values. The fresh values are stored (so later reads return them too) and the response carries statusReadAt, the time of the read. At most 20 platform objects are read per request. Where a read fails (credentials, platform error, no reader on that platform), the stored values come back with statusReadAt: null. See "Status freshness" in the operation description. On X the budget is read live in the same read: on GET /v1/ads/{adId} budget, adSetBudget, campaignBudget and budgetLevel are the line item and campaign budgets X holds now (stored like the switches); on the ad set and campaign listings budget is the one that line item or campaign holds now (returned, not stored); a row whose budget the other level holds keeps its synced budget.
falseResponse Body
application/json
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.adcampaigns.listAdCampaigns();console.log(data);{ "campaigns": [ { "platformCampaignId": "123456789", "platform": "google", "campaignName": "Search campaign", "budget": { "amount": 5, "amountMicros": "5000000", "type": "daily", "explicitlyShared": false, "resourceName": "customers/9122445560/campaignBudgets/1234567890", "deliveryMethod": "STANDARD" } } ], "pagination": { "page": 1, "limit": 20, "total": 1, "pages": 1 }}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).
Create a standalone campaign
Creates an empty campaign, paused, so you can add ad sets and ads to it afterwards. Creates a campaign WITHOUT its first ad set / ad, on the platform of the given `accountId`. Ad sets join it later via `existingCampaignId` on the create endpoints. Platform notes: on Meta a budget here is campaign-level (CBO) by definition; omit it for ABO (each ad set carries its own budget), and `specialAdCategories` is Meta-only (400 elsewhere); `bidStrategy` is Meta and Google (400 elsewhere), and Google also accepts `portfolioBidStrategyId` instead. Google, X and OpenAI require a budget (422 without one; OpenAI accepts daily or lifetime, Google only `budgetType: daily`). On OpenAI `goal` sets the campaign objective, and `conversions` needs an active standard conversion event on the account. On Reddit `goal` is one of traffic, awareness, conversions, video_views or lead_generation (422 otherwise) and the budget is optional: with one, the campaign uses Reddit's campaign budget optimization and carries the pixel (see `promotedObject`, which then needs `customEventType` for `conversions`), daily or lifetime (a lifetime budget needs `endDate`, 400 otherwise). `startDate` / `endDate` set the campaign's schedule and need that campaign budget (400 without one). Without a budget, each ad set carries its own budget and dates. LinkedIn creates the campaign GROUP (our campaign level) and rejects a budget, which lives on the campaign (ad set) level there; it comes back `status: DRAFT`. Created `PAUSED` (TikTok `DISABLE`) unless `status: ACTIVE` where the platform supports it. **Idempotency:** send an `Idempotency-Key` header to make retries safe.