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

Changelog

Every change to the Zernio API, newest first.


Every change is listed here. Changes that need action and major launches are posted right away on the Telegram channel and on X (@zerniodevs). The rest go out there in a daily digest at 17:00 UTC on weekdays.

Every entry is tagged with the platforms and areas it touches. Filter below by platform and type, and share the URL (for example /changelog?platform=whatsapp&type=breaking_change). The same filters work on the RSS feed (/changelog/feed.xml?platform=whatsapp) and on /changelog.json.

To automate on changes, subscribe a webhook to api.changelog.published: each entry arrives as it is published, with its tags and the diff of the OpenAPI spec behind it as data.

List API changelog entries returns the same entries, with a platform filter, for back-filling.

Nothing below breaks a working integration. Every endpoint is versioned in the URL path, currently /v1, and a breaking change ships only as a new path version: /v1 keeps working.

New endpoints, new response fields and new error codes arrive inside /v1 at any time, which is why error handling asks you to branch on code.

An operation on its way out is marked deprecated: true in the OpenAPI spec and announced here before it is removed.

RSS for this viewJSONWebhook

943 entries

October 24, 2026New feature
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.


``bash
curl -sS -H "Authorization: Bearer $TOKEN" \
"$BASE_URL/v1/inbox/mentions?limit=25"
``
October 24, 2026New feature
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)


``bash
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"}'
``
October 24, 2026Improvement
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.


``bash
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}'
``
October 24, 2026New feature
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.


``bash
curl -sS -H "Authorization: Bearer $ZERNI0_API_KEY" \
"https://api.zernio.com/v1/accounts/$ACCOUNT_ID/facebook-tagged-posts?limit=25"
``
October 23, 2026Improvement
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.


``bash
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"
``
October 23, 2026Improvement
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)


``bash
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"
``
October 23, 2026Improvement
TikTok Smart+ materials reporting now returns missingRows on successful responses from GET /v1/ads/tiktok-smart-plus-materials.

When TikTok declares more rows than could be retrieved (after an internal retry), Zernio may still return 200 with a small shortfall and set missingRows to the number of rows that could not be returned (otherwise missingRows=0).

Use missingRows to detect partial results and decide whether to retry or accept the data.


``bash
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"
``
October 23, 2026Breaking change
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)


``bash
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"]}'
``
October 23, 2026New feature
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.


``bash
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"}'
``
October 23, 2026Improvement
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).


``bash
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"]}'
``
October 23, 2026New feature
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.


``bash
curl -G "https://api.zernio.com/v1/connect/instagram" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "profileId=$PROFILE_ID" \
--data-urlencode "handoff=true"
``
October 23, 2026Improvement
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.


``bash
curl -G "https://api.zernio.com/v1/accounts" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "limit=100" \
--data-urlencode "cursor=$NEXT_CURSOR"
``
October 23, 2026New feature
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


``bash
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"}]}'
``
October 23, 2026Improvement
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


``bash
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!"}'
``
October 23, 2026New feature
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.


``bash
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"}'
``
October 23, 2026Improvement
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.


``bash
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"
``
October 23, 2026Improvement
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.


``bash
curl -sS -H "Authorization: Bearer $ZERNIO_API_KEY" \
"$ZERNIO_API_BASE/v1/inbox/conversations?platform=whatsapp&limit=10"
``
October 22, 2026New feature
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.


``bash
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"}'
``
October 22, 2026Improvement
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.


``bash
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"
``
October 22, 2026New feature
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.


``bash
curl -X POST "$ZERNIO_API/v1/webhooks/test" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"webhookId":"507f1f77bcf86cd799439011","event":"ad.review.rejected"}'
``
October 22, 2026Improvement
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)
October 22, 2026New feature
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.


``bash
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"
``
October 22, 2026New feature
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


``bash
curl -sS -H "Authorization: Bearer $TOKEN" \
"https://api.zernio.com/v1/inbox/mentions?limit=25&sortOrder=desc"
``
October 22, 2026New feature
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.


``bash
curl -sS -H "Authorization: Bearer $ZERNIOTOKEN" \
"https://api.zernio.com/v1/accounts/$ACCOUNT_ID/instagram/mentions/comments/17894227972186120"
``
October 22, 2026New feature
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.


``bash
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"}'
``
October 22, 2026New feature
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.


``bash
curl -X POST "$BASE_URL/v1/posts/$POST_ID/review" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"decision":"approve"}'
``
October 22, 2026New feature
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)
October 22, 2026New feature
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).
October 21, 2026Breaking change
install.siteUrl in tracking tag install/status/remove responses can now be null. Update your integration to handle a missing site URL.

These endpoints now also support Wix sites for install management.

Affected endpoints:
• GET /v1/accounts/{accountId}/tracking-tags/{tagId}/install
• POST /v1/accounts/{accountId}/tracking-tags/{tagId}/install
• DELETE /v1/accounts/{accountId}/tracking-tags/{tagId}/install

Changes:
• install.platform enum now includes wix
• install.siteUrl: string | null (Wix: null when the site was never published)
• storeAccountId now accepts connected Wix account ids (in query/body, depending on endpoint)
October 21, 2026New feature
Webflow is now supported for Blogs, including connecting a site via a site API token.

Connect a Webflow site with POST /v1/connect/webflow/token using profileId and siteToken.

Once connected, Webflow works in the Blogs API (platform=webflow):
• GET /v1/accounts/{accountId}/blogs returns each CMS collection that has a rich text field (collection id = blogId)
• Articles are supported via /articles (list/get/create/update/delete)

Webflow-specific behavior:
• No native scheduling: a future publishDate returns 400 (unless isPublished=false keeps a draft)
• seo is rejected on Webflow
• Create/update can include fieldData (Webflow only) to supply collection-specific fields by slug; unknown/unmappable required fields return 400

Also added webflow to the platform filter on GET /v1/accounts/health.
October 21, 2026New feature
New endpoint GET /v1/ads/{adId}/tiktok-smart-plus-review returns TikTok Smart+ ad review status per creative (Spark post/video/carousel), including rejection reasons.

Use adId (Zernio ad id or TikTok ad id). Response includes review (ad-level) and materials (per-creative), plus readAt.

reviewStatus is normalized to: approved, partially_approved, rejected, unknown (see rawReviewStatus). Each entry can include rejectReasons, passedLocations, and detailed rejections (with suggestion and rejected content).
October 21, 2026New feature
POST /v1/inbox/conversations/{conversationId}/messages now supports Instagram-only sends for sharing a published post and sending a sticker.

Use sharedMediaId to share one of the account’s own published Instagram posts by media id, or sticker to send a sticker instead of text.

New fields:
• sharedMediaId (Instagram only, JSON body only; numeric string like 17895695668004550)
• sticker (Instagram only, JSON body only; like_heart)

Both are sent on their own (can’t be combined with message, attachments, quickReplies, buttons, template, or each other).
October 21, 2026New feature
Instagram now supports listing the posts an account is tagged in via GET /v1/accounts/{accountId}/instagram/tags.

Returns tagged media newest-first and is cursor-paginated.

Key params:
• accountId (Instagram account connected via Facebook Login)
• limit (1-50, default 25)
• cursor (use the prior response’s nextCursor)

Response includes:
• data
• nextCursor (null when no more pages; the final page may be empty)

Note: accounts connected with classic Instagram Login will get 400 instagram_tagged_media_requires_facebook_login and must be reconnected using the Facebook option.
October 21, 2026New feature
Instagram now supports listing live broadcasts in progress for a connected account via GET /v1/accounts/{accountId}/instagram/live-media.

This returns the broadcasts that are live at request time (returns 200 with an empty data array when nothing is live), so you can pair the returned id with live-comment workflows.

Key details:
• Path param: accountId (Instagram account connected via Facebook Login)
• Response: { data: InstagramLiveMedia[] } where each item includes id, mediaType, mediaProductType, username, timestamp
• If the account was connected with classic Instagram Login, the endpoint returns 400 with code instagram_live_media_requires_facebook_login (reconnect using Facebook Login)

Also added: richer Meta error details in conversion failures via platformError in POST /v1/ads/conversions and POST /v1/whatsapp/conversions responses.
October 21, 2026New feature
Instagram now supports listing live broadcasts in progress for a connected account via GET /v1/accounts/{accountId}/instagram/live-media.

This returns the live videos the account is broadcasting right now; when nothing is live, you’ll get 200 with an empty data array (not an error).

Key details:
• Path param: accountId (Instagram account connected via Facebook Login)
• Response: { data: InstagramLiveMedia[] } with fields like id, mediaType, mediaProductType, username, timestamp
• Accounts connected with classic Instagram Login will get 400 instagram_live_media_requires_facebook_login and must be reconnected using Facebook Login.
October 21, 2026New feature
Connect now supports a workspace-saved welcome screen you can reuse across OAuth connect flows.

You can save branding once for the whole workspace, and (optionally) have it show by default on GET /v1/connect/{platform} calls that don’t explicitly pass welcome.

New endpoints:
• GET /v1/connect/welcome-screen – fetch saved settings
• PUT /v1/connect/welcome-screen – replace saved settings (omitted fields are cleared)

Saved settings include:
• showByDefault
• brandName
• logoUrl
• theme (same keys as welcomeTheme)

Connect behavior update:
• GET /v1/connect/{platform} welcome can now be omitted and still show the welcome screen if showByDefault=true
• Pass welcome=false to explicitly skip it (also skipped when headless=true or signup=hosted)
October 21, 2026New feature
Workflows now support a new node type: hubspot_upsert_contact in body.nodes[].type.

This node lets you create or update a contact in the connected HubSpot portal during a workflow run, and save the result into workflow variables.

Use type = hubspot_upsert_contact with config:
• email, phone, firstName, lastName
• properties (map of HubSpot internal property names → values, max 50)
• saveAs (defaults to hubspotContact)

Edges via sourceHandle:
• success
• error
October 20, 2026New feature
Google Ads ad accounts now support managing user access invitations (list, invite by email, and revoke).

List pending/declined/expired invites with GET /v1/ads/accounts/user-invitations using accountId (required) and optional adAccountId.

Send an invite with POST /v1/ads/accounts/user-invitations:
• accountId, adAccountId, emailAddress, accessRole, optional validateOnly
• accessRole: ADMIN | STANDARD | READ_ONLY | EMAIL_ONLY
• Response status: PENDING | PENDING_APPROVAL (multi-party approval)

Revoke an unaccepted invite with DELETE /v1/ads/accounts/user-invitations using accountId, adAccountId, invitationId.
October 20, 2026Improvement
Meta conversions now support Business Messaging events via actionSource = business_messaging and a new messaging object on POST /v1/ads/conversions events.

Use this to attribute conversions that happen in WhatsApp, Messenger, or Instagram Direct conversations.

Set events[].actionSource to business_messaging and include events[].messaging:
• channel: whatsapp | messenger | instagram_direct
• WhatsApp: wabaId, ctwaClid
• Messenger/Instagram Direct: pageId
• Messenger: pageScopedUserId
• Instagram Direct: instagramScopedUserId
October 20, 2026New feature
Instagram posts now support fetching collaborators via GET /v1/accounts/{accountId}/instagram/media/{mediaId}/collaborators.

Use it to list invited collaborator accounts on a published post and see whether each invite was accepted or is still pending.

Params:
• accountId (Instagram account connected via Facebook Login)
• mediaId (digits-only Instagram media ID)

Response items include id, username, inviteStatus (accepted | pending, other Meta values passed through lowercase). Meta returns up to 5 collaborators; no collaborators returns an empty list.

Note: accounts connected with classic Instagram Login will get instagram_collaborators_require_facebook_login and must be reconnected using Facebook Login.
October 20, 2026New feature
HubSpot is now supported as a CRM connection, including OAuth connect and per-portal sync settings.

Start the connect flow with GET /v1/connect/hubspot using profileId (optional redirect_url). The response returns authUrl and state.

Read/update what Zernio syncs to HubSpot via:
• GET /v1/accounts/{accountId}/hubspot-settings
• PATCH /v1/accounts/{accountId}/hubspot-settings with syncContacts and/or logMessages

HubSpot is also available in account listing/health filters:
• GET /v1/accounts category=crm
• GET /v1/accounts/health platform=hubspot
• platform enum now includes hubspot in relevant responses.
October 20, 2026Improvement
You can now filter GET /v1/inbox/conversations by SMS conversations using platform=sms.

This lets you include or isolate SMS threads when listing aggregated inbox conversations.

Set platform to one of: facebook, instagram, twitter, bluesky, reddit, telegram, whatsapp, imessage, sms.
October 20, 2026Improvement
Google Business Profile search keywords now support pagination and thresholded impression reporting in GET /v1/analytics/googlebusiness/search-keywords.

You can fetch up to 100 keywords per page and continue with pageToken when nextPageToken is returned.

New:
• Request param: pageToken
• Response field: nextPageToken
• Response field: keywords[].impressionsThreshold (when Google only reports “below threshold”, impressions will be 0 and impressionsThreshold will be set; otherwise it’s null)
October 20, 2026New feature
X posts now support tagging users on attached photos via mediaTaggedUsers in platformSpecificData.

Provide up to 10 X usernames (with or without @) to tag on photos (not video/GIF). Tags are applied to the media of every tweet in a thread; an unknown username will fail the post.

Use platformSpecificData.mediaTaggedUsers (max 10, pattern ^@?\w{1,15}$).
October 20, 2026Improvement
GET /v1/posts now supports cursor pagination and field selection.

Use cursor to page through long histories efficiently (constant cost per page vs deep page/offset), and use fields to return only the post fields you need to reduce response size.

New options:
• cursor — pass pagination.nextCursor from the previous response (takes precedence over page/offset; must use same filters + sortBy; not available with sortBy=status or sortBy=platform, or with source=external)
• fields — comma-separated fields to return (always includes _id; fields=_id returns ids only; unknown field returns 400; not available with source=external)

Response addition:
• pagination.nextCursor — string or null (null on last page; always null for sortBy=status/sortBy=platform; absent for source=external)
October 20, 2026Improvement
GET /v1/ads now returns Google Display image asset resource names in ads[].creative.assets.

This lets you see the native Google asset resourceName for each image role on a responsive display ad (useful for auditing what’s currently attached after creative updates).

New fields:
• ads[].creative.assets.marketingImages[].resourceName (landscape; first item matches creative.assetResourceName)
• ads[].creative.assets.squareMarketingImages[].resourceName (square)

Only applies to Google Display ads; absent for other platforms and for ads synced from Google.
October 20, 2026Improvement
SMS carrier registration endpoints may now return 403 when the caller is a team member limited to specific profiles (registrations are account-wide).

If you use restricted team-member tokens, make sure your integration handles 403 on:
• GET /v1/sms/registrations
• POST /v1/sms/registrations
• GET /v1/sms/registrations/{id}
• DELETE /v1/sms/registrations/{id}
• POST /v1/sms/registrations/{id}/verify-otp
• POST /v1/sms/registrations/{id}/resend-otp
• POST /v1/sms/registrations/{id}/appeal
• POST /v1/sms/registrations/{id}/respond
October 20, 2026Improvement
Organic Reddit endpoints may now return 503 with PLATFORM_DISABLED.

Reddit has blocked third-party apps from its API, so these endpoints are temporarily unavailable and will return 503 until Reddit restores access (Reddit Ads is not affected).

Handle 503 (PLATFORM_DISABLED) for:
• GET /v1/tools/validate/subreddit
• GET /v1/reddit/search
• GET /v1/reddit/feed
• GET /v1/reddit/comments/{postId}
• GET /v1/accounts/{accountId}/reddit-subreddits
• PUT /v1/accounts/{accountId}/reddit-subreddits
• GET /v1/accounts/{accountId}/reddit-subreddits/{subreddit}/rules
• POST /v1/accounts/{accountId}/reddit-vote
• GET /v1/accounts/{accountId}/reddit-flairs
• POST /v1/accounts/{accountId}/reddit-flairs
October 20, 2026Improvement
GET /v1/ads/accounts now returns accounts[].selected.

selected tells you whether each ad account is in the connection’s ad-account selection (the ones Zernio syncs). If a connection has no selection, every account returns selected: true.

Use accounts[].selected to decide which ad accounts are eligible for writes; writes to an ad account with selected: false will be restricted and return 403 ad_account_not_selected until it’s added to the selection.
October 20, 2026New feature
Wix is now supported as a blog platform in the Blogs API, and you can start the Wix install/connect flow via a new endpoint.

Use GET /v1/connect/wix to get the Wix installer URL.
Required: profileId
Optional: redirect_url
Returns: authUrl, state

After connecting, Wix accounts work with:
• GET /v1/accounts/{accountId}/blogs (now supports platform=wix)
• /v1/accounts/{accountId}/blogs/{blogId}/articles CRUD (now supports platform=wix)

Notes for Wix:
• Wix is connect-only for Blogs (no social posts/inbox/analytics/ads)
• Wix list-articles returns bodyHtml: null; fetch the article to get the body

Also added wix to platform enums in places like GET /v1/accounts/health (query platform) and account objects (platform).
October 19, 2026New feature
Commerce now supports Orders: you can list and fetch store orders, and subscribe to order webhooks.

New endpoints (requires orders.read; store capability orders.read):
• GET /v1/commerce/orders with accountId, optional limit, cursor, createdAfter, createdBefore, updatedAfter
• GET /v1/commerce/orders/{orderId} with accountId

New webhook events (available in POST/PUT /v1/webhooks/settings and POST /v1/webhooks/test): commerce.order.created, commerce.order.updated, commerce.order.refunded.

Order webhook payloads use WebhookPayloadCommerceOrder and include identifiers only; read full order details via GET /v1/commerce/orders/{orderId}.
October 19, 2026New feature
Added GET /v1/analytics/linkedin/demographics to fetch LinkedIn organization follower demographics (lifetime breakdown by job function, seniority, industry, and company size).

Query params:
• accountId (required) - LinkedIn organization SocialAccount ID
• breakdown - comma-separated: function, seniority, industry, company_size (defaults to all)

Response includes metric=follower_demographics and a demographics object with arrays of {dimension, id, value} (sorted by value desc).

Notes: organization accounts only (personal returns 400 personal_account_not_supported). Requires LinkedIn scopes r_organization_social, r_organization_followers, r_organization_admin (412 linkedin_org_analytics_scope_missing otherwise) and the Analytics add-on (402 analytics_addon_required).
October 19, 2026Improvement
WhatsApp business username endpoints now return 403 when Meta hasn’t granted username management permissions for the WhatsApp Business Account.

This makes permission issues explicit via the standard error envelope with code insufficient_permissions.

Applies to:
• GET /v1/whatsapp/business-profile/username
• POST /v1/whatsapp/business-profile/username
• DELETE /v1/whatsapp/business-profile/username

Handle 403 + insufficient_permissions separately from 401 (auth) and 404 (account not found).
October 19, 2026New feature
PUT /v1/ads/ad-sets/{adSetId} now supports updating Meta ad set placements and targeting.

Use placements to replace the full manual placement set (or send null to return to automatic placements). Use targeting (Meta TargetingSpec) to update specific targeting keys; Zernio reads live targeting, merges only the keys you send, and writes the full spec back.

New request fields (Meta only; other platforms return 400):
• placements (object | null)
• targeting (object)

New response behavior:
• 200.targeting is returned when placements or targeting was sent (full Meta targeting as written, snake_case)
• 502 is returned if Meta live targeting can’t be read, and the placements/targeting update is not written
October 19, 2026Improvement
GET /v1/ads/targeting/search now supports dimension=interestSuggestion (Meta only).

This lets you fetch Meta interest suggestions related to the interest names you provide in q, returning interest ids you can use in TargetingSpec.interests.

Use:
• dimension: interestSuggestion
• q: comma-separated interest names (e.g. NBA,Michael Jordan) or a JSON array of strings when a name contains a comma (e.g. ["Earth, Wind & Fire","Yoga"], URL-encoded)
October 19, 2026Improvement
rateLimitedUntil is now returned on accounts in GET /v1/analytics and GET /v1/accounts/follower-stats.

This exposes the end time of an account’s publishing cooldown so you can avoid scheduling/retrying publishes that would be rejected during the cooldown window.

New field: accounts[].rateLimitedUntil (date-time | null)
October 18, 2026New feature
Workflows now support TikTok as a platform.

You can create or move a workflow onto TikTok by setting platform (create) or using accountId reassignment (update) for a TikTok social account.

Updated platform enum includes: whatsapp, instagram, facebook, telegram, twitter, bluesky, reddit, tiktok.
October 17, 2026Improvement
GET /v1/ads now returns ads[].creative.assetResourceName for Google Display ads.

This exposes the Google resource name of the landscape marketing image asset behind creative.imageUrl, making it easier to track which asset an ad is currently pointing at after creative updates.

New field:
• creative.assetResourceName (Google Display only)
October 17, 2026Improvement
POST /v1/ads/videos now lets you set the video’s name in Meta’s Ads Manager media library.

Use name (takes precedence) or filename (now maxLength: 255) to control how the uploaded video is titled/searchable.

New optional fields:
• name
• filename (max 255 chars)
October 16, 2026New feature
Meta catalog template ads can now be configured with an explicit format via catalogFormat on POST /v1/ads/create.

This lets you control the template creative layout Meta uses for catalog ads (goal catalog_sales, or traffic with promotedObject.productSetId, or attach via adSetId + promotedObject.productSetId).

Set catalogFormat to:
• single_image
• carousel_images_multi_items
• carousel_images_single_item
• carousel_slideshows

Also added to GET /v1/ads responses:
• ads[].creative.creativeFeatures (Meta-only; echoed when created via Zernio)
• ads[].creative.catalog (Meta-only; catalog template details when created via Zernio)
October 16, 2026Improvement
OAuth connect URLs now support an optional branded welcome screen before sending users to the platform’s authorization dialog.

Enable it with welcome=true on GET /v1/connect/{platform}. You can optionally customize the screen via brandName, logoUrl, primaryColor, and welcomeTheme (URL-encoded JSON).

Notes:
• welcome=true cannot be combined with headless=true or signup=hosted

Activity logs now support better filtering and correlation.

On GET /v1/logs:
• New filter: profileId
• New fields in 200.logs[]: profile_id, operation_id
October 16, 2026Improvement
GET /v1/inbox/comments/{postId} now returns 200.meta.postUrn for LinkedIn.

This exposes the exact LinkedIn post URN that was queried (after resolving postId), which helps when you pass a bare number and it’s interpreted as urn:li:activity:<n>.

New field:
• meta.postUrn (LinkedIn only) — the resolved post URN used for the request
October 16, 2026Improvement
POST /v1/posts/{postId}/update-metadata now returns 429 when YouTube rate-limits thumbnail uploads (uploadRateLimitExceeded).

This can happen when updating thumbnailUrl; handle 429 by retrying later (not immediately) to avoid staying over the channel limit.

Key behavior:
• Thumbnail updates via thumbnailUrl may return 429
• Other temporary failures still return 500 (retryable)
October 15, 2026Improvement
Error responses for POST /v1/inbox/conversations/{conversationId}/messages now include additional platform diagnostics when the send is rejected by the platform.

On 400 responses with type=platform_error and code=platform_api_error, platformError may now include:
• platformError.message (TikTok error message)
• platformError.request_id (TikTok request id for support tickets)

Existing integrations continue to work; these fields are optional and can be logged for troubleshooting.
October 15, 2026New feature
You can now delete an inbox conversation from Zernio storage via DELETE /v1/inbox/conversations/{conversationId}.

This permanently removes Zernio’s stored copy of the conversation and its messages (the thread is not deleted on WhatsApp/Messenger/Instagram), and unlinks the contact channel; the contact record remains.

Call with:
• conversationId (path)
• accountId (query)

Success response includes data.id, data.accountId, data.platform, data.deletedMessages.
October 15, 2026Improvement
Instagram account selection now may include follower counts in the response from GET /v1/connect/instagram/select-account.

When Meta returns it, you’ll receive 200.pages[].instagram_business_account.followers_count (integer), which you can use to show richer account details during the Page/IG account picker step.
October 15, 2026Improvement
GET /v1/ads/accounts now supports inScopeOnly (Google Ads only).

When inScopeOnly=true, the response includes only Google Ads customers that this connection will accept as adAccountId/customerId on other /v1/ads endpoints (i.e. inside its ad-account selection). Without it, the list may include customers reachable by the Google login but not usable on this connection.

Use: inScopeOnly=true (default: false). Ignored on non-Google platforms.
October 14, 2026Improvement
GET /v1/ads/{adId} now returns darkPost when {adId} is a Facebook placement dark post that can’t be mapped to a single ad.

This lets you detect the “dark post with no resolvable ad” case and still proceed with comment moderation by using the same id with the ad comments endpoint.

In this case the response is ad: null plus darkPost with key fields like darkPost.platform (facebook), darkPost.platformPostId, darkPost.pageId, darkPost.platformAdAccountIds, darkPost.firstSeenAt, darkPost.lastActivityAt.
October 14, 2026Improvement
Instagram Business Discovery now returns richer media details in GET /v1/accounts/{accountId}/instagram/business-discovery.

You can now retrieve temporary CDN URLs and extra metadata for each returned media item (useful for previews, downloading assets, and handling carousels).

New fields on 200.media[]:
• mediaUrl (temporary; may be null e.g. some licensed-music videos)
• thumbnailUrl (VIDEO cover frame)
• viewCount (Reels only)
• children (carousel slides; null unless mediaType is CAROUSEL_ALBUM)

Note: media URLs are temporary, and fields Meta doesn’t return come back as null (not omitted).
October 14, 2026Improvement
Ads analytics breakdowns now return extra metadata to help you handle unsupported/partial breakdown results on Meta/TikTok/LinkedIn.

On GET /v1/ads/campaigns/{campaignId}/analytics and GET /v1/ads/{adId}/analytics, the response may now include:
• analytics.unsupportedBreakdowns - requested breakdowns the platform can’t provide
• analytics.breakdownHints - suggested alternatives for unsupported breakdowns
• analytics.breakdownErrors - TikTok breakdowns that failed, while the response stays 200
• analytics.breakdownDroppedMetrics - TikTok metrics refused for a breakdown (derived row values become null)
• analytics.breakdownsRange - TikTok-only window used when your requested range exceeds 365 days (summary/daily still cover the full range)

Unknown breakdown names still return 400.
October 14, 2026Improvement
Responses from GET /v1/ads now include profileId on each ad (200.ads[].profileId).

Use profileId to attribute each ad to the owning profile (especially in multi-profile setups), even when accountId/connections change over time.
October 13, 2026Improvement
POST /v1/whatsapp/phone-numbers/kyc and POST /v1/whatsapp/phone-numbers/{id}/remediate now include a 503 TemporarilyUnavailable response.

This indicates the service may be temporarily unable to process KYC submissions/remediations; clients should treat it as transient and retry with backoff.

New response:
• 503 - TemporarilyUnavailable
October 13, 2026Improvement
GET /v1/analytics now supports filtering by post tags via a new optional query parameter tags.

Use tags to request analytics only for posts created through Zernio that contain every listed tag (exact, case-sensitive match). This filter is ignored when postId is set.

Key details:
• tags: comma-separated list (max 20)
• If more than 200 published posts match within the date range, the API returns 400 asking you to narrow fromDate/toDate
October 13, 2026Improvement
GET /v1/inbox/comments now documents a 400 BadRequest response for invalid requests.

This can occur when using accountId with platform=metaads and the accountId is not a Meta Ads account ID, or a Facebook/Instagram account ID tied to a Meta Ads connection (non-Meta platforms return 400).

If you validate inputs client-side, ensure platform=metaads is only paired with supported accountId values, and handle 400 alongside 401/403 in your error handling.
October 13, 2026Improvement
TikTok campaigns and ad groups now include an isSmartPlus flag in ads listing/tree responses.

Use this to detect Upgraded Smart+ objects and adjust your UI/automation (some edits may be restricted on Smart+).

New fields:
• GET /v1/ads/campaigns → campaigns[].isSmartPlus
• GET /v1/ads/tree → campaigns[].isSmartPlus
• GET /v1/ads/tree → campaigns[].adSets[].isSmartPlus
October 13, 2026Improvement
Meta carousel ads now support controlling card order via optimizeCardOrder on create endpoints.

By default Meta may reorder carousel cards for performance. Set optimizeCardOrder: false to keep the order you send.

Available on:
• POST /v1/ads/create
• POST /v1/ads/creatives
• POST /v1/ads/messaging
• POST /v1/ads/call
• POST /v1/ads/ctwa

Rules:
• Only valid when carouselCards is present (otherwise 400)
• optimizeCardOrder: false limits Meta to max 5 cards (so >5 cards with false is a 400)
• Omit the field to use Meta’s default (true)
October 12, 2026Improvement
You can now delete X (twitter) campaigns via DELETE /v1/ads/campaigns/{campaignId}.

For EMPTY campaigns (zero ads), you can pass accountId either in the JSON body or on the query string, and on X you may also need adAccountId (when the campaign was never synced).

New options:
• platform now supports twitter
• adAccountId (X only) added for deleting an empty, never-synced campaign

Also, POST /v1/ads/boost adds lifetimeBudgetCap (X only): set a lifetime total cap (whole currency units) while using budgetType=daily.
October 12, 2026Improvement
Facebook comment webhooks now include comment.ad.isDarkPost in WebhookPayloadComment.

This lets you tell whether a comment came from an unpublished ad creative (dark post) vs a boosted organic post when comment.ad is present.

New field:
• comment.ad.isDarkPost (boolean) — true = dark post, false = boosted organic post
October 12, 2026Improvement
Support thread run listings now include the original question via question on each run returned by GET /v1/support/runs.

This lets you render a full Q&A history (question + answer) when paging through a thread.

New field: runs[].question (string | null).
October 12, 2026Improvement
Webhook payloads now include profile routing info via a new profiles field.

When present, profiles lists the profile(s) the event belongs to, including the externalId you set on the profile (or null if none). This helps route events to the right tenant without storing Zernio profile IDs.

New field:
• profiles: [{ id: string, externalId: string|null }]

Added to many webhook payloads, including:
• WebhookPayloadPost, WebhookPayloadPostPlatform
• WebhookPayloadAccountConnected, WebhookPayloadAccountDisconnected
• WebhookPayloadMessage*, WebhookPayloadConversation*
• WebhookPayloadComment, WebhookPayloadLead, WebhookPayloadReview*
October 12, 2026New feature
Added GET /v1/support/runs to list a support thread’s runs (Ana’s answers), returned oldest-first.

Use it to page through long threads and retrieve runs kept for 90 days.

Key params:
• threadId (required)
• limit (1–50, default 20)
• cursor (pass prior nextCursor)

Response includes runs and nextCursor (null when there are no more pages).
October 12, 2026Improvement
Profiles now support external IDs so you can map a Zernio profile to your own tenant/client identifier and look it up later.

You can:
• Set externalId when creating a profile via POST /v1/profiles
• Update/clear it via PUT /v1/profiles/{profileId} (set externalId to null to clear)
• Filter profiles by it via GET /v1/profiles?externalId=...

If externalId is already used by another profile of the same owner, you’ll get 409 with code profile_external_id_conflict (and details.existingProfileId).
October 12, 2026Improvement
Meta (Facebook/Instagram) ads are now supported in GET /v1/ads/{adId}/review.

You can now read Meta’s live review status and feedback for an ad, including placement-specific rejections, without re-enabling a paused ad.

New Meta-only fields in 200.review:
• reviewFeedback (from ad_review_feedback): global and placementSpecific
• issues (from issues_info)

Meta uses reviewStatus = effective_status (e.g. ACTIVE, PAUSED, PENDING_REVIEW, DISAPPROVED, PREAPPROVED, WITH_ISSUES, IN_PROCESS, ...). Placement-level feedback is reflected in rejections and forbiddenPlacements.

The endpoint may now return 429 (RateLimited).
October 12, 2026Improvement
POST /v1/inbox/comments/{postId}/{commentId}/private-reply now returns 502 when Meta errors after receiving the reply and delivery can’t be confirmed.

The 502 response indicates the private reply outcome is unknown (it’s usually delivered), so avoid blind retries and check the conversation first.

On 502, the error payload includes details.privateReplyOutcome = "unknown".
October 12, 2026Improvement
YouTube analytics endpoints now include an explicit 429 RateLimited response.

This makes rate limiting behavior easier to detect and handle when calling these endpoints:
• GET /v1/analytics/youtube/daily-views
• GET /v1/analytics/youtube/video-retention

If you see 429, back off and retry according to the RateLimited response.
October 10, 2026Improvement
Account health responses now include analytics sync status via analyticsSync.

This lets you detect failing/stalled analytics syncs; a failing or stalled sync can raise an otherwise healthy account to at least warning.

New fields:
• GET /v1/accounts/health → accounts[].analyticsSync
• GET /v1/accounts/{accountId}/health → analyticsSync

analyticsSync.status is one of: ok, failing, stalled, never_synced

analyticsSync.lastSyncedAt is the last successful sync time (or null if never synced / latest attempt failed).
October 10, 2026New feature
GET /v1/ads/targeting/search now supports TikTok lookups for Additional Interests and Hashtags.

Use dimension to fetch targetable TikTok options beyond standard interest/behavior:
• dimension=interestKeyword
• dimension=hashtag

Responses may now include results[].status for these TikTok dimensions (e.g. EFFECTIVE/INEFFECTIVE for interestKeyword, ONLINE/OFFLINE for hashtag) so you can filter to targetable ids.
October 9, 2026Improvement
GET /v1/changelog now includes an impact filter, and each changelog entry now returns an impact value.

Use impact to fetch only entries that match a specific integration impact:
• none
• additive
• action_required

In the response, entries[].impact indicates the computed impact (may be null for older entries). Operation refs in entries[].changes.endpoints.*[] also include tags and xPlatforms for easier routing/grouping.
October 9, 2026Improvement
GET /v1/inbox/comments/{postId} now includes post metadata for Facebook and Instagram (in addition to Reddit).

This lets you render a preview of the post being commented on (text, permalink, thumbnail/media) without an extra API call.

post can now be:
• Reddit post shape (unchanged)
• Facebook/Instagram post shape with key fields: id, permalink, text, thumbnailUrl, mediaUrl, mediaType, productType, createdAt

Instagram productType values: AD, FEED, REELS, STORY.
October 9, 2026New feature
New endpoint GET /v1/ads/targeting/browse to browse Meta detailed-targeting categories as a flat list you can render as a tree.

Use it to display available targeting options without keywords; combine with GET /v1/ads/targeting/search for open-ended categories and name-based lookup.

Required query params:
• accountId (connected Meta account)
• adAccountId (format act_<digits>)

Optional filters:
• type (e.g. interests, behaviors, income, life_events, education_statuses, relationship_statuses)
• parentNodeId (return descendants of an organizational node)
• selectable (true selectable entities only, false organizational nodes only)

Response returns nodes[] with nodeId, parentNodeId, id (Meta targeting id or null), type, path, selectable, plus optional audience size bounds. No pagination (catalog is returned in one response).
October 9, 2026Breaking change
GET /v1/connect/{platform}/ads now returns 409 reconnect_required in a specific case: when you call with force=true and accountId points to the posting account the ads connection depends on, but that posting account is no longer connected.

This prevents the API from reconnecting a different posting account implicitly; you must reconnect the posting account first.

Key params:
• force=true
• accountId=<posting SocialAccount ID>

Updated 409 cases include:
• ambiguous_account
• reconnect_required
October 9, 2026New feature
POST /v1/webhooks/test now supports sending a sample payload for a specific webhook event (not just webhook.test).

This lets you exercise handlers for events that are hard to trigger in real life (e.g. outages/lifecycle events). Samples are delivered like real webhooks (same headers) but include test: true and placeholder ids (never your data), and they appear in webhook logs.

Use:
• webhookId (required)
• event (optional) — one of: post.scheduled, post.published, post.failed, post.partial, post.cancelled, post.recycled, post.platform.published, post.platform.failed, post.platform.deleted, post.tiktok.url_resolved, post.external.created, post.external.updated, post.external.deleted, account.connected, account.disconnected, account.ads.initial_sync_completed, account.ads.sync_failed, account.ads.sync_recovered, analytics.synced, message.received, message.sent, message.edited, message.deleted, message.delivered, message.read, message.played, message.failed, reaction.received, referral.received, conversation.started, conversation.control_changed, contact.tag_added, contact.tag_removed, contact.field_changed, sequence.enrolled, sequence.exited, workflow.run.started, workflow.run.completed, workflow.run.failed, support.run.completed, support.run.failed, call.received, call.ended, call.failed, call.permission_request, comment.received, review.new, review.updated, ad.status_changed, ad.video.processed, lead.received, whatsapp.template.status_updated, whatsapp.template.category_updated, whatsapp.account.name_status_updated, whatsapp.account.quality_updated, whatsapp.account.status_updated, whatsapp.account.alert_received, whatsapp.contact.identity_changed, whatsapp.number.activated, whatsapp.number.declined, whatsapp.number.action_required, whatsapp.automatic_event, whatsapp.number.verification_required, whatsapp.number.suspended, whatsapp.number.reactivated, whatsapp.number.released, whatsapp.number.kyc_submitted, phone_number.stock_available, sms.registration.action_required, sms.registration.status_updated, branded_calling.identity.status_updated, branded_calling.identity.action_required, branded_calling.number.status_updated, rcs.agent.status_updated, verification.approved, verification.failed, commerce.product.created, commerce.product.updated, commerce.product.deleted, api.changelog.published

Note: invalid event now returns 400 (omit event to send webhook.test).
October 9, 2026Improvement
POST /v1/ads/boost now supports using an X Ads connection as accountId.

For X, accountId can be either the posting X account or its X Ads connection; Zernio will resolve the other from the same profile.

If you send a Zernio postId while using an X Ads connection, it resolves via the profile’s linked X account. If the profile has no linked X account, the request returns 400 and you must use platformPostId instead.
October 8, 2026Improvement
Post targets now include publishing attempt/retry counters in PlatformTarget responses.

This helps you debug why a target is still processing/failed and distinguish pipeline re-claims vs platform-level re-sends (Instagram).

New fields:
• publishAttempts (integer) — number of times the pipeline claimed the target to publish since creation/last manual retry
• publishRetries (integer) — Instagram only, automatic re-sends of media_publish on the same container after transient errors (absent when none was scheduled)
October 8, 2026Improvement
Several phone-number endpoints may now return 403 when the API key is scoped to profiles that don’t include the target number.

This makes authorization failures explicit (instead of only 401/404), so clients should handle 403 as “not permitted for this number/profile scope”.

New/updated response:
• 403 - The API key is scoped to profiles that do not include this number.

Applies to remediation and messaging flows (e.g. /v1/phone-numbers/{id}/remediate, /remediate/reply, /remediate/respond), voice (/voice), SMS (/sms, /sms/reuse-registration), SIP trunk attach/detach (/sip-trunk), WhatsApp verification (/whatsapp/request-code) and caller-id verification endpoints, plus deprecated WhatsApp alias paths.
October 8, 2026Improvement
Some phone-number reads can now return 403 Forbidden when the API key is scoped to profiles that don’t include the requested number.

This makes the “not allowed for this key” case explicit (instead of only 401/404), so clients should handle 403 separately from “not found”.

Applies to:
• GET /v1/phone-numbers/{id} → 403
• GET /v1/phone-numbers/{id}/whatsapp/calling → 403
October 8, 2026New feature
TikTok ad metrics now include additional video retention fields in AdMetrics: video2SecWatchedActions, video6SecWatchedActions, video6SecFocusedViews.

These let you compute hook/hold-style video performance directly from API responses (TikTok only).

New fields:
• video2SecWatchedActions - plays ≥ 2s (replays excluded)
• video6SecWatchedActions - plays ≥ 6s (replays excluded)
• video6SecFocusedViews - TikTok “engaged_view” (≥ 6s or interaction in first 6s)

Backfill note: these were added in 2026-10 and sync re-fetches only the last 7 days, so older days may read 0 until the ad is re-synced from scratch.
October 8, 2026Improvement
TikTok ads now return richer conversion metrics in AdMetrics.

You can now read TikTok website + app funnel events and (when provided by the advertiser) per-event values, enabling more complete TikTok ROAS and funnel reporting.

Key updates:
• AdMetrics.actions now includes TikTok website (pixel) events: complete_payment, initiate_checkout, add_to_cart, view_content, lead (plus existing app events like purchase)
• AdMetrics.actionValues now supports TikTok (values only present when the event includes a value)
• AdMetrics.purchaseValue for TikTok now includes app purchase value + website complete_payment value (from 2026-10-08)
• AdMetrics.funnel now populates for TikTok (from 2026-10-08): contentViews, cartAdds, checkoutsInitiated, purchases, leads

Note: TikTok history/backfill—these website event counts/values were missing before 2026-10-08, and each sync re-fetches only the last 7 days, so older days may remain absent until a full re-sync.
October 8, 2026Improvement
Instagram Login connections now support forcing a fresh login via GET /v1/connect/instagram.

Use this to prevent Instagram from silently using whatever account is currently logged in on the device (common when users manage multiple IG accounts on one phone).

New parameter:
• forceReauth=true | false (default false) — Instagram Login only (loginMethod=instagram_login); ignored for other platforms.

Tip: pair forceReauth=true with expectedUsername to also reject a wrong account at the end of the flow.
October 8, 2026Improvement
Facebook/Instagram connect selection endpoints now support sending the OAuth user token via X-Temp-Token (header) instead of tempToken in the query/body.

This lets you avoid putting access tokens in URLs (which often end up in logs) and also supports the Zernio-hosted picker flow via connectFlow.

Changes:
• GET /v1/connect/facebook/select-page: tempToken can be omitted if you send X-Temp-Token; new connectFlow (query)
• POST /v1/connect/facebook/select-page: classic flow tempToken is now optional if using X-Temp-Token; new connectFlow (body)
• GET /v1/connect/instagram/select-account: tempToken can be omitted if you send X-Temp-Token; new connectFlow (query)
• POST /v1/connect/instagram/select-account: tempToken is now optional if using X-Temp-Token; new connectFlow (body)

If you currently pass tempToken in the query string, prefer X-Temp-Token going forward.
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.

Refer & earn

Earn 20% recurring commission for 12 months when you refer new customers to Zernio.