Zernio | Developer News
692 subscribers
1 photo
1 video
487 links
This channel is for recurrent updates and announcements on https://zernio.com.

Zernio is a Social API for Posting and Analytics on 14 platforms.
Download Telegram
Webhook post events now include the connected social account per platform target via post.platforms[].accountId.

This lets you route/attribute webhook deliveries by the specific SocialAccount used for each platform publish (useful when a single post spans multiple accounts).

New field:
WebhookPayloadPost.post.platforms[].accountId
WebhookPayloadPostPlatform.post.platforms[].accountId (on post.platform.published / post.platform.failed; see also the top-level account block there)

View documentation
1
Webhook payloads now include account.accountId (same value as account.id) as a canonical field for filtering/routing events.

This makes it easier to consistently filter all webhook events by a single field (e.g. route staging vs production by account) while keeping account.id for backward compatibility.

New field:
account.accountId

Added to these webhook payloads:
comment.received
lead.received
review.new
review.updated
post.external.created, post.external.updated, post.external.deleted
• inbox webhook payloads via InboxWebhookAccount

View documentation
Webhooks now support TikTok URL backfill via the new event post.tiktok.url_resolved.

This fires when a published TikTok post’s public URL is resolved/backfilled, using the same payload shape as post.platform.published/post.platform.failed (see WebhookPayloadPostPlatform).

Subscribe by including post.tiktok.url_resolved in events when calling POST /v1/webhooks/settings or PUT /v1/webhooks/settings.

Also clarified for PUT /v1/posts/{postId}: to promote a draft to scheduled you must send isDraft: false together with scheduledFor (or publishNow: true / queuedFromProfile). If isDraft is omitted, the post keeps its current draft status.

View documentation
1
Inbox webhook account context now includes optional profileId in InboxWebhookAccount.

Use profileId (workspace/profile ID) to route or filter inbox webhooks by workspace. It may be omitted for the shared WhatsApp sandbox account or when the account has no resolvable profile.

View documentation
1
New endpoint: GET /v1/inbox/conversations/search.

You can now search message text across stored inbox conversations and get back matching conversations with up to 3 most-recent matching messages per conversation (useful for finding threads by topic or filtering by sent/received).

Key params:
query (required, 2–200 chars)
direction: incoming | outgoing
platform: facebook | instagram | telegram | whatsapp | sms
profileId, accountId
limit (1–50, default 20), cursor

Response includes data[].conversation, matchCount, matches (up to 3), plus pagination and meta.accountsSkipped for connected accounts on live-fetched platforms that can’t be searched.

Requires Inbox addon (403 if missing).

View documentation
1
Meta ad metrics now include video performance fields in AdMetrics (and therefore AdDailyMetrics).

You can track video starts, thruplays, 30s views, completion percentiles, and average watch time for hook/hold/drop-off analysis. These fields are Meta video ads only (0 for non-video ads and other platforms).

New fields:
videoPlayActions
video30SecWatchedActions
videoThruplayWatchedActions
videoP25WatchedActions, videoP50WatchedActions, videoP75WatchedActions, videoP95WatchedActions, videoP100WatchedActions
videoAvgTimeWatchedActions

Note: in AdDailyMetrics, videoAvgTimeWatchedActions is recomputed per day; don’t sum or plain-average it across days (the range value is play-weighted).

View documentation
2
GET /v1/inbox/mentions now returns additional LinkedIn author details in each mention.

You can display richer mention attribution (when available) without extra profile resolution on your side.

New fields:
authorName - display name resolved from authorUrn (can be null)
authorUsername - LinkedIn vanity name (can be null)
authorPicture - author profile picture URL (can be null; CDN URLs may expire, so fetch promptly)

View documentation
2
WhatsApp inbox messages now support commerce interactive messages (products, product lists, catalog messages, and carousels) via interactive on POST /v1/inbox/conversations/{conversationId}/messages.

This lets you send catalog-driven messages and receive cart submissions / product inquiries back in webhooks.

New interactive.type values:
product, product_list, catalog_message, carousel

Webhook message.received metadata adds:
metadata.order (cart submitted from commerce messages)
metadata.referredProduct (product inquiry context)

Note: interactive messages are session messages (must be sent within WhatsApp’s 24-hour window).

View documentation
2
Ads reporting endpoints may now return 202 when part of the requested date range isn’t ingested yet.

When this happens, the response includes currently-available data plus backfillPending: true, and a Retry-After header with the recommended poll interval. Repeat the same request until it returns 200 with the full range.

Applies to:
GET /v1/ads
GET /v1/ads/tree
GET /v1/ads/timeline
GET /v1/ads/campaigns/{campaignId}/analytics
GET /v1/ads/{adId}/analytics

Also, POST /v1/posts 403 responses now include a stable code to distinguish causes:
ACCOUNT_DISCONNECTED
PROFILE_OVER_LIMIT

View documentation
4
You can now update saved_targeting audiences via PUT /v1/ads/audiences/{audienceId}.

This lets you change an audience’s name, description, or fully replace its spec (no merge). Uploaded/derived audiences aren’t updatable and return 422.

Request body (send at least one): name, description, spec

Also: GET /v1/ads/audiences now returns accountId for type=saved_targeting items, and DELETE /v1/ads/audiences/{audienceId} clarifies that saved_targeting deletes only the local record (it exists only on Zernio).

View documentation
2
GET /v1/ads/{adId}/analytics and GET /v1/ads/campaigns/{campaignId}/analytics now validate breakdown dimensions and will return 400 for unknown values.

This prevents silent/partial breakdown results and makes invalid breakdowns requests fail fast with a supported-values list.

Updates:
breakdowns: unknown dimensions now return 400 (instead of being ignored)
placement is accepted as an alias for publisher_platform
breakdown (singular) is also accepted

New Meta breakdown options include: platform_position, impression_device, video_asset, image_asset, body_asset, title_asset.

View documentation
GET /v1/analytics now supports a new metric: follows.

You can read analytics.follows in responses (Instagram feed posts and stories only: organic accounts that started following from this post; 0 for reels and other platforms).

You can also sort analytics results by sortBy = follows (enum now includes: date, engagement, impressions, reach, likes, comments, shares, saves, clicks, views, follows).

View documentation
2
The supported breakdowns values were reduced on analytics endpoints.

If you request breakdowns that are no longer supported, your call may fail (400) or no longer return those breakdowns.

Affected endpoints:
GET /v1/ads/{adId}/analytics: Meta breakdowns now limited to age, gender, country, publisher_platform, device_platform, region (removed: platform_position, impression_device, video_asset, image_asset, body_asset, title_asset; also removed aliases placement and singular breakdown)
GET /v1/ads/campaigns/{campaignId}/analytics: Meta breakdowns now limited to age, gender, country, publisher_platform, device_platform, region, platform_position, impression_device, video_asset, image_asset, body_asset, title_asset (removed aliases placement and singular breakdown)

View documentation
1
Google Business Profile posts: offer.offerType has been removed from GoogleBusinessPlatformData.

If you were sending offerType (previously OFFER or BUY_ONE_GET_ONE), remove it from your payloads and use the remaining offer fields instead:
redeemOnlineUrl
termsConditions
couponCode

View documentation
1
POST /v1/sms/registrations now enforces additional required fields for 10DLC registrations.

This can break existing integrations that submit brand/campaign without the newly-required fields.

For brand, these fields are now required: website, street, city, state, postalCode (in addition to existing required fields).

For campaign, sample2 is now required and must be distinct from sample1.

Webhook post events now echo back your post’s free-form metadata (when provided at create time) in:
WebhookPayloadPost.post.metadata
WebhookPayloadPostPlatform.post.metadata

View documentation
1
POST /v1/whatsapp/business-profile/photo now accepts an image via URL in addition to multipart upload.

You can either upload bytes with multipart/form-data (file) or send application/json with url; we fetch the image server-side and upload the bytes to Meta.

New JSON body option:
accountId
url (public https image URL; must resolve directly without redirects)

New response to handle:
422 when the profile photo is locked for WhatsApp coexistence numbers (must be managed in the WhatsApp Business app).

View documentation
1
New billing snapshot endpoint: GET /v1/billing.

It returns the billing “statement” view (plan, current cycle, balance/credits, spend caps, and payment/access status). Use this for billing state; use GET /v1/usage for usage/metering.

Key response blocks:
plan (includes isUsageBased)
period (start/end may be null on Stripe)
balance (null for Stripe; populated for Metronome)
caps (e.g. xSpendUsedCents, xSpendLimitCents)
status (e.g. hasAccess, suspended, openInvoiceUrl, declineReason)

Also: GET /v1/usage is now dual-mode.
• Default (no metering params): same snapshot as before
• Metering mode (billed spend by product) when passing any of: range, granularity, from, to

Metering params:
range: cycle | prev-cycle | 7d | 14d | 30d | 3mo | 12mo | custom
granularity: day | month | total
from/to required when range=custom

Stripe accounts calling metering mode receive { "supported": false }.

View documentation
1
Webhooks now support additional event subscriptions for conversations, calls, leads, and WhatsApp.

You can subscribe to these new events via POST /v1/webhooks/settings or PUT /v1/webhooks/settings:
conversation.started
call.received, call.ended, call.failed, call.permission_request
lead.received
whatsapp.automatic_event

SMS carrier registrations (10DLC) now accept campaign.subUsecases on POST /v1/sms/registrations (2–5 values): 2FA, ACCOUNT_NOTIFICATION, CUSTOMER_CARE, DELIVERY_NOTIFICATION, FRAUD_ALERT, HIGHER_EDUCATION, MARKETING, POLLING_VOTING, PUBLIC_SERVICE_ANNOUNCEMENT, SECURITY_ALERT.

For rejected registrations, GET /v1/sms/registrations/{id} may now include campaignContent (messageFlow, sample1, sample2), and POST /v1/sms/registrations/{id}/appeal can include corrected messageFlow/sample1/sample2 along with appealReason.

View documentation
2
GET /v1/usage now includes estimated tax via a new tax field on UsageMetering.

This lets you show an estimated tax amount (computed with Stripe Tax) on top of the window’s net spend (totals.total). tax is null when no billing address is on file, the total is ≤ 0, or the estimate fails.

New fields:
tax.taxUsd — estimated tax in USD (added on top of totals.total)
tax.ratePercent — combined rate percentage (nullable)
tax.jurisdictionLabel — human label like “ES VAT” (nullable)
tax.reverseChargetrue for EU/UK B2B reverse charge (0 tax added)

View documentation
2
POST /v1/ads/ctwa now supports manual ad placements via placements.

This lets you restrict CTWA ad delivery to specific Meta surfaces/devices instead of using automatic placements (Meta may still enforce eligibility/co-selection rules and return actionable errors).

Use placements with:
publisherPlatforms: facebook | instagram | threads | messenger | audience_network
facebookPositions, instagramPositions, messengerPositions, audienceNetworkPositions, threadsPositions, whatsappPositions
devicePlatforms: mobile | desktop

View documentation
2
Meta placements now support delivering ads on WhatsApp by allowing whatsapp in placements.publisherPlatforms.

This lets you explicitly include WhatsApp inventory when using manual placements (instead of relying on automatic placements).

Set placements.publisherPlatforms to include:
whatsapp (alongside facebook, instagram, threads, messenger, audience_network)

Applies to:
POST /v1/ads/create
POST /v1/ads/ctwa

View documentation
4