Zernio | Developer News
694 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
POST /v1/ads/create now supports safe retries via an optional Idempotency-Key header.

This endpoint isn’t idempotent at the ad-platform level (a blind retry can create duplicate campaigns/ad sets/ads). With Idempotency-Key, retries return the original stored response instead of creating duplicates.

Use Idempotency-Key (e.g. a UUID):
• Same key + same body → replays the original response (response header Idempotent-Replayed: true)
• Same key + different body → 422
• Key still processing → 409 (retry after backoff)

Keys are scoped to your credential and expire after 24h.

View documentation
1
Meta ads created via POST /v1/ads/create now support raw Meta-native targeting via rawTargeting.

This lets you pass a Meta targeting spec through verbatim (snake_case) to clone an existing campaign’s targeting exactly, including advanced fields not covered by the camelCase targeting fields.

Use rawTargeting (Meta only) and do not combine it with:
• camelCase targeting fields (e.g. countries, regions, cities, interests, ageMin, ...)
audienceId
savedTargetingId

Sending both will return 422. If targeting EU users, also provide dsaBeneficiary / dsaPayor separately (not inside rawTargeting).

View documentation
1
You can now rename Meta ads objects via update endpoints.

This adds name updates without recreating entities (Meta only; other platforms return 501).

PUT /v1/ads/campaigns/{campaignId} now accepts name (max 255)
PUT /v1/ads/ad-sets/{adSetId} now accepts name (max 255)
PUT /v1/ads/{adId} now supports name (max 255) and propagates it to Meta; non-Meta returns 501

Ad creation on Meta also adds more naming control:
POST /v1/ads/create now accepts campaignName and adSetName (max 255)
• In Meta multi-creative mode, creatives[].name sets the per-ad name (max 255)

View documentation
1
New Inbox Analytics endpoints are available to query messaging volume, response times, and conversation-level stats (max date range: 365 days).

New endpoints:
GET /v1/analytics/inbox/volume — volume + KPIs + per-platform split (key params: fromDate, toDate, profileId, platform, accountId, source)
GET /v1/analytics/inbox/heatmap — day-of-week × hour heatmap (key params: fromDate, toDate, action=message.received|message.sent|message.read|all)
GET /v1/analytics/inbox/source-breakdown — breakdown by metadata.source
GET /v1/analytics/inbox/response-time — time-to-first-response summary + histogram
GET /v1/analytics/inbox/top-accounts — top accounts by inbox volume (key param: limit 1–50)
GET /v1/analytics/inbox/conversations — paginated conversation analytics (key params: limit, page, sortBy=lastMessageAt|firstMessageAt|totalMessages|received|sent|read|failed, order=asc|desc)
GET /v1/analytics/inbox/conversations/{conversationId} — single-conversation analytics ({conversationId} accepts Mongo _id or platformConversationId)

Webhook event enums were expanded in POST /v1/webhooks/settings, PUT /v1/webhooks/settings, and the Webhook schema to include:
whatsapp.number.suspended
whatsapp.number.reactivated
whatsapp.number.released

View documentation
5
POST /v1/ads/create now supports Meta-specific single-ad naming and ad-level tracking.

You can explicitly set the created ad’s name (instead of inheriting name), and attach pixel measurement + URL tags regardless of optimization goal.

New fields:
adName (Meta only) — overrides the default ad name (default was name)
tracking.pixelId (Meta only) — attaches pixel measurement via ad tracking_specs
tracking.urlTags (Meta only) — sets ad url_tags as [{ key, value }]

View documentation
2
Webhooks now support external post events for posts created/updated/deleted directly on the platform (not published via Zernio).

Subscribe by including these in events when calling POST /v1/webhooks/settings or PUT /v1/webhooks/settings:
post.external.created
post.external.updated
post.external.deleted

Payload uses WebhookPayloadExternalPost with post = ExternalPostWebhookPost (includes post.id = platform-native ID, post.source = external; on post.external.deleted, post.deletedAt is populated). Events are sync-detected (~hourly), not real-time.

View documentation
2
GET /v1/comment-automations now returns stats.trackedSends for each automation.

Use trackedSends as the CTR denominator for tracked links (divide stats.linkClicks by stats.trackedSends, not stats.dmsSent). It may lag dmsSent for automations that predate click tracking.

New field:
stats.trackedSends - DMs sent with a trackable (wrapped) link

View documentation
2🔥1
Google Ads now supports conversion adjustments via POST /v1/ads/conversions/adjustments.

You can retract, restate value, or enhance an already-uploaded conversion (Google only; other platforms return 405). Partial failure is supported (check adjustmentsFailed / failures[]).

Send:
accountId (must be a googleads account)
destinationId (conversion action resource name)
adjustments[] with adjustmentType = RETRACTION | RESTATEMENT | ENHANCEMENT

Per adjustment:
• Identify the original conversion with orderId (required for ENHANCEMENT) or gclid + conversionTime
adjustmentTime (unix seconds)
restatementValue + currency (for RESTATEMENT)
user.email/user.phone (+ optional userAgent) for ENHANCEMENT

Also: Meta standalone ad creation adds goal = lead_conversion on POST /v1/ads/create (and Ad.goal) for website pixel lead optimization (distinct from lead_generation instant forms).

View documentation
1
Meta ads created via POST /v1/ads/create now support explicitly setting the ad set optimization goal via optimizationGoal.

This lets you override the default optimization derived from goal (e.g. traffic defaulting to LINK_CLICKS) and pass a Meta-native optimization_goal value directly; Meta will validate and reject incompatible combinations.

Use optimizationGoal (Meta only), e.g. LANDING_PAGE_VIEWS, LINK_CLICKS, REACH, IMPRESSIONS, OFFSITE_CONVERSIONS, THRUPLAY, LEAD_GENERATION.

View documentation
3
Meta ads tracking-tag updates are now simpler on PATCH /v1/ads/{adId}/tracking-tags: you can send urlTags alone and Zernio will preserve the existing creative verbatim while rebuilding/repointing the ad.

This removes the previous requirement to provide the full Meta creative payload just to add/update click-URL tags. For creatives where Meta strips object_story_spec (e.g. share/page-post/dark/asset_feed), you may still get 422 and need to include creative explicitly.

Key fields:
urlTags (Meta)
creative (Meta, optional; required only when preservation isn’t possible)
trackingUrlTemplate, finalUrlSuffix (Google)
dynamicValueParameters, customValueParameters (LinkedIn)

View documentation
❤‍🔥1
Meta Lead Gen ads created via POST /v1/ads/create now support per-placement creative using placementAssets.

You can pin different image/video assets to placement groups (e.g. Stories/Reels vs Feed) while still attaching a Lead Gen form via leadGenFormId.

Use:
goal=lead_generation
leadGenFormId
placementAssets with defaultImageUrl or defaultVideoUrl + rules[].placements

Note: dynamicCreative is still not compatible with goal=lead_generation.

View documentation
1
GET /v1/accounts now supports filtering by connection status via the new status query param.

This lets you fetch only healthy accounts or only accounts that need reconnection (matching the dashboard reconnection check). Pagination totals reflect the filtered result set when used with page/limit.

Use status:
connected
disconnected

View documentation
X (Twitter) posts now support additional labeling and media safety controls via platformSpecificData.

You can label posts as paid promotions or AI-generated media, and mark attached media with sensitive-content warnings.

New fields in TwitterPlatformData:
paidPartnership (boolean)
madeWithAi (boolean)
sensitiveMedia with adultContent, graphicViolence, other (booleans; requires media)

Reddit posts now support additional post options via platformSpecificData.

New fields in RedditPlatformData:
flairText (string; ignored if flairId is set)
nsfw (boolean)
spoiler (boolean)
sendreplies (boolean)

View documentation
1
Meta Lead Gen ads created via POST /v1/ads/create now support Dynamic Creative using dynamicCreative together with goal=lead_generation.

You can run Meta’s multi-text / multi-asset optimization ("Multiple Text Options") on instant-form lead ads; Zernio will create the required Dynamic Creative ad set automatically and attach the form for you.

Use:
goal=lead_generation
leadGenFormId=<form_id>
dynamicCreative.imageUrls (send 1+; send a single entry if you only want multi-text)
• Optional variations: dynamicCreative.titles, dynamicCreative.bodies, dynamicCreative.descriptions, dynamicCreative.linkUrls
• Required: dynamicCreative.callToActionTypes (e.g. LEARN_MORE, SIGN_UP, DOWNLOAD, REGISTER, BUY_NOW)

View documentation
1
WhatsApp template buttons updated: WhatsAppTemplateButton now supports a new button type value copy_code, and text is no longer required for all button types.

This enables WhatsApp marketing “copy code” buttons where the label is fixed by WhatsApp, and the coupon code is provided via example.

Key changes:
type enum now includes: quick_reply, url, phone_number, otp, copy_code, flow, mpm, catalog
text: required for all types except copy_code
example is now string or string[] (URL buttons: string[]; copy_code: coupon code as string)

View documentation
1🔥1
Invite token creation now supports assigning an org role and issuing read-only invites via POST /v1/invite/tokens.

Use role to grant org-level permissions (member | billing_admin, default member), and readOnly to restrict the invitee to view-only access within their scope (default false).

View documentation
🔥1
Webhooks now support a new WhatsApp number event: whatsapp.number.action_required.

Subscribe to this event to be notified when a WhatsApp number needs additional action to proceed.

Add it to events when creating/updating a webhook via POST /v1/webhooks/settings or PUT /v1/webhooks/settings:
events: ["whatsapp.number.action_required", ...]

View documentation
5
Invite creation now supports a dedicated read-only role via role on POST /v1/invite/tokens.

Use role to control access level:
member
billing_admin
viewer - read-only (no publish/edit/delete/connect)

The readOnly field is now deprecated. If readOnly=true, the invite is created with role=viewer (and it can’t be combined with role=billing_admin).

View documentation
1
POST /v1/ads/create now supports Meta link descriptions via a new description field.

This lets you set the secondary link text on Facebook/Instagram ads instead of relying on Meta scraping OpenGraph data.

Use:
description (Meta only) — applies to legacy + attach + placementAssets
creatives[].description (Meta multi-creative) — per-ad override; falls back to top-level description

Also clarified for Meta lead ads: when using adSetId (attach shape) into a lead ad set, you must pass leadGenFormId on every attached ad.

View documentation
1
Meta video ads created via POST /v1/ads/create no longer require a thumbnail.

You can now omit video.thumbnailUrl and Zernio/Meta will auto-generate the poster frame using Meta’s preferred video thumbnail (same candidates as Ads Manager). Provide it only if you need an exact poster frame.

Applies to:
• Top-level video (legacy + attach shapes): video.url required, video.thumbnailUrl optional
creatives[].video (Meta multi-creative): video.url required, video.thumbnailUrl optional

View documentation
1
New endpoint: GET /v1/accounts/{accountId}/gmb-attribute-metadata.

You can now fetch Google Business Profile attribute metadata (valid attribute names, value types, and allowed enum values) before reading/writing via gmb-attributes.

Query modes (mutually exclusive):
• Location mode: locationId (or omit to use the account’s stored selectedLocationId)
• Category mode: categoryName (must start with categories/) + regionCode (optional languageCode)

Pagination: pageSize (1–200) and pageToken.

Response includes attributeMetadata[] with parent, valueType (e.g. BOOL, ENUM, URL, REPEATED_ENUM), displayName, repeatable, deprecated, and valueMetadata[] (enum options), plus nextPageToken when more results are available.

View documentation
2