X (Twitter) posts now support additional labeling and media safety controls via
You can label posts as paid promotions or AI-generated media, and mark attached media with sensitive-content warnings.
New fields in
•
•
•
Reddit posts now support additional post options via
New fields in
•
•
•
•
View documentation
platformSpecificData.You can label posts as paid promotions or AI-generated media, and mark attached media with sensitive-content warnings.
New fields in
TwitterPlatformData:•
paidPartnership (boolean)•
madeWithAi (boolean)•
sensitiveMedia with adultContent, graphicViolence, other (booleans; requires media)Reddit posts now support additional post options via
platformSpecificData.New fields in
RedditPlatformData:•
flairText (string; ignored if flairId is set)•
nsfw (boolean)•
spoiler (boolean)•
sendreplies (boolean)View documentation
❤1
Meta Lead Gen ads created via
You can run Meta’s multi-text / multi-asset optimization ("Multiple Text Options") on instant-form lead ads; Zernio will create the required Dynamic Creative ad set automatically and attach the form for you.
Use:
•
•
•
• Optional variations:
• Required:
View documentation
POST /v1/ads/create now support Dynamic Creative using dynamicCreative together with goal=lead_generation.You can run Meta’s multi-text / multi-asset optimization ("Multiple Text Options") on instant-form lead ads; Zernio will create the required Dynamic Creative ad set automatically and attach the form for you.
Use:
•
goal=lead_generation•
leadGenFormId=<form_id>•
dynamicCreative.imageUrls (send 1+; send a single entry if you only want multi-text)• Optional variations:
dynamicCreative.titles, dynamicCreative.bodies, dynamicCreative.descriptions, dynamicCreative.linkUrls• Required:
dynamicCreative.callToActionTypes (e.g. LEARN_MORE, SIGN_UP, DOWNLOAD, REGISTER, BUY_NOW)View documentation
❤1
WhatsApp template buttons updated:
This enables WhatsApp marketing “copy code” buttons where the label is fixed by WhatsApp, and the coupon code is provided via
Key changes:
•
•
•
View documentation
WhatsAppTemplateButton now supports a new button type value copy_code, and text is no longer required for all button types.This enables WhatsApp marketing “copy code” buttons where the label is fixed by WhatsApp, and the coupon code is provided via
example.Key changes:
•
type enum now includes: quick_reply, url, phone_number, otp, copy_code, flow, mpm, catalog•
text: required for all types except copy_code•
example is now string or string[] (URL buttons: string[]; copy_code: coupon code as string)View documentation
❤1🔥1
Invite token creation now supports assigning an org role and issuing read-only invites via
Use
View documentation
POST /v1/invite/tokens.Use
role to grant org-level permissions (member | billing_admin, default member), and readOnly to restrict the invitee to view-only access within their scope (default false).View documentation
🔥1
Webhooks now support a new WhatsApp number event:
Subscribe to this event to be notified when a WhatsApp number needs additional action to proceed.
Add it to
•
View documentation
whatsapp.number.action_required.Subscribe to this event to be notified when a WhatsApp number needs additional action to proceed.
Add it to
events when creating/updating a webhook via POST /v1/webhooks/settings or PUT /v1/webhooks/settings:•
events: ["whatsapp.number.action_required", ...]View documentation
❤5
Invite creation now supports a dedicated read-only role via
Use
•
•
•
The
View documentation
role on POST /v1/invite/tokens.Use
role to control access level:•
member•
billing_admin•
viewer - read-only (no publish/edit/delete/connect)The
readOnly field is now deprecated. If readOnly=true, the invite is created with role=viewer (and it can’t be combined with role=billing_admin).View documentation
❤1
POST
This lets you set the secondary link text on Facebook/Instagram ads instead of relying on Meta scraping OpenGraph data.
Use:
•
•
Also clarified for Meta lead ads: when using
View documentation
/v1/ads/create now supports Meta link descriptions via a new description field.This lets you set the secondary link text on Facebook/Instagram ads instead of relying on Meta scraping OpenGraph data.
Use:
•
description (Meta only) — applies to legacy + attach + placementAssets•
creatives[].description (Meta multi-creative) — per-ad override; falls back to top-level descriptionAlso clarified for Meta lead ads: when using
adSetId (attach shape) into a lead ad set, you must pass leadGenFormId on every attached ad.View documentation
❤1
Meta video ads created via
You can now omit
Applies to:
• Top-level
•
View documentation
POST /v1/ads/create no longer require a thumbnail.You can now omit
video.thumbnailUrl and Zernio/Meta will auto-generate the poster frame using Meta’s preferred video thumbnail (same candidates as Ads Manager). Provide it only if you need an exact poster frame.Applies to:
• Top-level
video (legacy + attach shapes): video.url required, video.thumbnailUrl optional•
creatives[].video (Meta multi-creative): video.url required, video.thumbnailUrl optionalView documentation
❤1
New endpoint:
You can now fetch Google Business Profile attribute metadata (valid attribute names, value types, and allowed enum values) before reading/writing via
Query modes (mutually exclusive):
• Location mode:
• Category mode:
Pagination:
Response includes
View documentation
GET /v1/accounts/{accountId}/gmb-attribute-metadata.You can now fetch Google Business Profile attribute metadata (valid attribute names, value types, and allowed enum values) before reading/writing via
gmb-attributes.Query modes (mutually exclusive):
• Location mode:
locationId (or omit to use the account’s stored selectedLocationId)• Category mode:
categoryName (must start with categories/) + regionCode (optional languageCode)Pagination:
pageSize (1–200) and pageToken.Response includes
attributeMetadata[] with parent, valueType (e.g. BOOL, ENUM, URL, REPEATED_ENUM), displayName, repeatable, deprecated, and valueMetadata[] (enum options), plus nextPageToken when more results are available.View documentation
❤2
WhatsApp phone number purchase now supports idempotent retries and duplicate-purchase protection on
Use
A second purchase within 10 minutes is now rejected with
View documentation
POST /v1/whatsapp/phone-numbers/purchase.Use
purchaseIntentId (optional) as an idempotency key: retry with the same value and, if a number was already bought, the API returns { status: "already_purchased", numberId, phoneNumber } instead of provisioning a second number.A second purchase within 10 minutes is now rejected with
409 and code PURCHASE_VELOCITY. To confirm an intentional additional purchase (e.g. bulk provisioning), set allowMultiple to true.View documentation
❤1
GET
This lets you list Embedded Signup–linked WABA numbers alongside purchased numbers (which remain in
New response field:
•
•
•
•
•
Included only on the default view and when
View documentation
/v1/whatsapp/phone-numbers now also returns connected (bring-your-own) WhatsApp numbers in a separate connected array.This lets you list Embedded Signup–linked WABA numbers alongside purchased numbers (which remain in
numbers). Connected numbers aren’t provisioned or billed by Zernio and use accountId for messaging/inbox endpoints.New response field:
connected[] with:•
accountId•
phoneNumber•
displayName•
profileId•
connectedAtIncluded only on the default view and when
status=active.View documentation
❤2
Meta catalog ads are now supported via
This lets you create Advantage+ catalog ads (e.g. vehicle inventory) using a Meta product catalog + product set; Meta renders the visuals per catalog item (no
Discover inputs with:
•
•
Create the ad with:
•
•
•
•
Notes:
View documentation
goal = catalog_sales on POST /v1/ads/create.This lets you create Advantage+ catalog ads (e.g. vehicle inventory) using a Meta product catalog + product set; Meta renders the visuals per catalog item (no
imageUrl/video sent).Discover inputs with:
•
GET /v1/ads/catalogs (accountId, adAccountId)•
GET /v1/ads/catalogs/{catalogId}/product-sets (catalogId, accountId)Create the ad with:
•
goal: catalog_sales•
promotedObject.productSetId•
promotedObject.pixelId•
promotedObject.customEventTypeNotes:
catalog_sales is single-shape only (no creatives[], adSetId, dynamicCreative, or placementAssets).View documentation
❤1
WhatsApp now supports managing your blocklist via
You can list blocked users, block up to 1,000 users per request, and unblock in batches (per-user failures are returned without failing the whole request).
New endpoints:
•
•
•
WhatsApp interactive messages now also support location requests in
View documentation
/v1/whatsapp/block-users.You can list blocked users, block up to 1,000 users per request, and unblock in batches (per-user failures are returned without failing the whole request).
New endpoints:
•
GET /v1/whatsapp/block-users with accountId, optional limit, after (cursor pagination via nextCursor)•
POST /v1/whatsapp/block-users body: accountId, users (1..1000)•
DELETE /v1/whatsapp/block-users body: accountId, users (1..1000)WhatsApp interactive messages now also support location requests in
POST /v1/inbox/conversations/{conversationId}/messages via interactive.type = location_request_message (and action can be omitted; defaults to {"name":"send_location"}).View documentation
❤1
POST
Use this to request consumer permission before placing a Business-Initiated Call; the consumer must tap Allow before
Set:
•
•
View documentation
/v1/whatsapp/calls now supports sending the WhatsApp call-consent prompt via a new optional action parameter.Use this to request consumer permission before placing a Business-Initiated Call; the consumer must tap Allow before
start_call is permitted (Meta rate-limits prompts and requires an open 24h service window).Set:
•
action: send_call_permission_request (omit action to place a call)•
bodyText: optional text shown with the consent prompt (max 1024 chars)View documentation
❤1
WhatsApp adds blocked-status lookup for a single contact via
This returns a definitive blocked state using Zernio’s blocklist mirror (kept in sync by block/unblock; first call per account may backfill from Meta’s full list).
Required query params:
•
•
Response
•
View documentation
GET /v1/whatsapp/block-users/status.This returns a definitive blocked state using Zernio’s blocklist mirror (kept in sync by block/unblock; first call per account may backfill from Meta’s full list).
Required query params:
•
accountId•
user (consumer wa_id or E.164 phone; leading + optional)Response
200:•
blocked (boolean)View documentation
❤1
GET
This lets you choose whether daily totals are attributed to the post’s publish date or bucketed by the day engagement was actually received (engagement-over-time).
Use
•
•
View documentation
/v1/analytics/daily-metrics now supports engagement attribution via a new query param attribution.This lets you choose whether daily totals are attributed to the post’s publish date or bucketed by the day engagement was actually received (engagement-over-time).
Use
attribution:•
publish (default) — attribute each post’s lifetime total to its publish date•
received — attribute per-day engagement increases to the day they occurredView documentation
❤1
YouTube analytics now supports video retention curves via
This returns an aggregated (not per-day) audience retention curve for a single video, plus
Call with:
•
•
• optional
Response highlights:
•
• empty
Requires
Also added to
• top-level
• per-day
View documentation
GET /v1/analytics/youtube/video-retention.This returns an aggregated (not per-day) audience retention curve for a single video, plus
durationSeconds so you can render the curve on a time axis.Call with:
•
videoId•
accountId• optional
startDate, endDateResponse highlights:
•
retentionCurve[] points with elapsedVideoTimeRatio, audienceWatchRatio (can be > 1), relativeRetentionPerformance• empty
retentionCurve for low-view / not-yet-processed videos (2–3 day delay)Requires
yt-analytics.readonly; if missing you may get 412 with code=youtube_analytics_scope_missing.Also added to
GET /v1/analytics/youtube/daily-views responses:• top-level
durationSeconds• per-day
averageViewPercentage (can exceed 100; don’t clamp client-side)View documentation
❤1
WhatsApp interactive messages now support voice call buttons when sending inbox messages via
This lets you render WhatsApp’s native “call” CTA in-chat (requires WhatsApp Business Calling enabled on the sending number). Optional attribution data can be echoed back on the
Use
•
•
•
Also,
View documentation
POST /v1/inbox/conversations/{conversationId}/messages.This lets you render WhatsApp’s native “call” CTA in-chat (requires WhatsApp Business Calling enabled on the sending number). Optional attribution data can be echoed back on the
calls webhook.Use
interactive.type = voice_call and interactive.action.name = voice_call. Optional interactive.action.parameters:•
display_text•
ttl_minutes•
payloadAlso,
GET /v1/whatsapp/calling now returns callDeepLink (nullable) for the public https://wa.me/call/<number> deep link when calling is enabled.View documentation
❤1
Google campaign objects now include
This exposes the raw Google Ads
New field:
•
View documentation
advertisingChannelType in AdCampaign and AdTreeCampaign.This exposes the raw Google Ads
campaign.advertising_channel_type so you can distinguish campaign serving surfaces (e.g. Search vs Performance Max) when syncing/reporting.New field:
•
advertisingChannelType (string, nullable) — Google-only (e.g. SEARCH, PERFORMANCE_MAX, VIDEO, DEMAND_GEN, DISPLAY, SHOPPING)View documentation
❤1
Broadcast recipient results now include a plain-language failure reason via
This helps you interpret WhatsApp
Use:
•
•
Webhooks for delivery status now also include
View documentation
errorExplanation on GET /v1/broadcasts/{broadcastId}/recipients.This helps you interpret WhatsApp
errorCode values (e.g. opt-out / re-engagement required) without maintaining your own mapping.Use:
•
recipients[].errorCode (integer, nullable)•
recipients[].errorExplanation (string, nullable; null if unmapped — fall back to error)Webhooks for delivery status now also include
error.explanation in WebhookPayloadMessageDeliveryStatus (populated on event=message.failed).View documentation
❤1
GET /v1/connect/{platform}/ads now supports ad sync scoping via adAccountId/adAccountIds across more ads platforms (not just Meta).You can limit discovery/sync to specific ad accounts for
facebook/instagram (Meta), linkedin, googleads, and twitter. Changing the scope will also remove already-synced ads from any de-scoped ad accounts.Use:
•
adAccountId - single ad account id (platform-specific format)•
adAccountIds - multiple ids (repeat param or comma-separated)Notes:
•
tiktok ignores these params (advertisers are scoped during OAuth)•
pinterest ignores these params (no ads discovery)• Meta ids (
act_<digits>) are validated against the connected token; unreachable ids return 400• Omitting both
adAccountId and adAccountIds keeps the previously persisted scope unchangedView documentation