Zernio | Developer News
707 subscribers
1 photo
1 video
498 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
Meta ads now support DSA (EU) advertiser disclosures via two new optional fields on ad creation endpoints.

When your targeting intersects EU member states, Meta may require these values (enforced server-side) to comply with DSA Article 26.

Set:
dsaBeneficiary — legal entity benefiting from the ad
dsaPayor — legal entity paying for the ad (Meta spelling: dsa_payor)

Available on:
POST /v1/ads/boost
POST /v1/ads/create
POST /v1/ads/ctwa

View documentation
4
GET /v1/ads/accounts now returns Meta ad account timezone details: timezoneName and timezoneOffsetHoursUtc.

Use these fields to align daily budget reset timing and Insights day boundaries with the ad account’s local timezone.

New fields in each item of accounts[]:
timezoneName (IANA timezone, Meta only)
timezoneOffsetHoursUtc (signed UTC offset in hours, reflects current DST, Meta only)

View documentation
🔥4
GET /v1/accounts/{accountId}/gmb-location-details now returns a new location summary object in the 200 response.

This provides a compact, public-facing view derived from GBP metadata, making it easy to surface “leave a review” and Maps URLs without parsing the raw metadata block.

New fields under location:
name
placeId
reviewUrl
mapsUri
isVerified

Populated when readMask includes metadata (default). For unverified/new locations, placeId/reviewUrl/mapsUri may be null.

View documentation
3
Ads API now supports setting bid strategy on campaigns, ad sets, and boosted posts.

You can update campaign-level defaults via PUT /v1/ads/campaigns/{campaignId} using bidStrategy (optionally alongside budget). Ad sets can now be updated via PUT /v1/ads/ad-sets/{adSetId} with bidStrategy plus bidAmount or roasAverageFloor when required.

Set bidStrategy to:
LOWEST_COST_WITHOUT_CAP
LOWEST_COST_WITH_BID_CAP (requires bidAmount)
COST_CAP (requires bidAmount)
LOWEST_COST_WITH_MIN_ROAS (requires roasAverageFloor)

Boosting posts via POST /v1/ads/boost now accepts bidStrategy, bidAmount, and roasAverageFloor. TikTok boosts also add linkUrl and callToAction.

Ad read models now include bidStrategy (normalized for Meta + TikTok) and may include bidAmount / roasAverageFloor on Ad, AdCampaign, and AdTree* responses.

GBP location details (GET /v1/accounts/{accountId}/gmb-location-details) now always includes title + metadata and always populates the derived location summary; passing location in readMask returns 400.

View documentation
3
New Ads endpoints and expanded TikTok support.

You can now list TikTok Business Centers and trigger a full ads re-sync when permissions or accessible accounts change.

• List TikTok BCs: GET /v1/ads/business-centers with accountId → returns businessCenters[] (bcId, name, advertiserCount)
• Re-sync an ads account: POST /v1/ads/sync/initial with accountId → returns status (queued | already_queued) + traceId; completion via webhook account.ads.initial_sync_completed

TikTok campaign duplication is now supported via POST /v1/ads/campaigns/{campaignId}/duplicate by setting platform to tiktok (Meta still supported).

Ad updates now support more platforms/fields:
PUT /v1/ads/{adId} supports targeting + creative on facebook/instagram/tiktok. Other platforms return 501 (unsupported_platform_operation) when sending targeting or creative.

Ad account listing now supports filtering/limiting:
GET /v1/ads/accounts adds optional adAccountId and limit

TikTok boost now supports cross-creator Spark Ads:
POST /v1/ads/boost adds sparkAuthCode

Standalone ad creation “attach” mode now supports TikTok:
POST /v1/ads/create adSetId is now supported for tiktok (ad group ID)

New response fields:
Ad adds platformAdAccountName and platformCreatedAt
AdCampaign and AdTreeCampaign add platformAdAccountName

View documentation
3
Analytics endpoints now support filtering by social account via accountId.

This lets you scope results to a specific connected account (useful when a profileId contains multiple accounts).

Added optional query param accountId on:
GET /v1/analytics/best-time
GET /v1/analytics/content-decay
GET /v1/analytics/posting-frequency

View documentation
3
TikTok boost ads now surface clearer requirements and failure modes in POST /v1/ads/boost.

For TikTok boosts, include targeting.countries (ISO country codes). TikTok requires locations on the ad group; other platforms can omit it.

The 422 response can now also indicate the connected TikTok user isn’t authorized as an Identity on the target advertiser (returned with code ads_connection_required and an actionable remediation message).

Also note: BusinessCenter.advertiserCount is now nullable (null when the BC asset walk is empty/failed, distinct from 0).

View documentation
1
TikTok ads created via POST /v1/ads/create now honor callToAction (it’s passed through to the Spark Ad creative’s call_to_action).

This lets you set a CTA on TikTok using the same field you already use for Meta.

Set callToAction to one of:
LEARN_MORE, SHOP_NOW, SIGN_UP, BOOK_TRAVEL, CONTACT_US, DOWNLOAD, GET_OFFER, GET_QUOTE, SUBSCRIBE, WATCH_MORE

View documentation
2
New Meta geo targeting lookup endpoint: GET /v1/ads/targeting/search.

It lets you resolve a human-readable location name into Meta’s opaque location key for use in ad targeting.

Call with accountId, q, optional type (country/region/city/subcity/neighborhood/zip/metro_area/geo_market, default city), optional countryCode, and optional limit.

POST /v1/ads/create now supports Meta-only geo targeting via cities[] and regions[]:
cities[]: { key, radius?, distance_unit? } where distance_unit is mile or kilometer
regions[]: { key }

countries[] is now documented as ISO-2 codes and defaults to ["US"] when no cities/regions are provided.

View documentation
1
POST /v1/comment-automations now supports account-wide (any post) comment-to-DM automations.

You can omit platformPostId (and postId) to evaluate comments across every post on an account. Multiple account-wide automations can be stacked and run independently; per-post automations take priority on their post.

Key request rules:
• Per-post: set platformPostId and include postId
• Account-wide: omit platformPostId (and postId)
matchMode: exact | contains

Note: 409 now applies only to per-post automations (duplicate active platformPostId).

View documentation
1
POST /v1/account-groups no longer requires profileId in the request body.

You can now create an account group using only a name and the list of social account IDs.

Request body now requires:
name
accountIds

View documentation
🔥2
Account groups can now include accounts across multiple profiles. For API keys scoped to specific profiles, GET /v1/account-groups only returns groups whose accountIds are all in allowed profiles.

GET /v1/account-groups may now include createdBy and legacy profileId (only on older groups).

POST /v1/account-groups accepts deprecated profileId (ignored) for backward compatibility.

Meta ads connect can now be scoped to specific ad accounts via GET /v1/connect/{platform}/ads (metaads only): adAccountId (format act_<digits>) or adAccountIds (repeat or comma-separated). Response may include scopedAdAccountIds.

Webhook account.ads.initial_sync_completed now includes richer correlation + error details:
account.platformAdAccountId, account.platformAdAccountIds
sync.error, sync.errorCode, sync.errorSubcode, sync.errorCategory = token_invalid | permission_denied | no_ad_accounts | rate_limited | discovery_failed | unknown

View documentation
🔥3
POST /v1/inbox/comments/{postId}/{commentId}/private-reply now supports optional quick reply chips on the first private reply.

You can include up to 13 chips to let users pick an intent in-app (Instagram/Messenger apps only).

New optional field: quickReplies (max 13)
quickReplies[].title (max 20 chars)
quickReplies[].payload
quickReplies[].imageUrl (optional)

View documentation
2
WhatsApp headless OAuth now supports multi-phone WABA selection via a new two-step flow.

When the OAuth redirect includes step=select_phone_number, first list available numbers with GET /v1/connect/whatsapp/select-phone-number using profileId + tempToken (optional X-Connect-Token).

Then bind the chosen number with POST /v1/connect/whatsapp/select-phone-number:
profileId
tempToken
wabaId
phoneNumberId

Note: GET /v1/connect/pending-data is now documented as only for LinkedIn organizations and Snapchat profiles; WhatsApp selection state is passed via redirect params and pending-data may return 404 for WhatsApp flows.

View documentation
🔥2
POST /v1/inbox/comments/{postId}/{commentId}/private-reply now supports inline buttons on the first private reply.

You can attach 1–3 buttons rendered in the same message bubble (Meta button_template). This is recommended for cold reach because quickReplies don’t render in Instagram Message Requests.

New request field: buttons (min 1, max 3), mutually exclusive with quickReplies.
Button types:
url: { type, title, url }
postback: { type, title, payload }
phone (Facebook only): { type, title, phone }

View documentation
🔥3
Ads analytics endpoints now support up to a 730-day metrics date range (previously 90 days).

You can query longer historical performance, and requests for ranges older than 90 days may trigger a one-time on-demand fetch from the ad platform, then be served from cache on subsequent requests.

Applies to:
GET /v1/ads (max range 730 days)
GET /v1/ads/tree (max range 730 days)
GET /v1/ads/{adId}/analytics (max range 730 days)

Use fromDate / toDate; ranges older than 90 days may require scoping to accountId (where noted) to trigger the on-demand fetch.

View documentation
🔥31
Webhooks now support additional message events you can subscribe to when creating/updating webhook settings.

This lets you receive callbacks for outbound message lifecycle changes (send/edit/delete/delivery/read/failure), not just inbound messages.

Use events in POST /v1/webhooks/settings or PUT /v1/webhooks/settings with any of:
message.sent, message.edited, message.deleted, message.delivered, message.read, message.failed

Also added to WebhookPayloadMessage.metadata (Instagram only): storyReply and isStoryMention.

View documentation
🔥3
Message webhooks now include expanded Meta ad-click attribution in metadata.referral (in addition to WhatsApp CTWA).

This lets you attribute the first inbound message to a specific Facebook/Instagram ad click for CTM/CTD flows.

New fields in metadata.referral:
ad_id
ref
source
type
ads_context_data (object: ad_title, photo_url, video_url, post_id, product_id, flow_id)

metadata.referral is now nullable and is only populated on the first inbound message after the click.

View documentation
🔥2
WhatsApp is now supported on 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 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 truth

View documentation
🔥1
Comment-to-DM automations now support inline DM buttons via 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