Shipped since Friday: 23 API updates
• Facebook: Build Page management and insights:
• Inbox: Triage mentions and label Messenger threads:
• Ads: Control tracking and objectives plus detect partial TikTok reports:
• Connect & Accounts: Ship safer connects and listings: Instagram QR handoff via
• Webhooks & Admin: Automate ad-rule alerts and team access: subscribe to
• LinkedIn @mentions can now be written directly in post text and resolved automatically when creating or updating posts.
• Facebook: Build Page management and insights:
facebook-tagged-posts, facebook-visitor-posts, facebook-page-info (GET/PATCH), plus pin/unpin via POST /v1/posts/{postId}/pin.• Inbox: Triage mentions and label Messenger threads:
GET /v1/inbox/mentions supports platform=facebook, and GET/POST/DELETE /v1/inbox/labels plus conversation label endpoints.• Ads: Control tracking and objectives plus detect partial TikTok reports:
tracking.zernioTag on POST /v1/ads/create, metaObjective on POST /v1/ads/boost, missingRows on TikTok materials.• Connect & Accounts: Ship safer connects and listings: Instagram QR handoff via
handoff=true, GA4 headless picker via pendingDataToken, and cursor paging on GET /v1/accounts + /follower-stats.• Webhooks & Admin: Automate ad-rule alerts and team access: subscribe to
ad_rule.triggered, inspect runs[].evaluation.notification, and restrict invites via disabledResourceGroups on POST /v1/invite/tokens.• LinkedIn @mentions can now be written directly in post text and resolved automatically when creating or updating posts.
🔥2
Zernio now supports Google/Microsoft Email, Calendar, and Files via new API surfaces.
Connect mailboxes/drives with
New endpoint families:
• Email: list threads/messages, read bodies, send/reply, move/mark, download attachments (
• Calendar: list calendars/events, create/update/delete, RSVP, free-busy, availability (
• Files: list/search, upload, create folders, download, share links, Google Picker sessions (
Operational additions:
•
• Webhooks add events:
• Microsoft tenants that require admin approval can use
View documentation
Connect mailboxes/drives with
GET /v1/connect/{platform} where platform now includes google and microsoft (and scopes is required for these platforms: email, calendar, files, contacts).New endpoint families:
• Email: list threads/messages, read bodies, send/reply, move/mark, download attachments (
/v1/email/*)• Calendar: list calendars/events, create/update/delete, RSVP, free-busy, availability (
/v1/calendar/*)• Files: list/search, upload, create folders, download, share links, Google Picker sessions (
/v1/files/*)Operational additions:
•
GET /v1/accounts/{accountId}/health adds sendCap and push for Google/Microsoft• Webhooks add events:
calendar.event.created/updated/deleted, file.created/updated/deleted, file.picked, account.rate_limited• Microsoft tenants that require admin approval can use
GET /v1/connect/microsoft/admin-consentcurl -sS -H "Authorization: Bearer $ZERNIO_API_KEY" \
"https://api.zernio.com/v1/connect/google?profileId=$PROFILE_ID&scopes=email,calendar,files"
View documentation
❤1
Shipped today: 7 API updates
• Ads Reporting: List account issues and compare periods in reports via
• Meta Ad Sets: Configure Meta ad set schedules and compliance fields via
• Ads Create: Create ads without a name and read inferred settings from
• Meta Lead Gen: Read disclaimer checkbox consent per lead via
• Connect: Detect connect token/profile mismatches via
• Meta ad accounts can now be pre-checked with GET /v1/ads/accounts/health before creating ads.
• Ads Reporting: List account issues and compare periods in reports via
GET /v1/ads/alerts and compare=previous on GET /v1/ads/tree//v1/ads/timeline.• Meta Ad Sets: Configure Meta ad set schedules and compliance fields via
PUT /v1/ads/ad-sets/{adSetId} using platformSpecificData.adSchedule, dsaBeneficiary, dsaPayor.• Ads Create: Create ads without a name and read inferred settings from
appliedDefaults in POST /v1/ads/create responses.• Meta Lead Gen: Read disclaimer checkbox consent per lead via
consents on lead list endpoints and lead.received webhook payloads.• Connect: Detect connect token/profile mismatches via
403 INSUFFICIENT_PERMISSIONS on connect endpoints like GET /v1/connect/googlebusiness/locations.• Meta ad accounts can now be pre-checked with GET /v1/ads/accounts/health before creating ads.
GET ad review responses can now return
When calling
You can now also pass
•
•
•
View documentation
adId: null on success.When calling
GET /v1/ads/{adId}/review with a Meta platformAdId plus accountId (for an ad not yet synced into Zernio), the response is read live from Meta and returns synced: false and adId: null. Update your code to treat adId as nullable.You can now also pass
accountId to read unsynced Meta ads via:•
GET /v1/ads/{adId} (returns ad.synced)•
GET /v1/ads/{adId}/preview (returns synced)•
GET /v1/ads/{adId}/media (returns synced)curl -sS -H "Authorization: Bearer $ZERNI0_KEY" \
"https://api.zernio.com/v1/ads/123456789012345/review?accountId=acc_abc"
View documentation
❤1
You can now manage and use your own OAuth apps for Connect.
Use the new
Key details:
• List supported platforms and setup info via
• Create/update apps with
• App
• New webhook event
View documentation
Use the new
/v1/connect/oauth-apps endpoints to store per-platform client credentials, rotate secrets, and validate keys. Then pass oauthAppId on GET /v1/connect/{platform} so the consent screen shows your app and the platform’s limits/quotas apply to your app.Key details:
• List supported platforms and setup info via
GET /v1/connect/oauth-apps (see platforms and redirectUri)• Create/update apps with
scopeAreas: posting, analytics, comments, messaging, ads• App
status: ok, unchecked, invalid• New webhook event
account.permissions_changed is available for subscriptions and test firescurl -X POST "$ZERNIO_API/v1/connect/oauth-apps" \
-H "Authorization: Bearer $ZERNIO_KEY" \
-H "Content-Type: application/json" \
-d '{"platform":"youtube","label":"Acme","clientId":"...","clientSecret":"..."}'
View documentation
OAuth app scope areas no longer include
If your integration sends
New:
View documentation
ads.If your integration sends
scopeAreas when creating/updating OAuth apps, remove ads (allowed: posting, analytics, comments, messaging). Also update any code that parses apps[].scopeAreas, platforms[].scopeAreas[].area, or webhook account.missingScopeAreas to not expect ads.New:
OAuthApp.webhook is now returned (Facebook/Instagram only) with callbackUrl, verifyToken, object (page|instagram), and fields.curl -X PATCH "$ZERNIO_API/v1/connect/oauth-apps/$APP_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"scopeAreas":["posting","comments"]}'
View documentation
OAuth app
If your integration sends or expects
This affects:
•
•
•
• Webhook
Also added:
View documentation
scopeAreas no longer supports ads.If your integration sends or expects
ads in OAuth app setup, update it to use only: posting, analytics, comments, messaging.This affects:
•
POST /v1/connect/oauth-apps body scopeAreas•
PATCH /v1/connect/oauth-apps/{appId} body scopeAreas•
GET /v1/connect/oauth-apps response apps[].scopeAreas and platforms[].scopeAreas[].area• Webhook
account.permissions_changed payload account.missingScopeAreasAlso added:
apps[].webhook in GET /v1/connect/oauth-apps (Facebook/Instagram only) with callbackUrl, verifyToken, object (page | instagram), and fields.curl -X PATCH "$ZERNIO_API/v1/connect/oauth-apps/$APP_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"scopeAreas":["posting","comments"]}'
View documentation
Shipped today: 10 API updates
• Ads: Manage Reddit audiences and ad groups:
• Ads Rules: Audit every rule action and keep past runs readable:
• Publishing: Incrementally sync posts with
• Meta Ads: Show Meta ad set learning phase in your UI:
• Instagram: Explain collaborator removals on publish: Instagram create post responses expose
• Ads: Manage Reddit audiences and ad groups:
GET/POST /v1/ads/audiences, POST /v1/ads/ad-sets, GET /v1/ads/ad-sets/{id}/targeting, PUT /v1/ads/ad-sets/{id}.• Ads Rules: Audit every rule action and keep past runs readable:
GET /v1/ads/rules/activity and GET /v1/ads/rules/{ruleId}/runs with runs[].evaluation.rule.• Publishing: Incrementally sync posts with
GET /v1/posts using updatedSince to fetch items whose updatedAt changed since a timestamp.• Meta Ads: Show Meta ad set learning phase in your UI:
GET /v1/ads/tree returns campaigns[].adSets[].learningStatus.• Instagram: Explain collaborator removals on publish: Instagram create post responses expose
platformSpecificData.droppedCollaborators[] with username and reason.Meta Dynamic Creative: update your
The CTA enum for
•
Meta CTA coverage was also expanded across
Additionally,
View documentation
dynamicCreative.callToActionTypes values.The CTA enum for
POST /v1/ads/create Dynamic Creative has changed: these values were removed and will now be rejected:•
REGISTER JOIN ATTEND REQUEST_DEMO VIEW_QUOTE APPLYMeta CTA coverage was also expanded across
callToAction, creatives[].callToAction, and dynamicCreative.callToActionTypes (e.g. SEE_DETAILS, LIKE_PAGE, MESSAGE_PAGE, OPEN_LINK, NO_BUTTON, CALL_NOW, WHATSAPP_MESSAGE, etc.).Additionally,
GET /v1/ads now returns richer Meta creative fields like creative.headline, creative.bodies, creative.description, creative.callToAction, creative.leadGenFormId, creative.imageHash, and creative.urlTags, and creative.headlines[]/creative.descriptions[] can now be strings or objects.curl -X POST "$ZERNIO_API/v1/ads/create" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"accountId":"...","adAccountId":"act_...","goal":"traffic","dynamicCreative":{"imageUrls":["https://..."],"callToActionTypes":["LEARN_MORE"],"linkUrls":["https://..."],"bodies":["Text"],"titles":["Title"]}}'
View documentation
Meta Facebook placements:
If your integration sends
Affected endpoints include
View documentation
video_feeds was removed from facebookPositions.If your integration sends
placements.facebookPositions (or placementAssets.rules[].placements.facebookPositions) with video_feeds, update your requests to omit it or replace it with supported positions.Affected endpoints include
PUT /v1/ads/ad-sets/{adSetId}, POST /v1/ads/create, POST /v1/ads/messaging, POST /v1/ads/call, POST /v1/ads/ctwa.curl -X POST "$ZERNIO_API/v1/ads/create" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"accountId":"...","adAccountId":"...","name":"...","placements":{"publisherPlatforms":["facebook"],"facebookPositions":["feed","story"]}}'
View documentation
❤1
Shipped today: 13 API updates
• Ads: Control attribution tags, reach estimates, and duplication correlation using
• Inbox: Route FB/IG conversations by Page and handle comment-reply failures with structured errors via
• Connect: Keep connect flows on your OAuth app and detect token mismatches via
• Meta Ads: Audit ad set delivery/compliance details from the ads tree using
• Slack & Health: Propagate Slack identity across a workspace and debug disconnects via
• OAuth apps now return
• Ads: Control attribution tags, reach estimates, and duplication correlation using
tracking.zernioTag, rawTargeting, and adSetIdMap/adIdMap.• Inbox: Route FB/IG conversations by Page and handle comment-reply failures with structured errors via
pageId and POST /v1/inbox/comments/{postId}.• Connect: Keep connect flows on your OAuth app and detect token mismatches via
oauthAppId in selection/WhatsApp credentials and 403 INSUFFICIENT_PERMISSIONS.• Meta Ads: Audit ad set delivery/compliance details from the ads tree using
destinationType, attributionSpec, and regionalRegulatedCategories.• Slack & Health: Propagate Slack identity across a workspace and debug disconnects via
applyToWorkspace and GET /v1/accounts/health fields like disconnectReason.• OAuth apps now return
sharedWebhookUrl on GET /v1/connect/oauth-apps.Top-ups and payout batches no longer return a Checkout URL; they now charge the billing owner’s saved card directly and may require 3D Secure.
For
• Response field
• Response now includes
• When
• You can also end an unfinished payment with
For
• Response field
• When
Also,
View documentation
For
POST /v1/balance/top-ups:• Response field
url was removed (breaking)• Response now includes
status: succeeded | processing | requires_action• When
status=requires_action, use clientSecret with Stripe.js, then call POST /v1/balance/top-ups/{topupId}/confirm• You can also end an unfinished payment with
POST /v1/balance/top-ups/{topupId}/cancelFor
POST /v1/creator-campaigns/{campaignId}/payout-batches:• Response field
url was removed (breaking)• When
payment.status=requires_action, complete 3D Secure then call POST /v1/payout-batches/{batchId}/confirm (or /cancel to end it)Also,
GET /v1/balance now includes payoutLockedCents and payoutLocks, and transfers/payouts may return 409 payout_funds_locked until 7 days after a card charge.curl -X POST "$ZERNIO_API/v1/balance/top-ups/$TOPUP_ID/confirm" \
-H "Authorization: Bearer $API_KEY"
View documentation
Ad campaign results are now available via the new Ad Campaign Results endpoints.
You can upload your own daily per-campaign metrics (e.g. leads, sales, revenue) and query summed results per campaign over a date range, so rules and reporting can use them alongside spend.
New endpoints:
•
•
•
•
View documentation
You can upload your own daily per-campaign metrics (e.g. leads, sales, revenue) and query summed results per campaign over a date range, so rules and reporting can use them alongside spend.
New endpoints:
•
GET /v1/ads/campaign-results with fromDate, toDate (inclusive, max 400 days), optional campaignIds (≤500), pagination via limit and cursor → nextCursor•
POST /v1/ads/campaign-results uploads rows (≤1000) and supports Idempotency-Key; returns 202 with uploadId and Location•
GET /v1/ads/campaign-results/uploads/{uploadId} to check status queued/done/failed and unmatched reasons no_campaign/ambiguous•
GET /v1/ads/campaign-results/metrics and PUT /v1/ads/campaign-results/metrics/{key} to name metrics (kind: count or money with currency)curl -X POST "https://api.zernio.com/v1/ads/campaign-results" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7b1c2c" \
-d '{"rows":[{"date":"2026-10-01","campaignId":"123","values":{"qualified_leads":14,"revenue":7800}}]}'
View documentation
Shipped today: 10 API updates
• Ads: Automate ads ops with rule templates, ad-level rules, and computed campaign results via
• Ads: List each ad account row and troubleshoot connections with scoped alerts via
• Ads: Launch a branded ads connect flow using
• Creator campaigns: Pay creators on engagements or organic-only views and review paid-view flags via
• Inbox & Webhooks: Filter inbox conversations by contact tags and track GBP review deletions/restores via
• Ads: Automate ads ops with rule templates, ad-level rules, and computed campaign results via
GET /v1/ads/rules/templates, PUT /v1/ads/campaign-results/metrics/{key}.• Ads: List each ad account row and troubleshoot connections with scoped alerts via
GET /v1/accounts?adAccountRows=true and GET /v1/ads/alerts?profileId=....• Ads: Launch a branded ads connect flow using
GET /v1/connect/{platform}/ads with welcome=true plus brandName, logoUrl, primaryColor, welcomeTheme.• Creator campaigns: Pay creators on engagements or organic-only views and review paid-view flags via
metric=engagements, organicViewsOnly, and submissions fields viewsPaid/engagementsLatest.• Inbox & Webhooks: Filter inbox conversations by contact tags and track GBP review deletions/restores via
GET /v1/inbox/conversations?tags=... and webhook events review.deleted/review.restored.The TikTok Tools download endpoint has been removed:
If your integration relied on this to fetch a download URL or available formats for TikTok videos, you’ll need to remove/replace those calls—requests to this endpoint will no longer work.
Affected endpoint:
View documentation
GET /v1/tools/tiktok/download.If your integration relied on this to fetch a download URL or available formats for TikTok videos, you’ll need to remove/replace those calls—requests to this endpoint will no longer work.
Affected endpoint:
GET /v1/tools/tiktok/downloadcurl -X GET \
"$ZERNIO_API_BASE/v1/tools/tiktok/download?url=..." \
-H "Authorization: Bearer $ZERNIO_API_KEY"
View documentation
Shipped since Sunday: 7 API updates
• Publishing: Label AI-generated Facebook Reels/video Stories via
• Analytics: Compute date-range sums without client aggregation:
• Inbox: Render Facebook comment attachments (GIFs, photos, links, videos) from
• Ads: Rebuild Meta catalog template ad creatives with a different format using
• Creator Campaigns: Move a creator participant to another campaign while keeping the same participant id via
• Card top-ups now support fee-on-top pricing, and you can fetch the estimated card fee before charging.
• Publishing: Label AI-generated Facebook Reels/video Stories via
platformSpecificData.isAiGenerated, and invite up to 10 Reel collaborators via platformSpecificData.collaborators.• Analytics: Compute date-range sums without client aggregation:
GET /v1/analytics/daily-metrics returns totals (impressions, reach, engagement, etc.).• Inbox: Render Facebook comment attachments (GIFs, photos, links, videos) from
comments[].attachment in GET /v1/inbox/comments/{postId}.• Ads: Rebuild Meta catalog template ad creatives with a different format using
creative.catalogFormat on PUT /v1/ads/{adId}.• Creator Campaigns: Move a creator participant to another campaign while keeping the same participant id via
POST /v1/creator-campaigns/{campaignId}/participants/{participantId}/move.• Card top-ups now support fee-on-top pricing, and you can fetch the estimated card fee before charging.
Shipped today: 15 API updates
• Ads: Build richer ads UIs: rank ads
• Ads Reporting: Report conversions by goal and booked appointments: timeline
• Ads Writes: Handle ads write edge cases: Meta asset_feed text edits via
• Account Health: Gate create/boost and inbox health:
• Analytics & Voice: Detect missing YouTube segments via
• Ads: Build richer ads UIs: rank ads
GET /v1/ads/performance, read schedules/special categories via GET /v1/ads/tree, and label audiences with audiences[].summary.• Ads Reporting: Report conversions by goal and booked appointments: timeline
rows[].conversionsByType and Meta metrics.funnel.schedules.• Ads Writes: Handle ads write edge cases: Meta asset_feed text edits via
PUT /v1/ads, lead forms return 409 AccountDisconnected, and campaign status uses 422 ad_account_unusable.• Account Health: Gate create/boost and inbox health:
GET /v1/ads/accounts/health returns ready/blockers, and /v1/accounts/health returns inboundActivity stamps.• Analytics & Voice: Detect missing YouTube segments via
segmentMetricsAvailable, estimate forwarded call costs with forwardTo, and debug uploads using failureReason on results status.Ad rules
When creating rules,
Key changes:
•
•
•
View documentation
conditions are now a strict group structure and no longer accept extra fields.When creating rules,
conditions must be either { all: [...] } or { any: [...] } (no other top-level keys). Items inside all/any can be a condition or another nested group (up to 3 levels).Key changes:
•
conditions is now oneOf: all or any•
conditions and each group are additionalProperties: false•
all[]/any[] items are now AdRuleConditionItem (condition or nested group)curl -X POST "$ZERNIO_API/v1/ads/rules" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"conditions":{"any":[{"metric":"cpc","window":"today","op":">","value":2}]}}'
View documentation
Ad rules budget actions now support fixed-amount updates, and
If you parse
• Fixed amount:
• Percent change:
Also,
View documentation
adjust_budget actions may no longer include direction/percent/limit.If you parse
rules[].actions[], update your logic to handle two adjust_budget shapes:• Fixed amount:
{ type: "adjust_budget", amount } (required amount)• Percent change:
{ type: "adjust_budget", direction, percent, limit }Also,
notify actions can now include send to deliver alerts via connected Slack or email destinations (in addition to the ad_rule.triggered webhook).View documentation
Ad rules now support a new action type:
If your integration strictly validates/parses rule actions, update your models to accept
•
•
•
You can also filter rule activity by
View documentation
duplicate.If your integration strictly validates/parses rule actions, update your models to accept
actions[].type = duplicate (in addition to notify, pause, activate, adjust_budget) and handle its fields.duplicate action fields:•
status: paused | active (default paused)•
renameSuffix•
maxChangesPerDayYou can also filter rule activity by
type=duplicate on GET /v1/ads/rules/activity, and webhook/run/activity payloads may now include type = duplicate.curl -G "$ZERNIO_API/v1/ads/rules/activity" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "type=duplicate" \
--data-urlencode "limit=50"
View documentation
Ad rule schedules now support set times and optional start/end windows, and
When reading rules, handle
You can now schedule rules with:
•
•
•
Sending
View documentation
everyMinutes is no longer guaranteed to be present.When reading rules, handle
schedule.everyMinutes being missing or null (it’s null when a rule runs at set times).You can now schedule rules with:
•
everyMinutes: 15, 30, 60, 180, 360, 720, 1440, or null•
times: weekly run times (days + HH:MM)•
startsAt / endsAt: optional date-time boundsSending
schedule replaces the rule’s whole timing; if omitted on create, a new rule defaults to every 60 minutes.View documentation