WhatsApp interactive messages now support native address capture via
This lets you prompt users with Meta’s structured shipping-address form in-chat; submissions arrive as
To send, set:
•
•
•
Webhook parsing update:
View documentation
interactive.type = address_message on POST /v1/inbox/conversations/{conversationId}/messages.This lets you prompt users with Meta’s structured shipping-address form in-chat; submissions arrive as
metadata.interactiveType = nfm_reply on the message.received webhook.To send, set:
•
interactive.type: address_message•
interactive.action.name: address_message•
interactive.action.parameters.country: ISO 3166-1 alpha-2 (required)Webhook parsing update:
WebhookPayloadMessage.metadata now includes nfmReplyName (e.g. flow vs address_message) to distinguish address submissions from Flow submissions; address fields are included in flowResponseData.View documentation
GET
This lets you preview a video before selecting it (useful when multiple videos share the same first frame).
Key field:
•
View documentation
/v1/ads/videos now returns a playable video URL via source in the default response.This lets you preview a video before selecting it (useful when multiple videos share the same first frame).
Key field:
•
data[].source — signed CDN MP4 URL (expires; use for preview only and re-list to refresh)View documentation
GET /v1/ads/tree now supports scoping the tree to multiple ad accounts via adAccountId.You can pass a comma-separated list to limit results to a subset of connected accounts (useful for agency profiles).
Use
adAccountId=act_1,act_2,act_3 (max 50 per request). Single values keep the old behavior.Note: the plural aliases
adAccountIds and platformAdAccountIds are now rejected with 400 (to avoid silently returning unfiltered results).View documentation
Inbox list endpoints now return which connected accounts were skipped during aggregation via
This helps you distinguish between accounts that failed (
New response field:
•
Applies to:
•
•
•
View documentation
meta.accountsSkipped.This helps you distinguish between accounts that failed (
meta.failedAccounts) vs accounts that were intentionally not queried because the platform/account doesn’t support the feature or isn’t enabled.New response field:
•
meta.accountsSkipped: array of { accountId, platform }Applies to:
•
GET /v1/inbox/conversations•
GET /v1/inbox/comments•
GET /v1/inbox/reviewsView documentation
Meta ads now support the Page Likes objective via
This lets you create campaigns/ads optimized for Page Likes (Meta maps this to Engagement/Page Likes) using the same create flows.
Use
•
•
Notes for
View documentation
goal = page_likes.This lets you create campaigns/ads optimized for Page Likes (Meta maps this to Engagement/Page Likes) using the same create flows.
Use
goal with:•
POST /v1/ads/campaigns: goal now includes page_likes•
POST /v1/ads/create: goal now includes page_likesNotes for
page_likes (Meta): promotedObject.pageId is optional (auto-filled from the connected Page). Creative fields like headline, body, linkUrl, callToAction, imageUrl/video are optional (Meta derives the Like button + destination from the Page).View documentation
❤1
Google Search ads created via
You can create and attach sitelink assets during ad creation (Google reviews them asynchronously; approval is not immediate).
Use
• 2–20 items
• each item:
• optional:
Applies when
View documentation
POST /v1/ads/create now support campaign-level sitelinks.You can create and attach sitelink assets during ad creation (Google reviews them asynchronously; approval is not immediate).
Use
sitelinks (Google Search only):• 2–20 items
• each item:
text (max 25) + linkUrl (URI)• optional:
description1, description2 (each max 35)Applies when
campaignType is search.View documentation
Pinterest posts now support targeting a board section and optionally disclosing AI-modified content via
Use
Set
View documentation
PinterestPlatformData.Use
boardSectionId to publish into a specific section within boardId (omit it to post to the board). Pinterest rejects the pin if the section doesn’t belong to the board, so send both together.Set
isAiGenerated to true to include Pinterest’s AI_MODIFIED disclosure (shows an “AI modified” label); false (default) omits the disclosure.View documentation
Threads posts now support an optional first comment via
This lets you automatically publish a reply immediately after the main post is published; when using
Key field:
•
Note: the first comment is a Threads post and counts toward the profile’s 250 posts / 24h limit.
View documentation
platformSpecificData.threads.firstComment.This lets you automatically publish a reply immediately after the main post is published; when using
threadItems, it replies to the root post.Key field:
•
firstComment (string, max 500)Note: the first comment is a Threads post and counts toward the profile’s 250 posts / 24h limit.
View documentation
Instagram now supports publishing videos muted via
When
Use:
•
Applies to Reels, Stories, and video carousel slides; ignored for images. Videos above 200MB cannot be muted (mute before uploading).
View documentation
muteAudio in platformSpecificData.When
muteAudio=true, we strip the audio track before sending the video to Instagram, so the published video is permanently silent.Use:
•
muteAudio (boolean, default false)Applies to Reels, Stories, and video carousel slides; ignored for images. Videos above 200MB cannot be muted (mute before uploading).
View documentation
You can now fetch a single Google Business Profile review by ID via
This returns one review in the same shape as the items from
Key params:
•
•
•
Response includes
View documentation
GET /v1/accounts/{accountId}/gmb-reviews/{reviewId}.This returns one review in the same shape as the items from
GET /v1/accounts/{accountId}/gmb-reviews, which is useful for checking the latest state before replying (replies are overwritten in place).Key params:
•
accountId (path)•
reviewId (path, ID portion only)•
locationId (query, optional override; otherwise uses the account’s selected location)Response includes
review (GoogleBusinessReview).View documentation
GET
This lets you track recent workspace sign-ins (stamped at most once per hour). The field may be omitted for users with no recorded sign-in since it was introduced.
New field:
•
The
Updated enum:
•
New optional fields:
•
•
View documentation
/v1/users now returns lastLoginAt for each user.This lets you track recent workspace sign-ins (stamped at most once per hour). The field may be omitted for users with no recorded sign-in since it was introduced.
New field:
•
users[].lastLoginAtThe
message.sent webhook payload now supports more platforms and can include send context in a new metadata object.Updated enum:
•
message.platform: instagram, facebook, telegram, whatsapp, twitter, reddit, bluesky, slackNew optional fields:
•
metadata.quotedMessageId•
metadata.threadTs (Slack only)View documentation
GET
This lets you request a desired locale (e.g.
New:
• Query param:
• Response field:
View documentation
/v1/whatsapp/template-library now supports selecting a specific language variant via an optional language query param.This lets you request a desired locale (e.g.
es, en_US); if it’s not available, the API returns the first available variant and reports the actual variant in template.language.New:
• Query param:
language• Response field:
template.availableLanguages (array of supported language codes)View documentation
DELETE /v1/ads/campaigns/{campaignId} now accepts platform=google.You can delete Google campaigns using the same endpoint and request body shape as Facebook/Instagram.
Set
platform to one of: facebook, instagram, googleFor empty campaigns (0 ads), include
accountId to allow deletion: accountId (Zernio SocialAccount id).View documentation
DELETE /v1/ads/campaigns/{campaignId} now accepts platform=google.This lets you delete Google campaigns via the same endpoint used for Meta.
Set
platform to one of: facebook, instagram, google.accountId behavior is unchanged (only needed to delete an EMPTY campaign with zero ads).View documentation
WhatsApp inbox conversation creation now supports sending values for template buttons that carry their own payload (copy-code / flow tokens), via
Use this when your approved WhatsApp template has buttons that need a per-send value (e.g. Pix copy-and-paste code, coupon code, Flow token). This complements
Set
•
•
•
Message lineage is now exposed as
Note: existing stored messages are not backfilled; treat
View documentation
templateButtonParams on POST /v1/inbox/conversations.Use this when your approved WhatsApp template has buttons that need a per-send value (e.g. Pix copy-and-paste code, coupon code, Flow token). This complements
templateParams (text variables + dynamic URL buttons).Set
templateButtonParams as an array of:•
index (0-9)•
subType: url | copy_code | flow•
valueMessage lineage is now exposed as
sentVia on GET /v1/inbox/conversations/{conversationId}/messages and on the message.sent webhook, with values:human | api | broadcast | sequence | workflow | comment_automation | bulk-api | nullNote: existing stored messages are not backfilled; treat
sentVia: null as “unknown”.View documentation
Inbox messages now include send attribution via
This lets you tell which Zernio surface produced an outgoing message (API vs human vs broadcast/workflow/etc). It’s available on message listing responses and on the
New field:
•
Notes:
• Present on
• Present on
• Not backfilled for older stored messages; treat
WhatsApp template sends can now pass per-button values via
Use this for buttons that carry a value at send time (e.g. copy-code payloads or flow tokens), which are not covered by
New request field on
•
-
-
-
Analytics sorting now supports additional Instagram metrics on
New
•
•
•
•
View documentation
sentVia.This lets you tell which Zernio surface produced an outgoing message (API vs human vs broadcast/workflow/etc). It’s available on message listing responses and on the
message.sent webhook.New field:
•
sentVia: human | api | broadcast | sequence | workflow | comment_automation | bulk-api | nullNotes:
• Present on
GET /v1/inbox/conversations/{conversationId}/messages message items• Present on
WebhookPayloadMessageSent.message.sentVia• Not backfilled for older stored messages; treat
null as “unknown”WhatsApp template sends can now pass per-button values via
templateButtonParams when creating a conversation.Use this for buttons that carry a value at send time (e.g. copy-code payloads or flow tokens), which are not covered by
templateParams.New request field on
POST /v1/inbox/conversations (JSON body only):•
templateButtonParams[] items: { index, subType, value }-
index: 0..9-
subType: url | copy_code | flow-
value: stringAnalytics sorting now supports additional Instagram metrics on
GET /v1/analytics.New
sortBy values:•
ig_reels_avg_watch_time•
ig_reels_video_view_total_time•
reposts•
reels_skip_rateView documentation
PlatformTarget.platformSpecificData is now returned as a free-form object (with additionalProperties: true) instead of a oneOf union of *PlatformData schemas.This avoids generated clients failing to deserialize
PlatformTarget responses when platformSpecificData doesn’t match exactly one variant. Treat platformSpecificData as an untyped JSON object on responses (it may be omitted rather than returned as an empty object).View documentation
Instagram is now supported (limited release) for liking/unliking posts and comments via:
•
•
This enables engagement actions on Instagram feed media (posts/reels/carousels) and their comments/replies, but access is currently restricted by Meta permissions.
Instagram requirements/behavior:
• Requires permission
• Only works for accounts connected via Facebook Login; Instagram Login returns
• Accounts whose token predates the permission return
• Limited release: non-allowed accounts return
• Burst limit: 50 like/unlike calls per 5s per Instagram account; exceeding can lock likes for 1 hour
Also note: these endpoints’
View documentation
•
POST /v1/inbox/posts/{postId}/like, DELETE /v1/inbox/posts/{postId}/like•
POST /v1/inbox/comments/{postId}/{commentId}/like, DELETE /v1/inbox/comments/{postId}/{commentId}/likeThis enables engagement actions on Instagram feed media (posts/reels/carousels) and their comments/replies, but access is currently restricted by Meta permissions.
Instagram requirements/behavior:
• Requires permission
instagram_manage_engagement• Only works for accounts connected via Facebook Login; Instagram Login returns
400 with code instagram_likes_require_facebook_login• Accounts whose token predates the permission return
403 with code reconnect_required• Limited release: non-allowed accounts return
403 with code PLATFORM_BETA_RESTRICTED• Burst limit: 50 like/unlike calls per 5s per Instagram account; exceeding can lock likes for 1 hour
Also note: these endpoints’
403 may now indicate missing platform permission (not only Inbox add-on).View documentation
New endpoint:
Provide the ad set ID via
Response includes
View documentation
DELETE /v1/ads/ad-sets/{adSetId} deletes an ad set on the platform and cancels its ads locally (it never deletes the campaign).Provide the ad set ID via
adSetId (path).Response includes
deleted and adCount (number of local Ad documents marked status: cancelled). Returns 501 if deletion isn’t supported on the target platform.View documentation
New endpoint:
Supports cached reads to avoid repeated YouTube calls; response includes
Key params:
•
•
•
•
•
Response highlights:
View documentation
GET /v1/accounts/{accountId}/youtube-captions to fetch a YouTube video transcript (plain text plus timed cues), including auto-generated (asr) and uploaded (standard) tracks.Supports cached reads to avoid repeated YouTube calls; response includes
source = cache | youtube and fetchedAt. Use refresh=true only when captions changed (re-downloads from YouTube).Key params:
•
accountId (path)•
videoId (query, required)•
language (query, optional; BCP-47)•
format (query) = json | srt (default json)•
refresh (query, boolean)Response highlights:
trackKind = asr | standard, cues (when format=json), srt (when format=srt), and availableTracks for language selection.View documentation
GET /v1/usage metering mode now supports spend attribution by profile/account, plus optional projection onto a single profile or account.This lets you break down billed spend (USD) across profiles/accounts for a given window, or fetch the metering payload scoped to one group for chargeback/reporting.
New query params (metering mode):
•
groupBy: profile | account (adds attribution)•
profileId: project results onto one profile (pair with range)•
accountId: project results onto one account (pair with range)New response fields in
UsageMetering:•
attribution (with groupBy, groups, unattributed, totals, restricted)•
scope (present with profileId/accountId)Note: when
profileId or accountId is set, peaks, callUsage, and tax return null (workspace-level only).View documentation