WhatsApp is now supported on
On WhatsApp, the typing indicator shows typing... for up to 25 seconds. It requires a recent inbound message in the conversation (Meta references the inbound message id) and will also mark that inbound message as read as a side-effect.
Use:
View documentation
POST /v1/inbox/conversations/{conversationId}/typing.On WhatsApp, the typing indicator shows typing... for up to 25 seconds. It requires a recent inbound message in the conversation (Meta references the inbound message id) and will also mark that inbound message as read as a side-effect.
Use:
{ "accountId": "..." }View documentation
🔥1
X API pricing/usage reporting now includes a new $0.200 “posts with URL” operation and tier.
This lets you attribute X spend more accurately per action; new clients should rely on per-operation counts rather than tier aggregates.
Key changes:
• New operation in
•
• In
View documentation
This lets you attribute X spend more accurately per action; new clients should rely on per-operation counts rather than tier aggregates.
Key changes:
• New operation in
GET /v1/billing/x-pricing: operation=content_create_with_url with tier=x_api_200 and pricePerCallUsd=0.2•
content_create price moved to pricePerCallUsd=0.015 (now tier=x_api_015)• In
GET /v1/usage-stats, usage.xApiCalls is now deprecated and excludes x_api_200 (and future tiers); use usage.xApiCallsByOperation as the source of truthView documentation
🔥1
Comment-to-DM automations now support inline DM buttons via
You can attach up to 3 buttons to the auto-DM (URL, postback, or phone on Facebook) to drive clicks or capture postbacks.
Use
•
•
Button schema:
Note: when
View documentation
buttons.You can attach up to 3 buttons to the auto-DM (URL, postback, or phone on Facebook) to drive clicks or capture postbacks.
Use
buttons in:•
POST /v1/comment-automations•
PATCH /v1/comment-automations/{automationId} (pass buttons: [] to clear)Button schema:
{ type, title, url|payload|phone } where type is url | postback | phone (phone = Facebook-only), and title is max 20 chars.Note: when
buttons is non-empty, dmMessage must be ≤ 640 characters. Responses from list/get/create/update may now include buttons (omitted when none are set).View documentation
❤1
Meta Ads now supports managing Tracking Tags (Meta Pixels) via new endpoints.
You can list/create/get/update pixels, share/unshare them across ad accounts, and fetch aggregated event stats.
New endpoints:
•
•
•
•
•
•
Notes: Meta-only (
View documentation
You can list/create/get/update pixels, share/unshare them across ad accounts, and fetch aggregated event stats.
New endpoints:
•
GET /v1/accounts/{accountId}/tracking-tags (optional adAccountId=act_...)•
POST /v1/accounts/{accountId}/tracking-tags body: adAccountId, name (not idempotent)•
GET /v1/accounts/{accountId}/tracking-tags/{tagId} (includes install code)•
PATCH /v1/accounts/{accountId}/tracking-tags/{tagId} fields: name, enableAutomaticMatching, automaticMatchingFields (em/ph/fn/ln/ge/db/ct/st/zp/country/external_id), firstPartyCookieStatus (empty/first_party_cookie_disabled/first_party_cookie_enabled), dataUseSetting (advertising_and_analytics/analytics_only/empty)•
GET|POST|DELETE /v1/accounts/{accountId}/tracking-tags/{tagId}/shared-accounts (DELETE supports adAccountId query)•
GET /v1/accounts/{accountId}/tracking-tags/{tagId}/stats (optional aggregation, startTime, endTime; aggregation enum includes event, url, device_type, browser_type, etc.)Notes: Meta-only (
platform=metaads; other platforms return 405). Requires the Meta ads SocialAccount from the Ads add-on connect flow; list view omits code (use get to retrieve it).View documentation
❤2
GET
This makes it easier to identify the boosted IG post and which connected Instagram account was used to read comments (useful for follow-up reply/hide actions via
New
•
•
•
Also clarified: for Instagram-placed ads, if no connected Instagram account on the profile can read the ad’s media, the endpoint returns
View documentation
/v1/ads/{adId}/comments now returns additional Instagram metadata in meta for Instagram-placed ads.This makes it easier to identify the boosted IG post and which connected Instagram account was used to read comments (useful for follow-up reply/hide actions via
/v1/inbox/comments).New
meta fields (Instagram-only):•
instagramUserId•
instagramPermalink•
instagramAccountIdAlso clarified: for Instagram-placed ads, if no connected Instagram account on the profile can read the ad’s media, the endpoint returns
422 with code ads_connection_required.View documentation
❤1
Meta ads (boosted/dark posts) are now included in
Ad rows are flagged so you can route comment fetching to the ads comments thread.
Use
•
•
• omit
New fields on inbox rows:
View documentation
GET /v1/inbox/comments for users with the Ads add-on (Metronome plans always qualify).Ad rows are flagged so you can route comment fetching to the ads comments thread.
Use
platform:•
metaads - ads only•
facebook/instagram - organic only• omit
platform - bothNew fields on inbox rows:
isAd (boolean), adId (string). For ad rows, fetch the thread via GET /v1/ads/{adId}/comments.GET /v1/inbox/comments/{postId} now returns meta.adComments when a boosted post has no organic comments (includes adId and adCommentsUrl), and may return 400 with code USE_AD_COMMENTS_ENDPOINT when postId is an ad creative/ad ID.GET /v1/ads adds filters to map Business Manager IDs back to Zernio ads: platformAdId, effectiveObjectStoryId, effectiveInstagramMediaId.View documentation
🔥3
POST
This creates a LinkedIn Single Image Ad backed by a Direct Sponsored Content ("dark post") authored by a Company Page, with supported goals
Key request fields for LinkedIn:
•
•
•
•
•
•
Also updated:
•
• Meta-only: new
View documentation
/v1/ads/create now supports creating LinkedIn standalone ads.This creates a LinkedIn Single Image Ad backed by a Direct Sponsored Content ("dark post") authored by a Company Page, with supported goals
engagement, traffic, awareness (and traffic requires linkUrl).Key request fields for LinkedIn:
•
organizationId (Company Page org ID or urn:li:organization:N; required unless it can be inferred)•
headline (now required for LinkedIn; max 400)•
body (used as LinkedIn post commentary)•
imageUrl (required for LinkedIn)•
linkUrl (required for goal=traffic)•
longHeadline (optional secondary description on LinkedIn traffic ads)Also updated:
•
callToAction enum expanded with REGISTER, JOIN, ATTEND, REQUEST_DEMO, VIEW_QUOTE, APPLY, SEE_MORE, BUY_NOW• Meta-only: new
attributionSpec to control conversion attribution windows (CLICK_THROUGH/VIEW_THROUGH/ENGAGED_VIDEO_VIEW with windowDays 1/7/28).View documentation
❤3
TikTok conversion ads via
For TikTok,
Set:
•
•
•
View documentation
POST /v1/ads/create now support/require TikTok pixel optimization settings through promotedObject.For TikTok,
goal=conversions uses promotedObject to configure the ad group’s pixel + optimization event (or inherit them by using adSetId).Set:
•
goal: conversions•
promotedObject.pixelId (required for TikTok conversions)•
promotedObject.customEventType (optional TikTok optimization_event code, e.g. ON_WEB_ORDER, INITIATE_ORDER, ON_WEB_CART, ON_WEB_REGISTER, FORM, ON_WEB_DETAIL)View documentation
❤1
New endpoint:
Send
Request body:
•
Auth/scope note: for profile-restricted API keys, both the account’s current profile and the target
Responses:
View documentation
PATCH /v1/accounts/{accountId} to move a connected account to a different profile owned by the same user.Send
profileId in the JSON body to set the target profile.Request body:
•
profileId (required)Auth/scope note: for profile-restricted API keys, both the account’s current profile and the target
profileId must be allowed, otherwise you’ll get 403.Responses:
200 returns message and profileId; errors include 400, 401, 403, 404.View documentation
🔥1
New endpoint
Key params:
•
•
•
Response:
View documentation
GET /v1/ads/timeline returns a daily time series of aggregate ad metrics for a social account (one row per calendar day), useful for spend/conversions charts without calling /v1/ads/tree per day.Key params:
•
accountId (required)•
fromDate, toDate (YYYY-MM-DD; defaults to last 90 days; max 730 days)•
platform (optional): facebook, instagram, tiktok, linkedin, pinterest, google, twitterResponse:
rows[] with per-day metrics like spend, impressions, clicks, ctr, conversions, actions, purchaseValue, roas. Returns empty rows if no activity. 403 if Ads add-on is required.View documentation
🔥1
GET /v1/ads/timeline now supports filtering by a specific platform ad account via adAccountId.Use this when a single Zernio connection wraps multiple platform ad accounts and you want the timeline chart for just one (e.g. Meta
act_…, TikTok advertiser ID).New query param:
•
adAccountId (optional)Note: rows ingested before
2026-05-13 may not include this dimension yet; the recurring 7-day re-sync will repopulate them over time.View documentation
🔥1
Webhooks now support
Subscribe to get notified when a Meta ads object (campaign/ad set/ad) changes status or enters
Add
Payload highlights:
•
•
•
•
Also,
View documentation
ad.status_changed.Subscribe to get notified when a Meta ads object (campaign/ad set/ad) changes status or enters
WITH_ISSUES.Add
ad.status_changed to events when creating/updating a webhook via POST /v1/webhooks/settings or PUT /v1/webhooks/settings.Payload highlights:
•
event: ad.status_changed•
adObject.level: CAMPAIGN | AD_SET | AD•
status.raw: platform-native status (e.g. ACTIVE, PAUSED, WITH_ISSUES)•
error: optional diagnostics on most WITH_ISSUES eventsAlso,
GET /v1/ads/{adId}/analytics now returns ad.currency (ISO 4217) so you can interpret money values in summary and daily.View documentation
❤2👍1
Google Business reviews now support owner replies via new endpoints:
Use
Reply body:
New optional bidding controls on CTWA:
CTWA create response is now a tagged union via
View documentation
POST /v1/accounts/{accountId}/gmb-reviews/{reviewId}/reply and DELETE /v1/accounts/{accountId}/gmb-reviews/{reviewId}/reply.Use
comment to post/update a reply (calling POST again overwrites the previous reply). Deleting removes only the reply, not the review.Reply body:
{ "comment": "..." }POST /v1/ads/ctwa now supports creating multiple CTWA ads under one campaign/ad set by sending a non-empty creatives[] array (each creative has its own headline, body, and exactly one of imageUrl/video). Single-creative requests still work.New optional bidding controls on CTWA:
bidStrategy (LOWEST_COST_WITHOUT_CAP, LOWEST_COST_WITH_BID_CAP, COST_CAP, LOWEST_COST_WITH_MIN_ROAS) plus bidAmount (required for bid-cap/cost-cap) and roasAverageFloor (required for min-ROAS).CTWA create response is now a tagged union via
adType: single or multi.View documentation
❤1🔥1
Webhooks now support WhatsApp template status updates via the new event
This fires when Meta completes a (re)review of a template on a connected WABA, so you can react to approvals/rejections and other status transitions.
Subscribe by adding
Payload:
View documentation
whatsapp.template.status_updated.This fires when Meta completes a (re)review of a template on a connected WABA, so you can react to approvals/rejections and other status transitions.
Subscribe by adding
whatsapp.template.status_updated to Webhook.events.Payload:
WebhookPayloadWhatsAppTemplateStatusUpdated with template.status ∈ APPROVED, REJECTED, PENDING, PAUSED, DISABLED, IN_APPEAL, PENDING_DELETION and template.reason (e.g. "NONE" on approval).View documentation
❤1
GET /v1/ads/campaigns now supports filtering aggregated campaign metrics by a date range.Use
fromDate and toDate (YYYY-MM-DD, inclusive) to control the metrics window returned for each campaign.New query params:
•
fromDate - start date (defaults to 90 days ago when both date params are omitted)•
toDate - end date (defaults to today; max 730-day range)View documentation
🔥1
Webhooks now support per-platform terminal post events:
These fire once per platform target inside a post when that specific platform reaches a terminal state (published or permanent failure), which helps track multi-platform posts more precisely.
Subscribe via
•
•
A new webhook event is also available:
•
View documentation
post.platform.published and post.platform.failed.These fire once per platform target inside a post when that specific platform reaches a terminal state (published or permanent failure), which helps track multi-platform posts more precisely.
Subscribe via
events on POST /v1/webhooks/settings or PUT /v1/webhooks/settings:•
post.platform.published•
post.platform.failedA new webhook event is also available:
•
whatsapp.template.status_updatedView documentation
🔥1
{adId} in GET /v1/ads/{adId} and GET /v1/ads/{adId}/comments now accepts multiple identifier types.You can call these endpoints using the Zernio internal
_id (24-char hex), Meta numeric platformAdId (from comment.received as comment.ad.id), or the creative’s effective_object_story_id / effective_instagram_media_id. Any of these resolves to the same ad, so you don’t need a translation step.View documentation
🔥2
POST
If you send the same
Use
Duplicate protection still applies separately: identical content to the same
View documentation
/v1/posts now supports request idempotency via x-request-id.If you send the same
x-request-id again within ~5 minutes (including while the first request is in-flight), the API treats it as a retry and returns HTTP 200 with the original post in existingPost (no duplicate post is created).Use
x-request-id (UUID) per logical create call. If you omit it, each request is treated as new.Duplicate protection still applies separately: identical content to the same
(platform, accountId) within 24h returns HTTP 409 with details.accountId, details.platform, details.existingPostId.View documentation
🔥1
Facebook now supports multi-link carousel posts via
This lets you publish a 2–5 card carousel where each image has its own click-through link (and optional headline/description).
Set
•
•
•
Optionally set
Constraints:
View documentation
facebookSettings on POST /v1/posts.This lets you publish a 2–5 card carousel where each image has its own click-through link (and optional headline/description).
Set
facebookSettings.carouselCards (2–5 items) with:•
link (required)•
name (optional)•
description (optional)Optionally set
facebookSettings.carouselLink for the carousel end-card destination.Constraints:
mediaItems must be images only, and must match carouselCards length/order. Mutually exclusive with facebookSettings.contentType = story or reel.View documentation
🔥1
GET
This lets you control the order of returned campaigns (by recency or aggregated spend) while keeping pagination at the campaign level.
Use
•
•
•
•
View documentation
/v1/ads/tree now supports campaign-level sorting via a new sort query parameter.This lets you control the order of returned campaigns (by recency or aggregated spend) while keeping pagination at the campaign level.
Use
sort:•
newest (default)•
oldest•
spend_desc•
spend_ascView documentation
❤2
GET
Use it to control the order of returned campaigns (by newest/oldest activity or by spend in the requested date range).
Set
•
•
•
•
View documentation
/v1/ads/tree now supports campaign-level sorting via sort.Use it to control the order of returned campaigns (by newest/oldest activity or by spend in the requested date range).
Set
sort to:•
newest (default)•
oldest•
spend_desc•
spend_ascView documentation
❤2🔥1