Zernio | Developer News
689 subscribers
1 photo
1 video
484 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
Some endpoints now return additional billing/capability errors you may need to handle.

Posts listing may now fail with 403 when X analytics isn’t enabled for the account (code X_ANALYTICS_NOT_ENABLED) on GET /v1/accounts/{accountId}/posts.

OpenAI Ads connect may now return 402 PaymentRequired on POST /v1/connect/openai-ads/credentials.

SMS sender ID creation now has explicit billing-related failures on POST /v1/sms/sender-ids:
402 (code payment_required) when no payment method is on file
409 (code billing_setup_incomplete) when billing setup is incomplete

View documentation
Some endpoints now return additional error statuses you may need to handle.

Posts listing can now return 403 when X analytics isn’t enabled for the account.
GET /v1/accounts/{accountId}/posts403 (code X_ANALYTICS_NOT_ENABLED)

Billing-gated connect / SMS setup now surfaces payment/setup issues explicitly.
POST /v1/connect/openai-ads/credentials402 (PaymentRequired)
POST /v1/sms/sender-ids402 (code payment_required), 409 (code billing_setup_incomplete)

View documentation
Creating or retrying posts can now return 403 with code=ACCOUNT_NOT_ENABLED_FOR_POSTING.

This happens when the target accountId is connected for ads only (i.e., enabled: false) and cannot be posted to. Connect the account as a posting account, refresh IDs via GET /v1/accounts, then retry.

Applies to:
POST /v1/posts (403 code enum now includes ACCOUNT_NOT_ENABLED_FOR_POSTING)
POST /v1/posts/{postId}/retry (403 may include ACCOUNT_NOT_ENABLED_FOR_POSTING, PROFILE_OVER_LIMIT, or insufficient_permissions)

View documentation
WhatsApp template sends via POST /v1/inbox/conversations now validate templateParams more strictly for positional templates.

If you provide fewer values than the template’s required header + body + dynamic URL-button slots, the request is rejected with 400 (INVALID_TEMPLATE_PARAMS) instead of sending a message with misaligned values.

Key fields:
templateParams - must cover all required slots for positional templates
templateButtonParams - can override a button’s value; overridden buttons may not need a value in templateParams unless later uncovered dynamic URL buttons follow

View documentation
GET /v1/ads now supports filtering by Meta ad set via adSetId.

This makes it easier to build adset-centric dashboards by listing only ads within a specific platform ad set.

Use adSetId (platform ad set id) alongside existing filters like campaignId.

PUT /v1/ads/{adId} now supports richer creative updates, especially for Meta.

Meta creative updates are now patch-style: send any subset of creative fields and omitted fields are preserved (including existing media), and you can also repoint an ad to an existing creative.

Key Meta-only options in creative:
description (link description)
videoId (reuse an already-uploaded video)
existingCreativeId (repoint to a creative from GET /v1/ads/creatives; ignores other creative fields)

GET /v1/ads/targeting/search now supports Meta work demographics via dimension values workPosition, workEmployer, workIndustry.

These ids can be used in TargetingSpec as:
workPositions
workEmployers
workIndustries

Also, TargetingSpec audience lists are now supported: audienceInclude and audienceExclude accept platform audience IDs (not supported on OpenAI Ads; returns 400).

View documentation
GET /v1/connect/pending-data pending OAuth tokens are now repeatable and expire 1 hour after issuance (previously one-time use, 10 minutes).

This makes headless OAuth selection flows more resilient (you can re-fetch the pending selection data until the user completes selection; completion deletes the pending record).

Use token (query) from pendingDataToken on the redirect. selectionType can be: organizations, pages, boards, locations, profiles.

Scope note: this pending-data flow now covers Google Business locations and Slack channels in addition to existing large selection lists.

View documentation
Several Ads endpoints can now return 403 with code ads_allowance_exceeded.

This happens when a team has no payment method on file and has reached the 500 free live ads limit; add a card to resume/continue.

You may see this on:
PUT /v1/ads/campaigns/{campaignId}/status
PUT /v1/ads/campaigns/{campaignId}
POST /v1/ads/campaigns/bulk-status
POST /v1/ads/campaigns/{campaignId}/duplicate
POST /v1/ads/ad-sets/{adSetId}/duplicate
POST /v1/ads/{adId}/duplicate
PUT /v1/ads/ad-sets/{adSetId} and PUT /v1/ads/ad-sets/{adSetId}/status
PUT /v1/ads/{adId} and PUT /v1/ads/{adId}/status
PATCH /v1/ads/{adId}/tracking-tags
POST /v1/ads/create
POST /v1/ads/boost
POST /v1/ads/messaging, POST /v1/ads/call, POST /v1/ads/ctwa
POST /v1/ads/campaigns/{campaignId}/assets

If you have retry logic, treat 403 ads_allowance_exceeded as non-retryable until billing is set up.

View documentation
Meta ads now accept regional regulated categories on ad set creation/boosting.

Use this when targeting countries where Meta requires extra regulation flags (e.g. Singapore/Taiwan/Thailand/Australia/India). Without it, Meta may reject the ad set.

Send regionalRegulatedCategories (array of strings) on:
POST /v1/ads/create
POST /v1/ads/boost

Example values include SINGAPORE_UNIVERSAL, TAIWAN_UNIVERSAL, THAILAND_UNIVERSAL, AUSTRALIA_FINSERV, INDIA_FINSERV.

View documentation
Instagram comment-to-DM private replies may now fail for non-followers when you include interactive elements.

Since late Aug 2026, Instagram can refuse buttons (and other attachments/cards) to commenters who don’t follow the account, returning a non-retryable 400 (Meta code 2, subcode 1545133). The failed call still consumes the comment’s single private reply.

If you need to reach non-followers, send plain text using message only, then add buttons after they reply. (quickReplies and buttons remain mutually exclusive.)

View documentation
New endpoint GET /v1/analytics/delta returns a cursor-based feed of analytics snapshots that changed across all readable accounts.

This lets integrations stay in sync with far fewer calls than polling GET /v1/analytics per account; bootstrap once from GET /v1/analytics, then poll deltas.

Key params:
cursor (opaque; omit to start “from now” and receive data: [] + nextCursor)
limit (1–100, default 50; out-of-range = 400)
platform (optional)
profileId (default all)

Response fields:
data (oldest-first changed snapshots)
nextCursor (always present, even on empty pages)
hasMore (if true, call again immediately)

New webhook event available for subscriptions: analytics.synced. It’s a trigger (no metrics/cursor); on receipt, call GET /v1/analytics/delta using your last stored nextCursor.

View documentation
Meta ads now support regional regulation identity mapping via regionalRegulationIdentities on POST /v1/ads/create and POST /v1/ads/boost.

When you include regionalRegulatedCategories (e.g. BRAZIL_REGULATION, SINGAPORE_UNIVERSAL, TAIWAN_UNIVERSAL, THAILAND_UNIVERSAL, AUSTRALIA_FINSERV, INDIA_FINSERV, TAIWAN_FINSERV), you can now pass the required Meta-verified beneficiary/payer entity IDs in regionalRegulationIdentities.

Set:
regionalRegulatedCategories: [...]
regionalRegulationIdentities: { universal_beneficiary: 123, universal_payer: 456, ... }

If omitted, Meta may use Ads Manager defaults when configured.

View documentation
Instagram publishing now supports paid partnership, sponsor tagging, comment toggling, and location tagging via new fields in platformSpecificData.

Use:
isPaidPartnership (boolean) — adds the “Paid partnership” label (feed/Reels/carousels; Stories return 400). Requires Facebook Login connection.
brandedContentSponsors (array, max 2) — tag sponsor brands by username (optional @) or numeric IG user ID; implies isPaidPartnership.
commentsEnabled (boolean, default true) — when false, turns off comments after publish (best-effort; Stories ignored).
locationId (string digits) — tags the post location using a Facebook Page ID with location data (feed/Reels/carousels; Stories rejected with 400).

View documentation
Meta ads created via POST /v1/ads/create now support Multiple Text Options (Advantage+ Flexible Format) using new top-level fields bodies, headlines, and optional descriptions.

This lets you send 1–5 variations of primary text/headlines (and optionally descriptions) and have Meta optimize delivery across them, without using full dynamicCreative.

Use:
bodies (1–5)
headlines (1–5)
descriptions (0–5)

Requires imageUrl or video, plus linkUrl and callToAction. When set, top-level body and headline are used for preview text (object_story_spec), and this mode is mutually exclusive with dynamicCreative, placementAssets, carouselCards, and creatives[].

View documentation
🔥1
WhatsApp Flows now supports managing the Flows endpoint encryption key via new endpoints.

You can check whether a business RSA public key is registered (and retrieve it) and register/replace the key used for endpoint-backed flows (flow_action: data_exchange).

New endpoints:
GET /v1/whatsapp/flows/encryption-key (query accountId) returns publicKey, registered, signatureStatus (VALID | MISMATCH)
POST /v1/whatsapp/flows/encryption-key body: accountId, businessPublicKey (PEM)

Note: only one key is active per phone number; replacing the key requires your flow endpoint to serve the matching private key or data_exchange flows will fail at runtime.

View documentation