Boost post as ad
Creates a paid ad campaign from an existing published post. Creates the full platform campaign hierarchy (campaign, ad set, ad).
API key authentication - use your Zernio API key as a Bearer token
In: header
Zernio post ID (provide this or platformPostId)
Platform post ID (alternative to postId)
Social account ID
Platform ad account ID
length <= 255Available goals vary by platform. Meta (Facebook/Instagram) and TikTok support all 7. LinkedIn supports all except app_promotion. Twitter/X supports engagement, traffic, awareness, video_views, app_promotion. Pinterest and Google Ads support only engagement, traffic, awareness, video_views.
"engagement" | "traffic" | "awareness" | "video_views" | "lead_generation" | "conversions" | "app_promotion""LOWEST_COST_WITHOUT_CAP" | "LOWEST_COST_WITH_BID_CAP" | "COST_CAP" | "LOWEST_COST_WITH_MIN_ROAS"Bid cap in WHOLE currency units (USD: 5 = $5.00; JPY: 100 = ¥100). Required when
bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. Backward-compat: providing
bidAmount without bidStrategy is treated as LOWEST_COST_WITH_BID_CAP.
Minimum ROAS as a decimal multiplier (e.g. 2.0 = 2.0x ROAS). Required when
bidStrategy is LOWEST_COST_WITH_MIN_ROAS. Sent to Meta as
bid_constraints.roas_average_floor × 10000 (Meta uses fixed-point integers).
Meta only. Tracking specs (pixel, URL tags).
Meta only. Required for housing, employment, credit, or political ads.
TikTok-only. Custom destination URL for the Spark Ad. Without this, TikTok
Spark Ads have no clickable destination — required for traffic / conversion
objectives. Maps to landing_page_url on the creative entry of /v2/ad/create/
(TikTok SDK AdcreateCreatives.landing_page_url). Ignored on Meta / LinkedIn /
Pinterest / X / Google (those infer the destination from the boosted post).
uriTikTok-only. Call-to-action button label on the Spark Ad creative (e.g.
LEARN_MORE, SHOP_NOW, DOWNLOAD_NOW, SIGN_UP, WATCH_NOW). Maps to
call_to_action on the creative entry of /v2/ad/create/. Pass-through —
the platform validates the value. See TikTok's "Enumeration - Call-to-Action"
reference for the full list.
TikTok-only. Spark Code (creator's auth_code) authorizing cross-creator
Spark Ads — the advertiser can boost a video owned by a DIFFERENT TikTok
account. Without this, boosts are limited to videos owned by the same
account running the ads (same-BC creators only). The creator generates the
code in their TikTok app's Promote settings and shares it with the
advertiser. Maps to auth_code on the creative entry of /v2/ad/create/.
Name of the legal entity benefiting from the ad. Required by Meta when targeting EU users (DSA Article 26). Not enforced at schema level; enforced server-side when targeting intersects EU member states.
length <= 100Name of the legal entity paying for the ad. Required by Meta when targeting EU users (DSA Article 26). Note Meta API spelling: dsa_payor (not dsa_payer).
length <= 100Response Body
application/json
application/json
import Zernio from '@zernio/node';const zernio = new Zernio({ apiKey: process.env.ZERNIO_API_KEY });const { data } = await zernio.ads.boostPost({ body: { accountId: 'account_abc123', adAccountId: 'adaccount_abc123', name: 'Example', goal: 'engagement', budget: { amount: 0, type: 'daily', }, },});console.log(data);{
"ad": {
"_id": "string",
"name": "string",
"platform": "facebook",
"status": "active",
"adType": "boost",
"goal": "engagement",
"isExternal": true,
"budget": {
"amount": 0,
"type": "daily"
},
"metrics": {
"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,
"lastSyncedAt": "2019-08-24T14:15:22Z"
},
"platformAdId": "string",
"platformAdAccountId": "string",
"platformCampaignId": "string",
"platformAdSetId": "string",
"campaignName": "string",
"adSetName": "string",
"platformObjective": "OUTCOME_SALES",
"optimizationGoal": "OFFSITE_CONVERSIONS",
"platformAdAccountName": "Zernio - previously Late",
"platformCreatedAt": "2019-08-24T14:15:22Z",
"bidStrategy": "LOWEST_COST_WITHOUT_CAP",
"bidAmount": 5,
"roasAverageFloor": 2,
"promotedObject": {
"custom_event_type": "PURCHASE",
"pixel_id": "string",
"page_id": "string",
"application_id": "string",
"product_set_id": "string"
},
"creative": {
"thumbnailUrl": "string",
"imageUrl": "string",
"videoId": "string",
"videoUrl": "string",
"objectType": "string",
"objectStoryId": "string",
"effectiveObjectStoryId": "string",
"effectiveInstagramMediaId": "string",
"instagramUserId": "string",
"instagramPermalinkUrl": "string",
"mediaUrls": [
"string"
],
"body": "string",
"googleHeadline": "string",
"googleDescription": "string",
"linkUrl": "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"
},
"message": "string"
}{
"error": "Unauthorized"
}List comments on an ad GET
Returns comments on an ad's underlying creative post. Useful for moderating or analyzing engagement on dark posts (ad creatives that never went live organically), which the regular GET /v1/inbox/comments/{postId} endpoint cannot serve because dark posts are not in Zernio's post database. An ad that runs on both Facebook feed and Instagram feed has two separate underlying posts with separate comment threads (the creative's effective_object_story_id and effective_instagram_media_id). Use the `placement` query param to pick one; with no param the Instagram side is returned when it exists, otherwise Facebook. The identifiers are read from the ad record (persisted during sync) with a Marketing-API fallback for ads that predate the field. For Instagram-placed comments, the Instagram account that runs the ad must be connected to Zernio — those comments are read through that account's token. If no connected Instagram account on the profile can read the ad's media, the call returns ads_connection_required (the Facebook side, if any, is still readable via ?placement=facebook). Meta-only. Other ad platforms (TikTok, LinkedIn, Pinterest, Google, X) do not expose a public per-ad comments API and return feature_not_available. Requires the Ads add-on. Response shape matches GET /v1/inbox/comments/{postId}. The `{adId}` path segment accepts any identifier dialect Zernio indexes for the ad: Zernio internal `_id` (24-char hex), Meta's numeric `platformAdId` (the value shipped in `comment.received` webhooks as `comment.ad.id`), or the creative's `effective_object_story_id` / `effective_instagram_media_id`. Caller doesn't need a translation step.
Create standalone ad POST
Creates a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X/Twitter, and LinkedIn. Supports three mutually-exclusive request shapes selected by the body, a legacy single-creative shape (all platforms, default), a Meta-only multi-creative shape via the creatives array (one ad set with N ads sharing budget and targeting), and a Meta-only attach shape via adSetId (adds one new ad to an existing ad set). Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content "dark post" authored by a Company Page (see `organizationId`); supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an `Idempotency-Key` header to make retries safe: the first request with a given key creates the ad and we store the response; a retry with the same key replays that exact response (with `Idempotent-Replayed: true`) instead of creating duplicates. Reusing a key with a different body returns 422; a key whose first request is still in flight returns 409 (retry after a short backoff). Keys are scoped to your credential and expire after 24h.