YouTube analytics endpoints now support returning provisional (not-yet-finalized) days when you set an explicit
By default,
Applies to:
•
•
•
New response field:
•
View documentation
endDate up to today.By default,
endDate still resolves to the newest fully finalized day (~3-day delay). If you request into the delay window, the response indicates which days may still change.Applies to:
•
GET /v1/analytics/youtube/daily-views•
GET /v1/analytics/youtube/video-retention•
GET /v1/analytics/youtube/demographicsNew response field:
•
provisionalSince — first date in the returned range whose numbers are provisional and may be revised by YouTube.View documentation
❤2
Zernio Ads now supports OpenAI Ads (ChatGPT Ads), including connect, create/manage, reporting, and conversions.
Connect an OpenAI Ads account via
Ads endpoints now accept
•
• Campaign/ad set status updates:
Creating ads:
•
• Required creative fields:
• Budget:
Conversions:
• Use
• If no pixel exists yet, create one via
Note:
View documentation
Connect an OpenAI Ads account via
POST /v1/connect/openai-ads/credentials with apiKey and profileId (requires Ads add-on).Ads endpoints now accept
platform=openai:•
GET /v1/ads, GET /v1/ads/campaigns, GET /v1/ads/tree, GET /v1/ads/timeline• Campaign/ad set status updates:
PUT /v1/ads/campaigns/{campaignId}/status, POST /v1/ads/campaigns/bulk-status, PUT /v1/ads/ad-sets/{adSetId}, PUT /v1/ads/ad-sets/{adSetId}/statusCreating ads:
POST /v1/ads/create supports OpenAI Ads with:•
goal: traffic | awareness | conversions• Required creative fields:
headline, body, imageUrl, linkUrl• Budget:
budgetType must be lifetime (sending daily returns 422) and requires endDateConversions:
POST /v1/ads/conversions now supports accountId platform openaiads.• Use
GET /v1/accounts/{accountId}/conversion-destinations to get the OpenAI pixel destinationId (pixel wire id)• If no pixel exists yet, create one via
POST /v1/accounts/{accountId}/tracking-tags (OpenAI Ads may return 422 if pixel management isn’t enabled)Note:
PUT /v1/ads/{adId} supports OpenAI Ads for status + budget only (no targeting/creative updates). DELETE /v1/ads/{adId} archives OpenAI Ads (no platform delete API).View documentation
🔥3👏2
PUT /v1/ads/ad-sets/{adSetId} now supports updating bid strategy for platform=openai.You can set OpenAI ad group bidding via
bidStrategy + bidAmount; bidAmount is converted to micros (× 1,000,000).Use
bidStrategy:•
LOWEST_COST_WITH_BID_CAP (requires bidAmount)•
COST_CAP (requires bidAmount)LOWEST_COST_WITH_MIN_ROAS is not supported on OpenAI and will return 422.View documentation
KYC reuse selection now supports a stable option identifier via
This makes selecting which prior verification to reuse unambiguous (a phone number may label multiple verifications) and lets you know whether reuse activates in minutes or still queues for carrier review.
Use on submit:
•
•
Returned on form spec:
•
View documentation
reusable.options[].id, and KYC reuse options now include instant to indicate activation speed.This makes selecting which prior verification to reuse unambiguous (a phone number may label multiple verifications) and lets you know whether reuse activates in minutes or still queues for carrier review.
Use on submit:
•
POST /v1/phone-numbers/kyc: pass reuseOptionId (preferred)•
reuseFrom is now a legacy fallback and may be ambiguousReturned on form spec:
•
GET /v1/phone-numbers/kyc (and the deprecated WhatsApp alias): reusable.options[] now includes id and instantView documentation
👏1
You can now view KYC documents on file via
This streams the stored verification document inline as
KYC spec responses now include
•
•
Use that
View documentation
GET /v1/phone-numbers/kyc/document/{documentId}.This streams the stored verification document inline as
application/pdf, so users can confirm what’s on file before reusing a verification. Access is auth-scoped (returns 404 if the documentId isn’t referenced by one of your numbers).KYC spec responses now include
documentId on document rows:•
GET /v1/phone-numbers/kyc → reusable.options[].details[].documentId•
GET /v1/whatsapp/phone-numbers/kyc → reusable.options[].details[].documentIdUse that
documentId as the {documentId} path parameter when fetching the PDF.View documentation
❤1
New endpoint:
Use it when the reviewer asks for info the structured remediation form can’t express; posting a reply can move the number back to
Request body:
•
•
Response
•
•
Errors:
View documentation
POST /v1/phone-numbers/{id}/remediate/reply lets you reply to a regulatory reviewer on a phone number awaiting remediation, including optional file attachments.Use it when the reviewer asks for info the structured remediation form can’t express; posting a reply can move the number back to
in review (comment-style asks). Requires text or at least one attachments item.Request body:
•
text (string, max 2000)•
attachments (array, max 5) items: { filename, base64 } (PDF/JPG/PNG/WEBP, max 10MB each)Response
200:•
posted (boolean)•
attachments (integer uploaded)Errors:
400, 401, 404, 502 (retry).View documentation
👍1
GET /v1/profiles now supports exact-name filtering and pagination, and the default sort order is now default-first (then creation date).Use
name (exact match) to find a profile by name, and limit/skip to paginate. When limit or skip is provided, the response may include total, skip, and limit.New query params:
name, limit (1..1000), skip (>=0)POST /v1/profiles now supports idempotent retries via Idempotency-Key (header).With
Idempotency-Key: same key + same body replays the original 201; same key + different body returns 422; key still processing returns 409. Duplicate name conflicts (409) now include details.existingProfileId.View documentation
❤1
New endpoint:
You can send a reviewer message and/or submit corrected requirement data in a single call; submitting corrections re-submits the number back to review, while message-only posts to the reviewer thread.
Request body supports:
•
•
•
•
•
Response includes
View documentation
POST /v1/phone-numbers/{id}/remediate/respond lets you respond to a regulatory reviewer for a phone number awaiting remediation.You can send a reviewer message and/or submit corrected requirement data in a single call; submitting corrections re-submits the number back to review, while message-only posts to the reviewer thread.
Request body supports:
•
message (max 2000)•
documents[] keyed by requirementId (use base64 or documentId)•
address (corrected address record)•
entityType: individual | business | null•
attachments[] (max 5; each filename + base64)Response includes
status: resubmitted | replied, plus posted, phoneNumber, and siblingsResubmitted.View documentation
🔥1
message.sent webhook payload now includes message.source for WhatsApp.This lets you tell whether a sent message came from the WhatsApp Business phone app on a Coexistence number vs being sent through Zernio (dashboard/API/broadcasts).
New field:
message.source = whatsapp_business_app | cloud_apiOnly present for WhatsApp; absent on non-WhatsApp platforms.
View documentation
👏3
WhatsApp template endpoints can now return
This makes Meta-side failures explicit so you can distinguish platform outages/rejections from Zernio validation/auth errors.
Applies to:
•
•
•
Also added ad review state support via
View documentation
502 when Meta rejects the request or is unreachable.This makes Meta-side failures explicit so you can distinguish platform outages/rejections from Zernio validation/auth errors.
Applies to:
•
GET /v1/whatsapp/templates/{templateName}•
PATCH /v1/whatsapp/templates/{templateName}•
DELETE /v1/whatsapp/templates/{templateName}Also added ad review state support via
reviewStatus (schema AdReviewStatus: in_review, approved, rejected, with_issues) and Meta-only configuredStatus on Ad to separate delivery status from the ad’s on/off toggle.View documentation
👍2
New endpoint
Keywords are populated by the periodic ads discovery sweep (~every 3 hours per account). Campaign-level negative keywords aren’t included (ad-group-level only).
Filter with:
•
•
•
•
•
•
Response returns
View documentation
GET /v1/ads/keywords is available to list Google Search keyword criteria (positive and negative) synced from connected Google Ads accounts (one row per ad-group keyword).Keywords are populated by the periodic ads discovery sweep (~every 3 hours per account). Campaign-level negative keywords aren’t included (ad-group-level only).
Filter with:
•
accountId, adAccountId (Google customer ID), profileId•
campaignId, adSetId (Google ad group)•
status: active | paused•
matchType: exact | phrase | broad | unknown•
negative: true (negative only) | false (positive only)•
search (substring match), plus pagination via page/limit (1–500)Response returns
keywords with fields like keyword, matchType, status, negative, and syncedAt, plus pagination.View documentation
POST /v1/tools/validate/post now accepts accountId per platform to validate against account-specific limits.For
platform=twitter, providing platforms[].accountId lets validation apply the correct character limit (280 vs 25000 for X Premium). Missing/invalid/foreign IDs fall back to 280 and won’t error.Use:
•
platforms[].platform (enum: twitter, instagram, tiktok, youtube, facebook, linkedin, bluesky, threads, reddit, pinterest, telegram, snapchat, googlebusiness, discord)•
platforms[].accountIdView documentation
GET /v1/accounts now enforces stricter pagination and query validation.If you use server-side pagination, you must send
page and limit together; sending only one now returns 400. Out-of-range page/limit values are also rejected with 400 (instead of being silently clamped).Key params:
•
page (1-based) + limit (1–100) must be supplied together•
profileId must be a valid ObjectIdView documentation
KYC submission now enforces stricter validation when requesting multiple numbers with an
If you pass
Applies to:
•
•
Key params:
View documentation
areaCode.If you pass
areaCode and request quantity above that area’s live inventory, the request is rejected with 400 (instead of best-effort skipping).Applies to:
•
POST /v1/phone-numbers/kyc•
POST /v1/whatsapp/phone-numbers/kycKey params:
areaCode, quantity (1–5).View documentation
New endpoint
Use it with:
•
•
•
•
•
•
•
To reply to a found tweet, set
Rate limit: 300 requests per 15 minutes per connected account.
View documentation
GET /v1/twitter/search lets you search public tweets from the last 7 days using an X query (passed through unchanged) to discover tweets to reply to.Use it with:
•
accountId (required)•
query (required, 1–512 chars)•
limit (10–100, default 10)•
cursor (pagination)•
sinceId / untilId (numeric tweet IDs)•
startTime / endTime (ISO 8601 UTC, within last 7 days)•
sortOrder: recency | relevancy (default recency)To reply to a found tweet, set
platformSpecificData.replyToTweetId to the returned tweets[].id when creating a post.Rate limit: 300 requests per 15 minutes per connected account.
View documentation
Webhook limits have increased: you can now configure up to 50 webhooks per user (was 10).
This lets you split event subscriptions across more endpoints/environments without hitting the previous cap.
Applies to:
•
•
View documentation
This lets you split event subscriptions across more endpoints/environments without hitting the previous cap.
Applies to:
•
GET /v1/webhooks/settings (list up to 50)•
POST /v1/webhooks/settings (create up to 50; 400 if max reached)View documentation
SMS carrier registrations now support a preflight dry-run and change-request replies.
Use
Request:
Response:
Use
Also added to
View documentation
Use
POST /v1/sms/registrations/preflight to validate and preview the exact 10DLC brand/campaign payloads that would be stored, without creating a registration. It returns compliance findings (including AI review when available) so you can fix issues before submitting.Request:
registrationType (standard_10dlc | sole_prop_10dlc), brand, campaign, optional phoneNumbers, optional messagingBrandNameResponse:
composed, advisories (severity block | warn), verdict (pass | warn | fail | unreviewed), aiUnavailableUse
POST /v1/sms/registrations/{id}/respond to reply to a reviewer change request (when a registration is in changes_requested) with a note, files (hosted URLs), or both—without resubmitting the full registration. On success, status returns to requested.Also added to
POST /v1/sms/registrations: messagingBrandName (2–60 chars) to brand samples/auto-replies when it differs from the legal brand.displayName.View documentation
Meta conversion goals on
This lets you run
Use
•
•
View documentation
POST /v1/ads/create now support optimizing against a Custom Conversion.This lets you run
goal conversions or lead_conversion without providing a standard event type, by pointing the ad set at an existing Custom Conversion.Use
promotedObject.customConversionId (instead of promotedObject.customEventType) for:•
goal=conversions•
goal=lead_conversionView documentation
Instagram is now supported for typing indicators via
Calling this endpoint can now show
Request:
Response:
The endpoint may now also return
View documentation
POST /v1/inbox/conversations/{conversationId}/typing.Calling this endpoint can now show
typing... to the Instagram recipient (works for both Instagram Login and Facebook Login accounts; recipient must be signed in to Instagram to see it).Request:
{ "accountId": "..." }Response:
{ "success": true|false } where success indicates whether the typing indicator was actually sent (false on unsupported platforms or if the platform call failed).The endpoint may now also return
400 (BadRequest) in addition to existing responses.View documentation
👏1
Webhooks now support
This event fires when Zernio’s background sync detects a platform post (published via Zernio) was later deleted on the platform (poll-driven ~hourly, not real-time).
Subscribe by including
In
•
•
• New field on delete events:
View documentation
post.platform.deleted in events for POST /v1/webhooks/settings and PUT /v1/webhooks/settings.This event fires when Zernio’s background sync detects a platform post (published via Zernio) was later deleted on the platform (poll-driven ~hourly, not real-time).
Subscribe by including
post.platform.deleted in events.In
WebhookPayloadPostPlatform:•
event: post.platform.published | post.platform.failed | post.platform.deleted | post.tiktok.url_resolved•
platform.status: published | failed | deleted• New field on delete events:
platform.deletedAt (ISO 8601)View documentation
POST /v1/sms/registrations no longer requires phoneNumbers in the request body.For 10DLC registrations, if
phoneNumbers is omitted or an empty array, it now defaults to your active SMS-enabled US local numbers that aren’t already covered by another registration.Key request fields:
•
registrationType: standard_10dlc | sole_prop_10dlc | toll_free•
phoneNumbers: optional (new defaulting behavior for 10DLC)View documentation