Zernio
APIFor you
Zernio
APIFor you
IntroductionQuickstartBuild a PlatformSDKsCLIMCPWebhooksWorkflowsSupport AssistantGuidesSecurityGlossaryPricingBillingChangelogRefer & earn
Dashboard
OverviewPlatformsAPI ReferenceResources

Changelog

Every change to the Zernio API, newest first.


Week of Oct 19, 2026

HubSpot, store orders and Wix blogs

Sync your inbox to HubSpot, read Shopify and WooCommerce orders in one format, publish to Wix, and four new Instagram endpoints.

Read the update →

Week of Oct 12, 2026

Route every event to your tenant

External ids on profiles, tenant routing in webhooks, a branded connect screen, deleting inbox conversations and Meta ad review status.

Read the update →

Week of Oct 5, 2026

Subtitles, message requests and Google Ads

Captions on videos, Facebook and Instagram message requests, safer connects, sample webhooks and a big Google Ads release. Seven changes need a look.

Read the update →

All platforms

Platforms

Areas

Subscribe

Follow

TelegramEvery change, as it shipsX@zerniodevs

Integrate

RSS feedThis view, in your readerJSONThis view, as dataWebhookapi.changelog.publishedAPIList changelog entries
26 October

Meta and Google ads can auto-add Zernio tag

You can now control automatic Zernio click tagging on ad creation with tracking.zernioTag (default true) for Meta and Google.

New feature#
DetailsHide details
Ad creation now supports automatic Zernio click tagging via tracking.zernioTag on Meta and Google.

When enabled (default true), Zernio appends a zrn parameter to the ad landing URL so downstream orders/events can be mapped back to the platform ad.

Use tracking.zernioTag:
• true (default) - create ads with the Zernio tag
• false - create ads without the Zernio tag

Applies to POST /v1/ads/create (Meta, Google only).

Events API can forward conversions to all destinations

Send conversion events once and have Zernio forward them to all saved ad platform destinations for a profile. New endpoints also let you list, add, and remove per-profile event destinations.

New feature#
DetailsHide details
New Events endpoints let you send conversion events once and have Zernio forward them to every saved ad destination for a profile (with per-destination results and partial failure handling).

Use POST /v1/events with profileId and events (1–1000). Optionally override saved routing with destinations (1–20), pass batch consent via consent (GRANTED/DENIED), or send test events with testCode (forwarded but not stored).

Manage saved forwarding targets per profile with:
• GET /v1/events/destinations (optional profileId)
• POST /v1/events/destinations (optional eventNames filter)
• DELETE /v1/events/destinations/{destinationId}
curl -X POST "$ZERNIO_API/v1/events" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"profileId":"prof_123","events":[{"eventName":"Purchase","eventId":"evt_1"}]}'
25 October

Ad rule runs now report notification status

Rule run evaluations can now include notification delivery status for notify actions, including whether the webhook was queued and the failure reason.

Improvement#
DetailsHide details
Ad rule runs now include evaluation.notification on each run when a rule with a notify action matched objects and attempted to queue the webhook.

This lets you see whether the ad_rule.triggered webhook was queued successfully, and why it failed when it wasn’t.

New field: runs[].evaluation.notification
• status: done | failed
• reason: string (present when it couldn’t be queued)

Ads rules and ad_rule.triggered webhook added

You can now create scheduled ad rules that evaluate campaign/ad set metrics and automatically notify, pause, activate, or adjust budgets. A new ad_rule.triggered webhook event is available.

New feature#
DetailsHide details
Ads automation is now available via Ad Rules: create scheduled rules that evaluate ad account metrics and can notify (webhook), pause, activate, or adjust_budget on matching campaigns/ad sets.

New endpoints:
• GET /v1/ads/rules, POST /v1/ads/rules
• GET/PATCH/DELETE /v1/ads/rules/{ruleId}
• POST /v1/ads/rules/{ruleId}/preview (evaluate without acting)
• GET /v1/ads/rules/{ruleId}/runs (run history)

Key fields:
• level: campaign | adset
• conditions.all[]: metric/window comparisons (e.g. spend, ctr, roas over today, last_7d, etc.)
• actions[]: notify, pause, activate, adjust_budget
• schedule.everyMinutes: 60 | 180 | 360 | 720 | 1440
• cooldownMinutes: how long an object is left alone after an action

Webhooks: you can now subscribe to ad_rule.triggered (also available as a sample via POST /v1/webhooks/test).
curl -X POST "https://api.zernio.com/v1/ads/rules" \
  -H "Authorization: Bearer $ZERNI0_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Pause high spend","accountId":"acc_...","adAccountId":"123","level":"campaign","conditions":{"all":[{"metric":"spend","window":"today","op":">=","value":100}]},"actions":[{"type":"pause"},{"type":"notify"}]}'

Posts listing now returns Pinterest Pin details

The posts listing response now includes Pinterest-native Pin fields (title, description, link, boardId, boardOwnerUsername) when the post is from Pinterest.

Improvement#
DetailsHide details
Pinterest posts returned by GET /v1/accounts/{accountId}/posts now include additional native Pin fields when applicable.

For Pinterest items, you can now read:
• title and description (native Pin values; message still contains the joined text)
• link (Pin destination URL)
• boardId and boardOwnerUsername

Absent fields are omitted for non-Pinterest platforms.
curl -s \
  -H "Authorization: Bearer $TOKEN" \
  "https://api.zernio.com/v1/accounts/$ACCOUNT_ID/posts"

Meta boosts now support OUTCOME_ENGAGEMENT objective

You can now set metaObjective on Meta engagement boosts to use the Ads Manager “Boost post” objective behavior (POST_ENGAGEMENT / ON_POST) while keeping existing defaults when omitted.

New feature#
DetailsHide details
Meta engagement boosts can now opt into the Ads Manager “Boost post” objective via the new metaObjective field on POST /v1/ads/boost.

Set metaObjective to OUTCOME_ENGAGEMENT (Meta only) to create an engagement boost with optimization_goal POST_ENGAGEMENT (unless optimizationGoal is set) and destination_type ON_POST (unless destinationType is set). When omitted, engagement boosts keep the existing default behavior.
curl -X POST "$BASE_URL/v1/ads/boost" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"accountId":"...","adAccountId":"act_...","platformPostId":"...","name":"Boost","goal":"engagement","metaObjective":"OUTCOME_ENGAGEMENT","budgetAmount":5,"budgetType":"daily"}'

Inbox API now supports Messenger labels

You can now list, create, and delete Facebook Messenger Page conversation labels via the Inbox API. Other platforms are not supported.

New feature#
DetailsHide details
Inbox now supports managing Facebook Messenger conversation labels: list, create, and delete Page custom labels.

Use:
• GET /v1/inbox/labels to list labels
• POST /v1/inbox/labels to create a label
• DELETE /v1/inbox/labels/{labelId} to delete a label

Key inputs:
• accountId (Facebook social account ID)
• name (label name, create)
• labelId (Meta label id, delete)

Notes:
• Facebook Messenger only; other platforms return platform_not_supported
• Requires Inbox addon (403)
• If no Page is selected: linked_account_required (422)
curl -sS -H "Authorization: Bearer $TOKEN" \
  "https://api.zernio.com/v1/inbox/labels?accountId=64e1f0a9e2b5af0012ab34cd"
Inbox conversations now support Facebook Messenger custom labels: you can list, add, and remove Page labels on the person in a conversation.

Available endpoints:
• GET /v1/inbox/conversations/{conversationId}/labels
• POST /v1/inbox/conversations/{conversationId}/labels
• DELETE /v1/inbox/conversations/{conversationId}/labels/{labelId}

Key params:
• conversationId (path)
• accountId (Facebook social account ID; query for GET/DELETE, body for POST)
• labelId (Meta label id; digits only)

Facebook Messenger only; other platforms return platform_not_supported. Requires Inbox addon.
curl -X POST "$BASE_URL/v1/inbox/conversations/$CONVERSATION_ID/labels" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"accountId":"64e1f0a9e2b5af0012ab34cd","labelId":"1712444532121303"}'
24 October

Instagram follow gate can include profile button

Comment automations can now add an optional profile URL button in the follow gate using followGate.profileButtonLabel, helping users navigate to the connected Instagram profile.

Improvement#
DetailsHide details
Instagram comment automations now support an optional profile link button in the follow gate via followGate.profileButtonLabel.

When set, the follow gate DM (followGate.message) and the not-following message (when it includes the confirm button) will also include a URL button that opens the connected Instagram account’s profile.

Set followGate.profileButtonLabel to a 1–20 char label (omit it to send only the confirm button).

Facebook Pages public info can now be managed

You can now fetch and update the selected Facebook Page’s public info (about, description, website, phone, emails, hours) for a connected Facebook account.

New feature#
DetailsHide details
Facebook accounts now support reading and updating the selected Page’s public info.

Use GET /v1/accounts/{accountId}/facebook-page-info to fetch fields like about, description, website, phone, emails, and hours (missing Page fields may be null).

Use PATCH /v1/accounts/{accountId}/facebook-page-info to update any subset of those fields (unknown fields are rejected; send an empty string to clear a text field). Updating requires Meta permission pages_manage_metadata and a Page role that can edit the Page.
curl -X PATCH "$BASE_URL/v1/accounts/$ACCOUNT_ID/facebook-page-info" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"website":"https://zernio.com"}'

YouTube Analytics now returns 429 rate limits

YouTube channel insights and demographics now document a 429 RateLimited response so you can implement backoff/retry and detect Google quota exhaustion via error details.

Improvement#
DetailsHide details
YouTube Analytics endpoints now return 429 RateLimited when requests exceed quota.

This applies to GET /v1/analytics/youtube/channel-insights and GET /v1/analytics/youtube/demographics, so clients can handle throttling explicitly (retry/backoff) instead of treating it as a generic 5xx.

On 429, check ErrorResponse.details for Google quota signals like quotaExhausted and quotaScope.
curl -G "https://api.zernio.com/v1/analytics/youtube/channel-insights" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "accountId=$ACCOUNT_ID"

Facebook posts can now be pinned and unpinned

You can now pin or unpin a published Facebook Page post, with optional account selection when a post was published to multiple Facebook accounts.

New feature#
DetailsHide details
Posts can now be pinned or unpinned on Facebook Pages.

Use POST /v1/posts/{postId}/pin to pin and POST /v1/posts/{postId}/unpin to unpin a published Facebook Page post. Only platform=facebook is supported; other platforms return platform_not_supported.

If the post was published to multiple Facebook accounts, pass accountId (otherwise you may get ambiguous_account).
curl -X POST "$BASE_URL/v1/posts/{postId}/pin" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"platform":"facebook","accountId":"..."}'

Facebook Pages can now list visitor posts

You can now fetch posts published by other people on a connected Facebook Page, with cursor pagination and optional media details.

New feature#
DetailsHide details
Facebook Pages now support listing visitor posts via GET /v1/accounts/{accountId}/facebook-visitor-posts.

This returns posts published by other people on the connected Page (newest first). It filters out the Page’s own posts and tag-only timeline posts.

Key params:
• limit (1–100, default 25) — number of Page feed entries to scan
• cursor — pass the previous response’s nextCursor for pagination

Response includes data (array of FacebookVisitorPost) and nextCursor (string or null). media.mediaType is one of image, video, carousel, text.

Requires Meta permission pages_read_user_content; if the Page was connected without it, you’ll get platform_api_error.
curl -sS -H "Authorization: Bearer $ZERNIO_API_KEY" \
  "https://api.zernio.com/v1/accounts/$ACCOUNT_ID/facebook-visitor-posts?limit=25"

Inbox mentions now include Facebook

Mentions can now return Facebook Page post and comment mentions, including a new postId field and a new type value for post mentions.

New feature#
DetailsHide details
Inbox mentions now include Facebook.

You can retrieve Facebook Page mentions (post + comment mentions) alongside LinkedIn and Instagram via GET /v1/inbox/mentions.

New values:
• platform: facebook
• type: post (Facebook post mention)

New field:
• postId (Facebook only)

Note: Facebook mentions can’t be replied to via POST /v1/inbox/mentions/reply.
curl -sS -H "Authorization: Bearer $TOKEN" \
  "$BASE_URL/v1/inbox/mentions?limit=25"

KYC can now order an exact phone number

You can now pass an E.164 phoneNumber when submitting KYC to order that specific number. If it’s unavailable, the request fails with 409 and nothing is ordered.

New feature#
DetailsHide details
KYC submissions can now request an exact phone number to order via phoneNumber.

Send phoneNumber (E.164) from the available-number list to order that specific number. If it’s no longer available (or can’t be used), the request fails with 409 (phone_number_unavailable) and nothing is ordered—no substitution and no pre-order.

Key rules:
• phoneNumber requires quantity = 1 (or omitted)
• Source it from GET /v1/phone-numbers/available (or the WhatsApp alias)
curl -X POST "$BASE_URL/v1/phone-numbers/kyc" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"profileId":"prof_123","country":"BR","phoneNumber":"+5511999999999"}'

LinkedIn mentions now resolve from URLs

You can now write LinkedIn @mentions as profile/company URLs in post text and have them resolved automatically. Mention resolution failures return structured codes/details and may return 503 when LinkedIn is unavailable.

Improvement#
DetailsHide details
LinkedIn @mentions can now be written directly in post text and resolved automatically when creating or updating posts.

Put a LinkedIn profile/company URL inside @[... ] in content (or LinkedIn customContent), e.g. @[https://www.linkedin.com/in/jane-doe] or @[Jane](https://www.linkedin.com/company/acme). Zernio resolves it to LinkedIn’s real name + link at publish/schedule time.

New error handling for mention resolution:
• 400 with code linkedin_mentions_invalid and details.mentions[] (LinkedInMentionIssue)
• 429 with code rate_limited
• 401 with code reconnect_required
• Retryable 503 with code temporarily_unavailable

Note: GET /v1/accounts/{accountId}/linkedin-mentions still works for previewing/producing @[Name](urn:...), but displayName is now deprecated.
curl -X POST "$ZERNIO_API/v1/posts" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content":"Thanks @[https://www.linkedin.com/in/jane-doe]","platforms":[{"platform":"linkedin","accountId":"ACCOUNT_ID"}],"publishNow":true}'

Facebook now supports fetching tagged posts

You can now retrieve public posts where a connected Facebook Page is tagged, with cursor pagination and support for Meta permission errors.

New feature#
DetailsHide details
Facebook Pages can now list posts they’re tagged in via GET /v1/accounts/{accountId}/facebook-tagged-posts.

This returns public posts where other people or Pages tagged the connected Page (cursor-paginated).

Use:
• limit (1–50, default 25)
• cursor (pass the previous response’s nextCursor)

Requires a Facebook account with a Page selected; Meta may return platform_api_error if the connection lacks pages_read_user_content.
curl -sS -H "Authorization: Bearer $ZERNI0_API_KEY" \
  "https://api.zernio.com/v1/accounts/$ACCOUNT_ID/facebook-tagged-posts?limit=25"
23 October

LinkedIn mention resolution adds rate limiting and structured errors

LinkedIn mention resolution now includes a 429 rate-limited response and standardized error fields (type/code/param/platform) to make error handling more consistent.

Improvement#
DetailsHide details
LinkedIn mention resolution now returns standardized error fields and can respond with 429 when rate limited.

Error responses for this endpoint now use error plus structured fields like type, code, param, docUrl, and platform (when applicable), making it easier to branch on specific failure cases.

Example error codes you may see include missing_required_field, linkedin_mention_no_organization, reconnect_required, linkedin_mention_lookup_forbidden, linkedin_person_not_resolvable, linkedin_organization_not_found, account_not_found.
curl -G "https://api.zernio.com/v1/accounts/{accountId}/linkedin-mentions" \
  -H "Authorization: Bearer $ZERNI0_API_KEY" \
  --data-urlencode "url=https://www.linkedin.com/company/microsoft"

TikTok Smart+ materials now report missing rows

TikTok Smart+ materials reporting now includes missingRows so you can detect partial results when TikTok declares more rows than can be retrieved.

Improvement#
DetailsHide details
TikTok Smart+ materials reporting now returns missingRows on successful responses.

When TikTok declares more rows than can be retrieved (even after a retry), the API may still return 200 with missingRows set (within a small tolerance). Use missingRows to detect partial results and decide whether to retry or proceed.

New field:
• missingRows - number of declared rows that could not be returned (0 when complete)
curl -G "https://api.zernio.com/v1/ads/tiktok-smart-plus-materials" \
  --data-urlencode "accountId=..." \
  --data-urlencode "adAccountId=..." \
  --data-urlencode "startDate=2026-10-01" \
  --data-urlencode "endDate=2026-10-07"

Webhooks removed ad_rule.triggered event

The ad_rule.triggered webhook event (and its payload schema) has been removed. Remove it from webhook subscriptions and webhook test requests.

Breaking change#
DetailsHide details
ad_rule.triggered has been removed from webhook events.

If your integration subscribes to or tests this event, you must remove it from events (create/update) and from event in test fires. Existing webhook configs that still include it will no longer validate against the API spec.

Removed:
• ad_rule.triggered (webhook event)
• WebhookPayloadAdRuleTriggered (payload schema)
curl -X PUT "$ZERNI0_BASE_URL/v1/webhooks/settings" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"webhookId":"507f1f77bcf86cd799439011","events":["ad.status_changed"]}'

Webhooks now support ad rule triggers

You can now subscribe to and test the new ad_rule.triggered webhook event, which fires when an ad rule run matches campaigns or ad sets (closed beta).

New feature#
DetailsHide details
Webhooks now support the ad_rule.triggered event.

This event fires when a scheduled ad rule run finds campaigns or ad sets that meet all rule conditions (ad rules are currently in closed beta and only fire for pilot accounts).

Use events to subscribe to ad_rule.triggered, and use POST /v1/webhooks/test with event=ad_rule.triggered to receive a sample payload.
curl -X POST "$ZERNIO_API/v1/webhooks/test" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"webhookId":"YOUR_WEBHOOK_ID","event":"ad_rule.triggered"}'

Invites can now disable resource groups

You can now create invite tokens that restrict specific resource groups via disabledResourceGroups, and the invite response/user data may include the applied restrictions.

Improvement#
DetailsHide details
Invite tokens can now include disabledResourceGroups to restrict what resource groups a new team member can access.

Set disabledResourceGroups on POST /v1/invite/tokens to disable specific groups (same set as restricted API keys). Omitted or empty means full access; groups the caller lacks are always added.

Allowed values include: publishing, engagement, messages, contacts, analytics, ads, telephony, accounts, billing, webhooks, commerce.

The created invite now returns disabledResourceGroups, and user objects may expose disabledResourceGroups (e.g. in post user data).
curl -X POST "$ZERNI0/api/v1/invite/tokens" \
  -H "Authorization: Bearer $ZERNIO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scope":"all","role":"member","disabledResourceGroups":["billing","ads"]}'

Connect now supports phone handoff via QR

You can now start a connect flow on desktop and let users finish OAuth on their phone via a QR code, then poll for the outcome with a new handoff status endpoint.

New feature#
DetailsHide details
Connect now supports phone handoff to finish OAuth on a user’s phone via QR code.

Start a connect with handoff=true on GET /v1/connect/{platform} to receive a handoff object (id, url, expiresAt). Show handoff.url as a QR code, then poll GET /v1/connect/handoffs/{handoffId} until status is connected, failed, or expired.

Handoff status: waiting, opened, connected, failed, expired.
curl -G "https://api.zernio.com/v1/connect/instagram" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "profileId=$PROFILE_ID" \
  --data-urlencode "handoff=true"

Accounts and follower stats add cursor pagination

You can now page through accounts and follower stats using cursor-based pagination via limit/cursor, with nextCursor returned in the pagination object.

Improvement#
DetailsHide details
Account listing and follower stats now support cursor-based pagination.

Use limit to fetch the first page, then pass pagination.nextCursor back as cursor until it becomes null. This avoids page shifting when accounts are added/removed between requests.

Key details:
• GET /v1/accounts: cursor paging uses limit and cursor; cannot be combined with page, sort, or perProfile. Response pagination is now one of: offset ({ page, limit, total, pages }) or cursor ({ limit, nextCursor }).
• GET /v1/accounts/follower-stats: new limit (max 25) and cursor; response may include pagination. Invalid cursors now return 400.
curl -G "https://api.zernio.com/v1/accounts" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "limit=100" \
  --data-urlencode "cursor=$NEXT_CURSOR"

Meta customer list audiences now support user removal

You can now remove emails/phones from Meta customer list audiences using the same plaintext user rows as uploads. Removals are applied asynchronously by Meta.

New feature#
DetailsHide details
You can now remove users from a Meta customer list audience with DELETE /v1/ads/audiences/{audienceId}/users.

Send the same users payload as uploads (plaintext email/phone rows); Zernio normalizes and SHA256-hashes server-side, and each row removes the person it previously added. Meta applies removals asynchronously.

Key details:
• Meta only, customer_list only (others return 422 with feature_not_available)
• Max 10000 users per request
• Response includes numReceived, numInvalid, and invalidEntrySamples
curl -X DELETE "$BASE_URL/v1/ads/audiences/$AUDIENCE_ID/users" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"users":[{"email":"a@example.com"},{"phone":"+14155550100"}]}'

Inbox review replies add 404 and 502 errors

Reply create/delete now distinguishes permanent missing reviews (404) from transient upstream failures (502), enabling safer retry logic and clearer error handling.

Improvement#
DetailsHide details
Review reply create/delete now return clearer failure modes with new 404 and 502 responses.

Use 404 to treat the review/reply as permanently unavailable (deleted or not addressable by the account) and avoid retries. Use 502 to detect upstream platform failures and retry safely with backoff.

Applies to:
• POST reply to review
• DELETE review reply
curl -X POST "$BASE/v1/inbox/reviews/$REVIEW_ID/reply" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{"accountId":"acc_123","message":"Thanks!"}'

WhatsApp conversions support more event types

You can now send QualifiedLead and order lifecycle events (created/canceled/returned) as WhatsApp conversion events to Meta, and they’ll appear in recent conversion logs.

New feature#
DetailsHide details
WhatsApp conversions now accept more Meta business messaging event types via eventName.

You can now send:
• QualifiedLead
• OrderCreated
• OrderCanceled
• OrderReturned

Use these in POST /v1/whatsapp/conversions (with accountId, eventId, and either conversationId or phoneE164). Recent events returned by GET /v1/whatsapp/conversions will also show these names.
curl -X POST "$BASE_URL/v1/whatsapp/conversions" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"accountId":"wa_123","eventName":"QualifiedLead","eventId":"lead_001","conversationId":"conv_abc"}'

Ads timeline rows now include currency

Ads timeline responses now return an ISO 4217 currency per row so you can handle multi-currency accounts without incorrectly summing money metrics across currencies.

Improvement#
DetailsHide details
Ads timeline rows now include currency in GET /v1/ads/timeline responses.

This lets you correctly chart money metrics when an account’s underlying ad accounts bill in different currencies (you may now receive one row per date and currency, never a sum across currencies).

Use rows[].currency (ISO 4217, or null if unknown) to interpret spend, cpc, cpm, costPerConversion, purchaseValue, and actionValues.
curl -G "https://api.zernio.com/v1/ads/timeline" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "accountId=acc_123" \
  --data-urlencode "fromDate=2026-10-01" \
  --data-urlencode "toDate=2026-10-23"

Inbox now returns enriched ad attribution

Inbox conversations and message.received webhooks now include enriched Meta ad attribution (campaign/ad set/ad account when available) plus extra WhatsApp CTWA creative metadata fields.

Improvement#
DetailsHide details
Inbox conversations now include enriched Meta ad attribution via adAttribution.

This lets you tie a conversation (and returning click referrals on inbound messages) back to the ad, and—when the ad is in your synced ads—also get campaign*, adSet*, and adAccount* fields.

New fields:
• GET /v1/inbox/conversations and GET /v1/inbox/conversations/{conversationId}: adAttribution
• message.received webhook: metadata.ad (enriched attribution for that message’s metadata.referral)

WhatsApp CTWA metadata now also includes creative details in metadata: ctwa_body, ctwa_media_type, ctwa_image_url, ctwa_video_url, ctwa_thumbnail_url.
curl -sS -H "Authorization: Bearer $ZERNIO_API_KEY" \
  "$ZERNIO_API_BASE/v1/inbox/conversations?platform=whatsapp&limit=10"
22 October

Webhooks add new ads lifecycle events

You can now subscribe to ad delivery issues, TikTok campaign budget depletion, and ad account status changes via webhooks, and generate sample payloads using the webhook test endpoint.

New feature#
DetailsHide details
Webhooks now support 3 new ads events: ad.delivery_issue, campaign.budget.depleted, and ad_account.status_changed.

Use them to get notified when tracked ads enter an error state, when a TikTok campaign stops delivering due to budget exhaustion, and when an ad account moves between active/restricted/disabled/closed.

Subscribe via events in POST /v1/webhooks/settings or PUT /v1/webhooks/settings, and you can generate sample payloads via POST /v1/webhooks/test using event.
curl -X POST "$BASE_URL/v1/webhooks/test" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"webhookId":"YOUR_WEBHOOK_ID","event":"ad.delivery_issue"}'

Google Ads search terms now include match source

Search terms rows now return matchSource so you can separate advertiser keyword matches from AI Max expansion matches.

Improvement#
DetailsHide details
Google Ads search terms reporting now includes matchSource on each row returned by GET /v1/ads/search-terms.

Use matchSource to tell what matched the query: ADVERTISER_PROVIDED_KEYWORD, AI_MAX_BROAD_MATCH, or AI_MAX_KEYWORDLESS.
curl -G "https://api.zernio.com/v1/ads/search-terms" \
  --data-urlencode "accountId=acc_123" \
  --data-urlencode "fromDate=2026-09-01" \
  --data-urlencode "toDate=2026-09-30"

Webhooks now support ad review outcome events

You can now subscribe to and test webhook deliveries for ad review outcomes via ad.review.approved and ad.review.rejected, with a dedicated payload schema for handling review details.

New feature#
DetailsHide details
Webhooks now emit ad review outcome events: ad.review.approved and ad.review.rejected.

Use these to track when an already-known ad’s platform review outcome changes (approved/rejected) across supported ad networks.

Subscribe by adding to events on webhook create/update, and you can generate sample payloads via POST /v1/webhooks/test using event.

New payload schema: WebhookPayloadAdReview.
curl -X POST "$ZERNIO_API/v1/webhooks/test" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"webhookId":"507f1f77bcf86cd799439011","event":"ad.review.rejected"}'

Commerce orders now include attribution data

Order responses now include attribution details like first/last visit, referrer, source, and UTM parameters (when available).

Improvement#
DetailsHide details
Commerce orders now include attribution data in orders[].attribution on order reads.

This lets you see where an order came from (e.g. source/referrer/UTM) and, on Shopify, the first and last visit before purchase.

Key fields:
• attribution.ready (Shopify may be false right after creation; re-read later)
• attribution.firstVisit (Shopify only) and attribution.lastVisit
• visit.landingUrl, visit.referrerUrl, visit.source, visit.sourceType, visit.utm
• attribution.customAttributes (Shopify cart/note attributes or WooCommerce public order meta)

TikTok Smart+ ad reviews can be fetched in bulk

You can now read review verdicts for all TikTok Smart+ ads of an advertiser in a paginated response, with built-in handling for TikTok’s Smart+ review quota.

New feature#
DetailsHide details
TikTok Smart+ ad reviews can now be fetched in bulk per advertiser with GET /v1/ads/tiktok-smart-plus-reviews.

This returns the review verdict for every Smart+ ad (and each creative) in a single paginated read, so you can refresh review status with one sweep per advertiser instead of calling the single-ad review endpoint per ad.

Use:
• accountId (TikTok / TikTok Ads connection)
• adAccountId (TikTok advertiser ID)
• Optional includeDeleted, page, pageSize

Quota handling: when TikTok’s Smart+ review quota is hit, the response stays 200 with incomplete=true, plus pendingSmartPlusAdIds and retryAfterSeconds (also in Retry-After). Re-read the same page after waiting to complete it.
curl -G "https://api.zernio.com/v1/ads/tiktok-smart-plus-reviews" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "accountId=acct_123" \
  --data-urlencode "adAccountId=789"

Inbox mentions now include Instagram

Inbox mentions can now return Instagram caption and comment mentions, including mediaId/commentId to support replying via the mentions reply endpoint.

New feature#
DetailsHide details
Inbox mentions now include Instagram in GET /v1/inbox/mentions (in addition to LinkedIn).

Instagram mentions can be type caption or comment, and include mediaId plus commentId (comment mentions only) so you can reply via POST /v1/inbox/mentions/reply.

Look for:
• platform: linkedin | instagram
• type: caption | comment | null
• mediaId, commentId
curl -sS -H "Authorization: Bearer $TOKEN" \
  "https://api.zernio.com/v1/inbox/mentions?limit=25&sortOrder=desc"

Instagram mention lookups by media or comment ID

You can now retrieve Instagram caption-mention posts and comment mentions by the ID Meta sends in mention notifications. Requires Instagram accounts connected via Facebook Login.

New feature#
DetailsHide details
Instagram now supports fetching @mention details by ID for both post captions and comments.

Use:
• GET /v1/accounts/{accountId}/instagram/mentions/media/{mediaId} to fetch a post whose caption mentions the connected account
• GET /v1/accounts/{accountId}/instagram/mentions/comments/{commentId} to fetch a comment mention (includes the parent media.id)

Key params:
• accountId (Instagram account connected via Facebook Login)
• mediaId / commentId (digits only)

Note: accounts connected with classic Instagram Login will get instagram_mentions_require_facebook_login and must be reconnected using Facebook Login.
curl -sS -H "Authorization: Bearer $ZERNIOTOKEN" \
  "https://api.zernio.com/v1/accounts/$ACCOUNT_ID/instagram/mentions/comments/17894227972186120"

Media can now be prepared per platform

You can now pre-process images and videos into platform-compliant versions and get back a publishable URL, using the same per-platform rules Zernio applies before publishing.

New feature#
DetailsHide details
Added media preparation via POST /v1/media/prepare to pre-process an image/video into the exact format a target platform accepts (the same processing Zernio applies before publishing).

Send url (public http(s) media URL) and target (instagram, instagram_story, facebook, facebook_reel, facebook_story, threads, tiktok, linkedin, twitter, bluesky, pinterest, reddit, snapchat, telegram, googlebusiness, youtube_thumbnail). Response includes changed, mediaType, originalSize, outputSize, and a publishable url.

Notes: synchronous processing; rate-limited to 60 files/hour per team (429 with retryAfterSeconds); videos over 200MB return 413.
curl -X POST "$ZERNIO_API/v1/media/prepare" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/clip.mov","target":"facebook_story"}'

Posts can now require approval before publishing

You can submit posts for approval, list them as pending_approval, and approve or reject them via a new review endpoint.

New feature#
DetailsHide details
Posts now support an approval workflow.

Create or update a post with requiresApproval: true to save it as status=pending_approval instead of scheduling/publishing immediately. The post will only publish after it’s reviewed.

Review a pending post via POST /v1/posts/{postId}/review with decision set to approve or reject.
• approve schedules the post for its scheduledFor (and fires the post.scheduled webhook)
• reject returns the post to draft

You can also filter/list these posts via GET /v1/posts using status=pending_approval.
curl -X POST "$BASE_URL/v1/posts/$POST_ID/review" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"decision":"approve"}'

Tracking tags can now be installed on Webflow sites

Connect a Webflow site and install or remove tracking tags with the existing install endpoints. Changes go live on the site's next publish.

New feature#
DetailsHide details
Webflow is now supported for tracking tag installs via the existing install endpoints.

You can connect a Webflow site using GET /v1/connect/webflow (returns authUrl + state), then install/remove tags by passing a Webflow site as storeAccountId.

Updates:
• StorePixelInstall.platform now includes webflow (in GET/POST/DELETE install responses)
• StorePixelInstall.publishRequired added (Webflow only; always true — changes go live on the site’s next publish)

Connection params for GET /v1/connect/webflow:
• profileId (required)
• redirect_url (optional)

Ad leads can now be updated with status and value

Update a lead's status and optionally its deal value and currency, tracking Meta and LinkedIn leads through to conversion.

New feature#
DetailsHide details
You can now update a lead’s status (and optionally deal value) via PATCH /v1/ads/leads/{id}.

This lets you track Meta leads from new → converted (or other outcomes) and store attribution value.

Request body:
• status: new | contacted | unreachable | qualified | converted | disqualified
• value (number, optional; requires currency)
• currency (ISO 4217, optional)
• accountId (required when {id} is a Meta leadgenId)

Lead responses now include tracking fields on GET /v1/ads/leads: status, statusChangedAt, value, currency, contactId, firstContactedAt.

GET /v1/ads/lead-forms/{formId}/leads now also returns leadId (Zernio lead id for the PATCH) and status when the lead is persisted.

When creating Meta lead forms, POST /v1/ads/lead-forms now supports platformSpecificData.customDisclaimer (consent checkboxes).

Nothing here breaks a working integration: endpoints are versioned in the path (/v1), a breaking change ships only as a new path version, and an operation is marked deprecated: true in the OpenAPI spec before it goes.

Was this page helpful?

Payment method required

What a 402 payment_required response means, which requests trigger it, and how the user adds a card without leaving the dashboard.

HubSpot, store orders and Wix blogs

Sync your inbox to HubSpot, read Shopify and WooCommerce orders in one format, publish to Wix, and four new Instagram endpoints.