Zernio | Developer News
685 subscribers
1 photo
1 video
480 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
Google Local Services Ads lead insights are now available via two new endpoints.

You can fetch LSA leads live from Google (newest first) and then pull the conversation history (calls/messages) for a specific lead. Note: data is not persisted (Google is the source of truth), and requests draw from the shared Google Ads operations budget.

Get leads with GET /v1/ads/local-services/leads
Required: accountId
Optional filters: customerId, fromDate, toDate, leadType (PHONE_CALL/MESSAGE/BOOKING), leadStatus (e.g. NEW, BOOKED, WIPED_OUT), chargedOnly, pageToken
Key fields: id, contact (null when WIPED_OUT), charged, creditState, createdTime

Get lead conversations with GET /v1/ads/local-services/leads/{leadId}/conversations
Params: leadId, accountId (+ optional customerId, pageToken)
Conversation fields include channel (PHONE_CALL/MESSAGE/SMS/EMAIL/WHATSAPP/ADS_API), participantType (ADVERTISER/CONSUMER), plus phoneCall.callRecordingUrl / message.attachmentUrls when applicable.

View documentation
1
Campaign listing and tree endpoints now support filtering by delivery/spend within a date window.

On GET /v1/ads/campaigns, you can now return only campaigns that actually delivered in fromDatetoDate, or that reached a spend threshold.

New query params:
hasDelivery (boolean) — only campaigns with delivery in the window (spend > 0 or impressions at zero spend)
minSpend (number, min 0) — only campaigns whose spend in the window reaches this amount (in the campaign’s own currency); implies hasDelivery

On GET /v1/ads/tree, the same filters were added, and fromDate is clarified: it affects metrics only unless you also pass hasDelivery or minSpend. Pagination totals reflect the filtered campaign set.

View documentation
1
GET /v1/inbox/comments/{postId} now supports passing a Facebook/Instagram comment ID as postId to fetch that comment’s replies (instead of the post’s top-level comments).

This lets you page deeper reply threads without a separate endpoint; on YouTube, postId must still be a video id.

Use:
GET /v1/inbox/comments/{postId}?accountId=... where {postId} can be a post ID or (FB/IG only) a comment ID
• New response signal (Facebook only): repliesHasMore (when true, fetch remaining replies by calling the same endpoint with that comment’s id as postId)

Also updated for GET /v1/inbox/comments pagination:
nextCursor pagination can continue past the first page on facebook, instagram, threads, linkedin, youtube
• Cursor paging is only coherent for sortBy=date + sortOrder=desc; other sort combinations can make page 2 unreliable
• Treat nextCursor as opaque and dedupe results by id

View documentation
GET /v1/ads/targeting/search expands geo targeting with a new geoType option all and additional geo types.

You can now search across multiple geo levels in one call (relevance-ranked) instead of picking a single level.

Updated geoType enum:
all, country, region, city, subcity, neighborhood, place, zip, metro_area, geo_market

Pinterest notes: city is treated as an alias for all (Pinterest has no city-level catalog), and some geo types (e.g. zip) return 400 because Pinterest doesn’t expose those catalogs.

View documentation
Workflow nodes now support an optional display label via WorkflowNode.label.

This lets you set a human-friendly name shown in the builder canvas/inspector (falls back to the node type when omitted). If you update a workflow, remember the nodes array is replaced wholesale—so resend label to keep it.

Use label (string, 1–80 chars) on WorkflowNode.

View documentation
POST /v1/posts now supports LinkedIn plain reposts (no commentary).

If every platform entry is a LinkedIn repost using platformSpecificData.reshareUrl, you can omit top-level content (and omit customContent) to publish LinkedIn’s one-click “Repost” with no text.

Use platformSpecificData.reshareUrl (LinkedIn post URL or urn:li:share/urn:li:ugcPost/urn:li:groupPost). If you include content, it becomes a quote-reshare (repost with your thoughts).

View documentation
You can now attach a Meta multi-language ad when adding an ad to an existing ad set via POST /v1/ads/create.

In adSetId (attach) mode, you can provide a per-locale asset feed so one ad carries localized copy (and optional localized media) while keeping social proof on a single post.

Use:
adSetId (attach mode)
defaultLocale (e.g. en, pt_BR)
translations[] with required fields: locale, headline, body, description (optional per-locale: linkUrl, imageUrl, videoUrl, thumbnailUrl)

Note: translations is mutually exclusive with dynamicCreative, placementAssets, carouselCards, existingCreativeId and creatives[].

View documentation
Webhooks now support referral click events via the new referral.received event.

This lets you capture Meta referral payloads even when a click opens an existing thread without generating a message (previously you could only see referrals on message.received when Meta attached them).

To subscribe, include referral.received in events when creating/updating a webhook:
POST /v1/webhooks/settings events
PUT /v1/webhooks/settings events

The webhook payload is WebhookPayloadReferral with:
event = referral.received
referral (Meta object forwarded verbatim; may include ref, source, type, referer_uri, ad_id, ads_context_data)
sender, conversation, account, timestamp

View documentation
KYC address payloads now accept an optional extended_address field on:
POST /v1/phone-numbers/kyc
POST /v1/phone-numbers/kyc/validate-address
(and the deprecated /v1/whatsapp/... aliases).

Use extended_address for address complements like apartment/suite/unit (or quadra/lote in some countries). This can help pass address validation without changing street_address.

Set address.extended_address (KYC submit) or top-level extended_address (validate-address).

View documentation
SMS is now supported in inbox webhooks, and SMS sends now explicitly fail for opted-out recipients.

Inbound SMS replies arrive via message.received with message.platform = sms, and outgoing SMS outcomes arrive via message.delivered / message.failed (carrier error details included on failure).

When sending via POST /v1/sms/messages:
• Opted-out recipients (replied STOP) are refused with 409
409 can also mean the same Idempotency-Key is still in flight

Webhook platform enum now includes sms (alongside instagram, facebook, telegram, whatsapp).

View documentation
Meta conversion setup on POST /v1/ads/create is now stricter/clearer around promotedObject.

Meta rejects promotedObject.pixelId unless promotedObject.customEventType is also provided (even if promotedObject.customConversionId is set). If you want to optimize for a Custom Conversion without sending pixel/event, you can now send promotedObject.customConversionId alone.

Key fields:
promotedObject.pixelId + promotedObject.customEventType (required together for Meta pixel-based conversion optimization)
promotedObject.customConversionId (can be sent alone; if pixelId is also sent, customEventType is still required)
• For pixel custom events: promotedObject.customEventType = OTHER + promotedObject.customEventStr

View documentation
Meta ad creation changed how the default Instagram identity is chosen when instagramAccountId is omitted on POST /v1/ads/create.

If you don’t pass instagramAccountId, we now use the Instagram actor Meta already runs the Page’s other ads as, falling back to the Page’s page-backed Instagram account.

To force a specific IG identity, set instagramAccountId to the desired Instagram Business Account ID (e.g. 17841...).

View documentation
1
Webhooks now support the new WhatsApp event template category updates via whatsapp.template.category_updated.

This fires when Meta reclassifies a WhatsApp template’s category on a connected WABA, so you can react to upcoming (scheduled) and applied (applied) changes.

Subscribe by adding whatsapp.template.category_updated to events when calling POST /v1/webhooks/settings or PUT /v1/webhooks/settings.

Payload highlights:
event: whatsapp.template.category_updated
template.changeType: scheduled | applied
template.category: UTILITY | MARKETING | AUTHENTICATION
template.previousCategory (only when applied)
template.scheduledCategory, template.effectiveAt (only when scheduled)

View documentation
GET /v1/accounts/{accountId}/health now includes platformConnection for WhatsApp accounts.

This adds a live probe of the Meta link behind the channel (same read as GET /v1/whatsapp/number-info), so WhatsApp liveness can be detected even when tokenStatus is valid. When the Meta link is dead, platformConnection.status is disconnected and overall status is error.

New WhatsApp-only fields:
platformConnection.status: connected | disconnected | unknown
platformConnection.checkedAt
platformConnection.phoneStatus
platformConnection.metaError (when disconnected: code, subcode, message)

View documentation
Campaign/ad set status toggles now return clearer, more explicit results and always confirm what switch was written.

For PUT /v1/ads/campaigns/{campaignId}/status, the API writes the campaign on/off switch and returns the confirmed status (active | paused). updated/skipped now describe only ads whose stored status changed alongside the campaign switch, so updated: 0 can be a normal successful resume.

Response additions:
status (active | paused)
skippedReasons (why ads were skipped)

For ad sets (PUT /v1/ads/ad-sets/{adSetId} and PUT /v1/ads/ad-sets/{adSetId}/status), status toggling is now defined as writing the ad set’s own switch where supported (Meta/LinkedIn). Where a platform has no ad-set switch, the API may return no status and instead return a message when nothing was written.

Response additions/changes:
status may be absent (see statusMessage/message)
statusSkippedReasons / skippedReasons
statusMessage / message

Also clarified: on Meta, resuming a campaign doesn’t automatically unpause ad sets paused independently—pair with PUT /v1/ads/ad-sets/{adSetId}/status when needed.

View documentation
👍3
Meta ad creation now supports setting campaign status independently via campaignStatus on POST /v1/ads/create.

This lets you create a campaign ACTIVE while keeping the ad set/ad PAUSED (or the reverse), instead of using a single status value for all levels.

Set campaignStatus to ACTIVE or PAUSED (Meta only). If omitted, it follows status.

Ads now also return Meta’s creative id as ad.creative.creativeId, which you can reuse via existingCreativeId on POST /v1/ads/create.

View documentation
Bluesky now supports default post languages at the account level, and per-post language tagging for feed-generator filtering.

Use the new endpoints to get/set an account default that applies at publish time when a post omits platformSpecificData.langs:
GET /v1/accounts/{accountId}/bluesky-settings → returns defaultLangs
PATCH /v1/accounts/{accountId}/bluesky-settings with defaultLangs = 1–3 BCP-47 codes (or null to clear)

On POST /v1/posts, Bluesky posts now accept platformSpecificData.langs (1–3 BCP-47 codes, e.g. pt, en-US). Per-post langs overrides the account default; if neither is set, the field is omitted. When using threadItems, the same langs applies to every item in the thread.

View documentation
Webhook message.received payload now may include metadata.noRenderableContent (Instagram / Facebook Messenger only).

This flag indicates the inbound message contains nothing you can render (e.g., a template attachment with no text/parseable content, or Meta’s is_unsupported flag). Use it to suppress/handle “empty” messages in your UI.

New field: metadata.noRenderableContent (boolean)

View documentation
Comment webhooks now include comment.author.isOwnAccount in WebhookPayloadComment.

This lets you detect when a comment.received event was authored by the connected account itself (Meta can re-deliver the account’s own replies as comment events), so you can filter or route them differently.

New field:
comment.author.isOwnAccount (boolean) — populated on Instagram/Facebook realtime webhooks only; if absent, it was not evaluated (don’t treat missing as false).

View documentation
WhatsApp messages sent via the inbox endpoints can now disable link previews using linkPreview.

This lets you send WhatsApp text without the URL thumbnail/preview (useful for cleaner utility messages or when previews are undesirable).

Set linkPreview (boolean, default true):
false - send without link preview
true - send with link preview

Available on:
POST /v1/inbox/conversations (WhatsApp Direct Send with category = utility)
POST /v1/inbox/conversations/{conversationId}/messages (WhatsApp; ignored on other platforms)

View documentation
PlatformTarget.errorCategory now includes more granular failure types: platform_rate_limit and quota_exhausted.

Use these to distinguish platform throttling vs. shared daily API quota exhaustion and adjust retry/backoff or alerting logic accordingly.

Updated errorCategory values now include: auth_expired, user_content, user_abuse, account_issue, platform_rejected, platform_error, platform_rate_limit, quota_exhausted, system_error, unknown.

View documentation