Zernio
Zernio
API Reference

Campaigns and Ads

Overview

Get campaign treeGETGet daily account metricsGET

Campaigns

List campaignsGETCreate a standalone campaignPOSTUpdate a campaignPUTDuplicate a campaignPOSTDelete a campaignDELETEPause or resume a campaignPUTPause or resume many campaignsPOSTAttach extension assets to a Google Search campaignPOST

Ad Sets

Live ad-set details incl. learning phaseGETUpdate an ad setPUTDuplicate an ad setPOSTDelete an ad setDELETEPause or resume a single ad setPUTList Search keywordsGET

Ads

List adsGETGet ad detailsGETCreate standalone adPOSTBoost post as adPOSTUpdate adPUTDuplicate an adPOSTCancel an adDELETEPause or resume a single adPUT

Other

Add Search keywords to an ad groupPOSTCreate a standalone ad groupPOSTCreate a Google Ads portfolio bid strategyPOSTRead a campaign's current biddingGETRead a Google campaign's device, location, and language targetingGETList ad setsGETList Google Ads portfolio bid strategiesGETList campaign-level negative keywordsGETRemove a Search keywordDELETEReplace campaign-level negative keywordsPUTPause or enable a Search keywordPATCHUpdate a Google Ads portfolio bid strategyPATCHEdit a Google campaign's device, location, or language targetingPUT
Dashboard
llms.txtOpenAPI
OverviewPlatformsAPI ReferenceResources
Campaigns and Ads

Update a campaign

Campaign-level edits. Send at least one of budget, bidStrategy, portfolioBidStrategyId, name or platformSpecificData. An unsupported field is always an error, never a silent drop.

Body fieldMetaGoogleOthers
bidStrategyYesYes501
bidAmount, roasAverageFloor400 — ad-set levelYes400
portfolioBidStrategyId400Yes400
budget (CBO; ABO returns 409)Yes501501
nameYes501501
platformSpecificData.spendCapYes400400
accountId (empty campaigns)Yes--

On Google: LOWEST_COST_WITHOUT_CAP = Maximize Conversions, COST_CAP + bidAmount = Target CPA, LOWEST_COST_WITH_MIN_ROAS + roasAverageFloor = Target ROAS, LOWEST_COST_WITH_BID_CAP + bidAmount = Maximize Clicks with a CPC ceiling; portfolioBidStrategyId attaches a portfolio strategy instead (exclusive with bidStrategy). Setting the standard triplet on a campaign that is currently on a PORTFOLIO strategy is rejected: detach it in Google Ads first, since it is shared across campaigns.

accountId forwards the update straight to Meta for a campaign with zero ads, which would otherwise 404; the response then carries updated: 0.


PlatformsMetaGoogleTikTokLinkedInPinterestX
PUT
/v1/ads/campaigns/{campaignId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key authentication - use your Zernio API key as a Bearer token

In: header

Path Parameters

campaignId*string

Platform campaign ID

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

{  "updated": 0,  "budget": {    "amount": 0,    "type": "daily"  },  "budgetLevel": "campaign",  "bidStrategy": "LOWEST_COST_WITHOUT_CAP",  "bidAmount": 0,  "roasAverageFloor": 0,  "portfolioBidStrategyId": "string",  "platformSpecificData": {}}
Was this page helpful?

Create a standalone campaign

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 only `budgetType: lifetime`, Google only `budgetType: daily`). 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`. TikTok campaigns are created without a status and report `ENABLE`. Created `PAUSED` unless `status: ACTIVE` where the platform supports it. **Idempotency:** send an `Idempotency-Key` header to make retries safe.

Duplicate a campaign

Duplicates a campaign, including its ad sets, ads, creatives, and targeting by default (`deepCopy: true`). The copy is created paused so callers can review before launching. Per-platform implementation: - **Meta** uses the native `POST /{campaign-id}/copies` endpoint. - **TikTok** has no native copy primitive; Zernio walks the source graph (`/v2/campaign/get/`, `/v2/adgroup/get/`, `/v2/ad/get/`) and recreates each entity via the corresponding `/create/` endpoints, carrying over budget / targeting / bid_type / bid_price / deep_bid_type / creative fields. Spark Ad linkage (`tiktok_item_id`) is preserved. - **LinkedIn** has no native copy primitive; Zernio walks the source CampaignGroup → Campaigns → Creatives and recreates each entity, carrying over `type` / `costType` / `unitCost` / `optimizationTargetType` / `creativeSelection` / `objectiveType` / `format` / `dailyBudget` / `totalBudget` / `targetingCriteria` / `runSchedule` and every Creative's `content` object verbatim. `statusOption: INHERITED_FROM_SOURCE` is evaluated **per entity**: any Group / Campaign / Creative whose source is `ACTIVE` gets its clone activated too. Duplicating an ACTIVE campaign with `INHERITED_FROM_SOURCE` starts a second front of spend the moment the clone activates — the safe default is `PAUSED`. The new hierarchy is asynchronous to materialize in our DB — we trigger sync discovery automatically. Set `syncAfter: false` to skip and poll `/v1/ads/tree` on your own cadence. Other platforms return 501 Not Implemented.

platform*string

Required: platform campaign IDs are not globally unique.

Value in

  • "facebook"
  • "instagram"
  • "google"
accountId?string

Meta only. Zernio SocialAccount id owning the ad account. Needed only for an EMPTY campaign (zero ads); ignored otherwise.

bidStrategy?string

Meta + Google. On Meta, the campaign default that ad sets inherit unless they override it. On Google, the campaign's own bidding strategy. On Google: LOWEST_COST_WITHOUT_CAP = Maximize Conversions, COST_CAP + bidAmount = Target CPA, LOWEST_COST_WITH_MIN_ROAS + roasAverageFloor = Target ROAS, LOWEST_COST_WITH_BID_CAP + bidAmount = Maximize Clicks with a CPC ceiling; portfolioBidStrategyId attaches a portfolio strategy instead.

Value in

  • "LOWEST_COST_WITHOUT_CAP"
  • "LOWEST_COST_WITH_BID_CAP"
  • "COST_CAP"
  • "LOWEST_COST_WITH_MIN_ROAS"
bidAmount?number

Google only. Whole currency units (USD: 12 = $12.00). Max CPC for LOWEST_COST_WITH_BID_CAP, CPA target for COST_CAP; required for both.

roasAverageFloor?number

Google only. Decimal ROAS multiplier (2.0 = 2.0x), required for LOWEST_COST_WITH_MIN_ROAS.

portfolioBidStrategyId?string

Google only. Attach an existing portfolio bid strategy (numeric id from GET /v1/ads/bid-strategies) instead of setting bidStrategy. Exclusive with bidStrategy.

Match^\d+$
budget?

Meta only. The CBO budget.

name?string

Meta only. Rename the campaign.

Lengthlength <= 255
platformSpecificData?

Meta only. Platform implied by the platform body param, same convention as POST /v1/ads/create.