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
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.
DetailsHide details
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 tagApplies 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.
DetailsHide details
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"}]}'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.
DetailsHide details
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.
DetailsHide details
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 actionWebhooks: 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.
DetailsHide details
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 boardOwnerUsernameAbsent 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.
DetailsHide details
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.
DetailsHide details
Use:
•
GET /v1/inbox/labels to list labels•
POST /v1/inbox/labels to create a label•
DELETE /v1/inbox/labels/{labelId} to delete a labelKey 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"}'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.
DetailsHide details
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.
DetailsHide details
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.
DetailsHide details
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.
DetailsHide details
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.
DetailsHide details
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 paginationResponse 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.
DetailsHide details
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.
DetailsHide details
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.
DetailsHide details
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_unavailableNote:
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.
DetailsHide details
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"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.
DetailsHide details
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.
DetailsHide details
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.
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).
DetailsHide details
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.
DetailsHide details
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.
DetailsHide details
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.
DetailsHide details
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.
DetailsHide details
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 invalidEntrySamplescurl -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.
DetailsHide details
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 replycurl -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.
DetailsHide details
eventName.You can now send:
•
QualifiedLead•
OrderCreated•
OrderCanceled•
OrderReturnedUse 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.
DetailsHide details
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.
DetailsHide details
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"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.
DetailsHide details
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.
DetailsHide details
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.
DetailsHide details
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).
DetailsHide details
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.
DetailsHide details
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, pageSizeQuota 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.
DetailsHide details
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, commentIdcurl -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.
DetailsHide details
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.
DetailsHide details
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.
DetailsHide details
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 draftYou 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.
DetailsHide details
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.
DetailsHide details
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.
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.