Zernio | Developer News
702 subscribers
1 photo
1 video
497 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
GET /v1/ads/{adId}/comments now returns additional Instagram metadata in meta for Instagram-placed ads.

This makes it easier to identify the boosted IG post and which connected Instagram account was used to read comments (useful for follow-up reply/hide actions via /v1/inbox/comments).

New meta fields (Instagram-only):
instagramUserId
instagramPermalink
instagramAccountId

Also clarified: for Instagram-placed ads, if no connected Instagram account on the profile can read the ad’s media, the endpoint returns 422 with code ads_connection_required.

View documentation
1
Meta ads (boosted/dark posts) are now included in GET /v1/inbox/comments for users with the Ads add-on (Metronome plans always qualify).

Ad rows are flagged so you can route comment fetching to the ads comments thread.

Use platform:
metaads - ads only
facebook/instagram - organic only
• omit platform - both

New fields on inbox rows: isAd (boolean), adId (string). For ad rows, fetch the thread via GET /v1/ads/{adId}/comments.

GET /v1/inbox/comments/{postId} now returns meta.adComments when a boosted post has no organic comments (includes adId and adCommentsUrl), and may return 400 with code USE_AD_COMMENTS_ENDPOINT when postId is an ad creative/ad ID.

GET /v1/ads adds filters to map Business Manager IDs back to Zernio ads: platformAdId, effectiveObjectStoryId, effectiveInstagramMediaId.

View documentation
🔥3
POST /v1/ads/create now supports creating LinkedIn standalone ads.

This creates a LinkedIn Single Image Ad backed by a Direct Sponsored Content ("dark post") authored by a Company Page, with supported goals engagement, traffic, awareness (and traffic requires linkUrl).

Key request fields for LinkedIn:
organizationId (Company Page org ID or urn:li:organization:N; required unless it can be inferred)
headline (now required for LinkedIn; max 400)
body (used as LinkedIn post commentary)
imageUrl (required for LinkedIn)
linkUrl (required for goal=traffic)
longHeadline (optional secondary description on LinkedIn traffic ads)

Also updated:
callToAction enum expanded with REGISTER, JOIN, ATTEND, REQUEST_DEMO, VIEW_QUOTE, APPLY, SEE_MORE, BUY_NOW
• Meta-only: new attributionSpec to control conversion attribution windows (CLICK_THROUGH/VIEW_THROUGH/ENGAGED_VIDEO_VIEW with windowDays 1/7/28).

View documentation
3
TikTok conversion ads via POST /v1/ads/create now support/require TikTok pixel optimization settings through promotedObject.

For TikTok, goal=conversions uses promotedObject to configure the ad group’s pixel + optimization event (or inherit them by using adSetId).

Set:
goal: conversions
promotedObject.pixelId (required for TikTok conversions)
promotedObject.customEventType (optional TikTok optimization_event code, e.g. ON_WEB_ORDER, INITIATE_ORDER, ON_WEB_CART, ON_WEB_REGISTER, FORM, ON_WEB_DETAIL)

View documentation
1
New endpoint: PATCH /v1/accounts/{accountId} to move a connected account to a different profile owned by the same user.

Send profileId in the JSON body to set the target profile.

Request body:
profileId (required)

Auth/scope note: for profile-restricted API keys, both the account’s current profile and the target profileId must be allowed, otherwise you’ll get 403.

Responses: 200 returns message and profileId; errors include 400, 401, 403, 404.

View documentation
🔥1
New endpoint GET /v1/ads/timeline returns a daily time series of aggregate ad metrics for a social account (one row per calendar day), useful for spend/conversions charts without calling /v1/ads/tree per day.

Key params:
accountId (required)
fromDate, toDate (YYYY-MM-DD; defaults to last 90 days; max 730 days)
platform (optional): facebook, instagram, tiktok, linkedin, pinterest, google, twitter

Response: rows[] with per-day metrics like spend, impressions, clicks, ctr, conversions, actions, purchaseValue, roas. Returns empty rows if no activity. 403 if Ads add-on is required.

View documentation
🔥1
GET /v1/ads/timeline now supports filtering by a specific platform ad account via adAccountId.

Use this when a single Zernio connection wraps multiple platform ad accounts and you want the timeline chart for just one (e.g. Meta act_…, TikTok advertiser ID).

New query param:
adAccountId (optional)

Note: rows ingested before 2026-05-13 may not include this dimension yet; the recurring 7-day re-sync will repopulate them over time.

View documentation
🔥1
Webhooks now support ad.status_changed.

Subscribe to get notified when a Meta ads object (campaign/ad set/ad) changes status or enters WITH_ISSUES.

Add ad.status_changed to events when creating/updating a webhook via POST /v1/webhooks/settings or PUT /v1/webhooks/settings.

Payload highlights:
event: ad.status_changed
adObject.level: CAMPAIGN | AD_SET | AD
status.raw: platform-native status (e.g. ACTIVE, PAUSED, WITH_ISSUES)
error: optional diagnostics on most WITH_ISSUES events

Also, GET /v1/ads/{adId}/analytics now returns ad.currency (ISO 4217) so you can interpret money values in summary and daily.

View documentation
2👍1
Google Business reviews now support owner replies via new endpoints: POST /v1/accounts/{accountId}/gmb-reviews/{reviewId}/reply and DELETE /v1/accounts/{accountId}/gmb-reviews/{reviewId}/reply.

Use comment to post/update a reply (calling POST again overwrites the previous reply). Deleting removes only the reply, not the review.

Reply body: { "comment": "..." }

POST /v1/ads/ctwa now supports creating multiple CTWA ads under one campaign/ad set by sending a non-empty creatives[] array (each creative has its own headline, body, and exactly one of imageUrl/video). Single-creative requests still work.

New optional bidding controls on CTWA: bidStrategy (LOWEST_COST_WITHOUT_CAP, LOWEST_COST_WITH_BID_CAP, COST_CAP, LOWEST_COST_WITH_MIN_ROAS) plus bidAmount (required for bid-cap/cost-cap) and roasAverageFloor (required for min-ROAS).

CTWA create response is now a tagged union via adType: single or multi.

View documentation
1🔥1
Webhooks now support WhatsApp template status updates via the new event whatsapp.template.status_updated.

This fires when Meta completes a (re)review of a template on a connected WABA, so you can react to approvals/rejections and other status transitions.

Subscribe by adding whatsapp.template.status_updated to Webhook.events.

Payload: WebhookPayloadWhatsAppTemplateStatusUpdated with template.statusAPPROVED, REJECTED, PENDING, PAUSED, DISABLED, IN_APPEAL, PENDING_DELETION and template.reason (e.g. "NONE" on approval).

View documentation
1
GET /v1/ads/campaigns now supports filtering aggregated campaign metrics by a date range.

Use fromDate and toDate (YYYY-MM-DD, inclusive) to control the metrics window returned for each campaign.

New query params:
fromDate - start date (defaults to 90 days ago when both date params are omitted)
toDate - end date (defaults to today; max 730-day range)

View documentation
🔥1
Webhooks now support per-platform terminal post events: post.platform.published and post.platform.failed.

These fire once per platform target inside a post when that specific platform reaches a terminal state (published or permanent failure), which helps track multi-platform posts more precisely.

Subscribe via events on POST /v1/webhooks/settings or PUT /v1/webhooks/settings:
post.platform.published
post.platform.failed

A new webhook event is also available:
whatsapp.template.status_updated

View documentation
🔥1
{adId} in GET /v1/ads/{adId} and GET /v1/ads/{adId}/comments now accepts multiple identifier types.

You can call these endpoints using the Zernio internal _id (24-char hex), Meta numeric platformAdId (from comment.received as comment.ad.id), or the creative’s effective_object_story_id / effective_instagram_media_id. Any of these resolves to the same ad, so you don’t need a translation step.

View documentation
🔥2
POST /v1/posts now supports request idempotency via x-request-id.

If you send the same x-request-id again within ~5 minutes (including while the first request is in-flight), the API treats it as a retry and returns HTTP 200 with the original post in existingPost (no duplicate post is created).

Use x-request-id (UUID) per logical create call. If you omit it, each request is treated as new.

Duplicate protection still applies separately: identical content to the same (platform, accountId) within 24h returns HTTP 409 with details.accountId, details.platform, details.existingPostId.

View documentation
🔥1
Facebook now supports multi-link carousel posts via facebookSettings on POST /v1/posts.

This lets you publish a 2–5 card carousel where each image has its own click-through link (and optional headline/description).

Set facebookSettings.carouselCards (2–5 items) with:
link (required)
name (optional)
description (optional)

Optionally set facebookSettings.carouselLink for the carousel end-card destination.

Constraints: mediaItems must be images only, and must match carouselCards length/order. Mutually exclusive with facebookSettings.contentType = story or reel.

View documentation
🔥1
GET /v1/ads/tree now supports campaign-level sorting via a new sort query parameter.

This lets you control the order of returned campaigns (by recency or aggregated spend) while keeping pagination at the campaign level.

Use sort:
newest (default)
oldest
spend_desc
spend_asc

View documentation
2
GET /v1/ads/tree now supports campaign-level sorting via sort.

Use it to control the order of returned campaigns (by newest/oldest activity or by spend in the requested date range).

Set sort to:
newest (default)
oldest
spend_desc
spend_asc

View documentation
2🔥1
WhatsApp is now supported as a platform for connecting accounts and checking account health.

You can now use whatsapp with:
GET /v1/connect/{platform} (path param platform enum now includes whatsapp)
GET /v1/accounts/health (query param platform enum now includes whatsapp)

View documentation
2
Instagram now supports Stories retrieval + insights.

You can list currently-active stories and fetch metrics for a specific story, including a clear indicator of whether insights are live, cached, or unavailable.

New endpoints:
GET /v1/accounts/{accountId}/instagram/stories
Returns active stories (24h window). Key fields: id, mediaType, mediaUrl (nullable), permalink, thumbnailUrl, timestamp
GET /v1/accounts/{accountId}/instagram/stories/{storyId}/insights
Returns data.source = live | cached | unavailable and data.metrics including views, reach, replies, shares, navigation, tapsForward, tapsBack, exits, swipesForward, profileVisits, follows, reposts, totalInteractions.

View documentation
4🔥1
GET /v1/broadcasts/{broadcastId}/recipients now returns errorCode per recipient.

This provides the Meta WhatsApp error code to help you classify and handle delivery failures (only populated when status=failed).

New field: errorCode (integer, nullable) — e.g. 131049 (antispam), 131021 (invalid phone), 131026 (re-engagement required).

View documentation
3
GET /v1/ads/audiences now supports fetching custom audiences for LinkedIn and X (Twitter) ad accounts.

Use the platform query param with one of:
facebook, instagram, googleads, tiktok, tiktokads, pinterest, linkedin, linkedinads, twitter, xads

View documentation
🔥1