Post webhooks
Events fired through the publishing lifecycle, per-platform results, and native (external) posts.
Events fired as posts move through the publishing pipeline, plus events for posts authored natively on the platform. Delivery, retries, idempotency, and signature verification work the same for every event and are covered in the webhooks overview.
Events
| Event | Description |
|---|---|
post.published | Fired when a post is successfully published. |
post.failed | Fired when a post fails to publish on all target platforms. |
post.partial | Fired when a post publishes on some platforms and fails on others. |
post.cancelled | Fired when a post publishing job is cancelled. |
post.scheduled | Fired whenever a post enters the scheduled state: created with a schedule, added to a queue, promoted from draft, or retried after failing. |
post.recycled | Fired when a post is recycled for republishing. |
post.platform.published | Fired once per platform target inside a post as that platform finishes publishing, without waiting for the other platforms. |
post.platform.failed | Fired once per platform target inside a post when that platform fails permanently. |
post.platform.deleted | Fired when a published platform target is detected as deleted on the platform. |
post.tiktok.url_resolved | Fired when a published TikTok post's public URL becomes available. |
post.external.created | Fired when a post authored natively on the platform (outside Zernio) is detected for the first time. |
post.external.updated | Fired when a tracked native post's text or media changes on the platform. |
post.external.deleted | Fired when a tracked native post is detected as removed from the platform. |
How the events fit together
A post you publish emits events at three moments, in a fixed order:
post.scheduledfires every time a post enters the scheduled state, not just at creation. That covers a post created with a schedule (includingpublishNow, so it means accepted and queued, not "scheduled for later"), a draft promoted to scheduled or queued, a post added to a queue, and a failed or partial post you retry. It does not fire when an already-scheduled post is edited or moved to a different time, so one post can legitimately emit it more than once over its life.- Platform events stream in as each platform finishes. A post targeting three platforms emits up to three
post.platform.published/post.platform.failedevents, each as soon as that platform terminates, without waiting for the slowest one.post.platform.failedfires only on permanent failure; retryable errors stay silent until they either succeed or fail for good. - The rollup fires once, after every platform has terminated:
post.publishedif all succeeded,post.partialif mixed,post.failedif all failed. post.tiktok.url_resolvedcan trail the rollup by minutes. It fires only when a TikTok target that was already reported as published gains its public URL.post.platform.deletedcan trail the rollup by days. It fires when Zernio's background sync detects that a platform target you published was later deleted on the platform (poll-driven, roughly hourly).
Three events sit outside this pipeline. post.cancelled fires when a post's publishing job is cancelled before anything published (if some platform already published, the rollup is post.partial instead). post.recycled fires when a recycling schedule clones a published post — it carries the new post's id, and that clone also emits its own post.scheduled. And the post.external.* family comes from a background sync of posts authored natively on the platform (poll-driven, roughly hourly), not from publishing at all.
post.published
Fired when a post is successfully published. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID
"post.scheduled" | "post.published" | "post.failed" | "post.partial" | "post.cancelled" | "post.recycled"UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.failed
Fired when a post fails to publish on all target platforms. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID
"post.scheduled" | "post.published" | "post.failed" | "post.partial" | "post.cancelled" | "post.recycled"UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.partial
Fired when a post publishes on some platforms and fails on others. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID
"post.scheduled" | "post.published" | "post.failed" | "post.partial" | "post.cancelled" | "post.recycled"UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.cancelled
Fired when a post publishing job is cancelled. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID
"post.scheduled" | "post.published" | "post.failed" | "post.partial" | "post.cancelled" | "post.recycled"UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.scheduled
Fired whenever a post enters the scheduled state: created with a schedule, added to a queue, promoted from draft, retried after a failure, or created as a recycled clone. Not fired when an already-scheduled post is edited or rescheduled. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID
"post.scheduled" | "post.published" | "post.failed" | "post.partial" | "post.cancelled" | "post.recycled"UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.recycled
Fired when a post is recycled for republishing. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID
"post.scheduled" | "post.published" | "post.failed" | "post.partial" | "post.cancelled" | "post.recycled"UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.platform.published
Fired once per platform target inside a post as that platform finishes publishing successfully, without waiting for other platforms on the same post. Use this for incremental UIs; use post.published for the post-level rollup, which fires separately after all platforms have terminated. The payload carries a platform block (platform post id and URL) and an account block identifying the connected social account, so cross-posts to multiple accounts on the same platform produce one event per account. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID.
"post.platform.published" | "post.platform.failed" | "post.platform.deleted" | "post.tiktok.url_resolved"The specific platform that just transitioned to a terminal state.
The connected social account the platform-write went through.
UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.platform.failed
Fired once per platform target inside a post when that platform fails permanently. Temporary, retryable failures do not fire this event, only permanent ones, so retry loops stay quiet. The envelope event (post.failed / post.partial) fires separately after all platforms have terminated. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID.
"post.platform.published" | "post.platform.failed" | "post.platform.deleted" | "post.tiktok.url_resolved"The specific platform that just transitioned to a terminal state.
The connected social account the platform-write went through.
UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.platform.deleted
Fired when Zernio's background sync detects that a platform target you published through Zernio was later deleted on the platform (for example, the user removed the Instagram post in the Instagram app). Detection is poll-driven (roughly hourly), not real-time: platforms offer no deletion push for published media, so Zernio diffs the platform's post listing and probes posts that stop resolving. The payload's platform.status is deleted and platform.deletedAt carries the detection time, not the moment the platform deleted the post. Coverage is bounded to the posts the platform's listing returns, so deletions of very old posts may not be detected. Subscribe with Create webhook settings or Update webhook settings.
Detection is listing-based, so a rare false positive is possible (for example, a platform API briefly omitting a post). Zernio self-heals its own data when the post reappears, but the webhook is not retracted. If you need certainty before acting destructively, re-check the post against the platform before deleting on your side.
Stable webhook event ID.
"post.platform.published" | "post.platform.failed" | "post.platform.deleted" | "post.tiktok.url_resolved"The specific platform that just transitioned to a terminal state.
The connected social account the platform-write went through.
UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.tiktok.url_resolved
Fired when a published TikTok post's public URL becomes available. TikTok exposes the numeric video id asynchronously (often minutes after the upload completes), so post.published can carry an empty publishedUrl for TikTok. This event delivers the resolved URL and platform post id, at most once per platform target. It never fires for drafts or private posts, which have no public URL. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID.
"post.platform.published" | "post.platform.failed" | "post.platform.deleted" | "post.tiktok.url_resolved"The specific platform that just transitioned to a terminal state.
The connected social account the platform-write went through.
UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.external.created
Fired when Zernio's background sync detects a post that was authored natively on the platform (outside Zernio), such as a Google Business Profile post created in the Google interface. This is poll-driven (roughly hourly), not real-time, because most platforms offer no push notification for merchant-authored posts. The payload's post.source is always "external", and post.id is the platform-native post ID. Subscribe with Create webhook settings or Update webhook settings.
On a freshly connected account, every existing native post is reported as post.external.created on the first sync (a one-time backfill). Treat created as an idempotent upsert keyed on post.id.
Stable webhook event ID
"post.external.created" | "post.external.updated" | "post.external.deleted"Native (external) post data shared by all post.external.* payloads.
UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.external.updated
Fired when a tracked native post's text or media changes on the platform. Edits are detected by comparing the post's text and media structure and, where the platform exposes one, the platform's own edit timestamp. A media-URL-only refresh (some platforms rotate expiring CDN URLs) does not fire this event. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID
"post.external.created" | "post.external.updated" | "post.external.deleted"Native (external) post data shared by all post.external.* payloads.
UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-timeResponse Body
post.external.deleted
Fired when a tracked native post is detected as removed from the platform. The payload's post.deletedAt carries the detection time. Coverage is bounded to the most recent posts the platform's listing returns, so deletions of very old posts may not be detected. Subscribe with Create webhook settings or Update webhook settings.
Stable webhook event ID
"post.external.created" | "post.external.updated" | "post.external.deleted"Native (external) post data shared by all post.external.* payloads.
UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.
date-time