Zernio
Zernio
Overview

Guides

ProfilesConnecting accountsMedia UploadsQueue SchedulingTimezones & SchedulingIdempotency & Safe RetriesPost LifecycleError HandlingRate LimitsPixels and Tracking TagsCommerceManyChat-style automationsReport Bugs & RequestsPlatform Settings
Dashboard
llms.txtOpenAPI
OverviewPlatformsAPI ReferenceResources
Guides

Post Lifecycle

Every post status, how a post moves between them, what you can do in each state, and which webhook fires on each transition.


A post is draft, scheduled or publishing, then published, partial or failed, and cancelled once every platform copy has been removed. Read post.status with GET /v1/posts/{postId}, or let a post webhook tell you when it changes. The status names what you can still do with the post and which event to expect next.

draft ──► scheduled ──► publishing ──► published
                            │      └──► partial
                            └─────────► failed
published / partial ──► cancelled   (via unpublish)

First call

Call GET /v1/posts/{postId}. The post-level status is an aggregate; each entry in platforms[] carries its own.

import Zernio from '@zernio/node';

const zernio = new Zernio();

const { data: fetched } = await zernio.posts.getPost({
  path: { postId: '65f1c0a9e2b5af0012ab34cd' }
});

console.log(fetched.post.status);

Response (200):

{
  "post": {
    "_id": "65f1c0a9e2b5af0012ab34cd",
    "status": "partial",
    "scheduledFor": "2027-01-01T17:00:00Z",
    "platforms": [
      {
        "platform": "linkedin",
        "status": "published",
        "platformPostUrl": "https://www.linkedin.com/feed/update/urn:li:share:7123456789012345678"
      },
      {
        "platform": "instagram",
        "status": "failed",
        "errorMessage": "Media processing failed: video too short for Reels",
        "errorCategory": "user_content",
        "errorSource": "user"
      }
    ]
  }
}

Post statuses

StatusMeaning
draftSaved and not going anywhere. The default when you send no scheduling field.
scheduledHas a future scheduledFor, set by you or assigned by a queue. Picked up at that time.
publishingBeing delivered to the platforms. Transient.
publishedEvery platform target succeeded.
partialSome platform targets succeeded, others failed.
failedEvery platform target failed.
cancelledPublishing was cancelled, or every platform copy was removed with unpublish. A cancelled post can be edited and rescheduled like a draft.

Which status a new post gets

Create post sets the initial status from the scheduling fields:

You sendInitial status
publishNow: truePublished in the same request. The response already carries the terminal result (published, partial or failed) with platformPostUrl per platform.
scheduledForscheduled. A time already in the past publishes in the same request, like publishNow.
queuedFromProfilescheduled, with scheduledFor assigned from the profile's next free queue slot.
isDraft: true, or none of the abovedraft. isDraft wins over publishNow and scheduledFor.

publishNow returns 201 when every platform published and 207 when at least one failed. 207 is a 2xx: fetch(...).ok is true and axios resolves, so branch on the status code or on post.status, never on "did it throw".

Per-platform status and errors

Each entry in platforms[] has a status of pending, processing, uploading, published, failed or cancelled, plus platformPostUrl once published. A published entry that later disappears from the platform keeps status: "published" and gets removedFromPlatformAt; detection runs with the analytics sync, so expect up to a few hours of lag.

A failed entry carries a human-readable errorMessage and two machine-readable fields:

errorCategoryMeaningFix
auth_expiredToken expired or revokedHave the user reconnect the account. Account health catches this early.
user_contentContent violates platform constraints (format, length, media specs)Fix the content. See platform requirements.
user_abusePlatform rate limits or spam detectionSlow down. See rate limits.
platform_rate_limitPlatform throttlingRetried automatically.
quota_exhaustedShared daily API quota emptyPublishing resumes at the platform's quota reset.
account_issueAccount configuration problem, such as the wrong account typeFix the account setup on the platform.
platform_rejectedPlatform rejected for policy reasonsChange the content.
platform_errorPlatform 5xx or maintenanceTransient. Retry later.
system_errorZernio-side issue (rare)Retry, or contact support if it persists.
unknownUnclassifiedInspect errorMessage.

errorSource (user, platform, system) says who can fix it: user errors need action from you or your user; platform and system errors are worth retrying.

What you can do in each state

OperationAllowed statesNotes
Updatedraft, scheduled, failed, partial, cancelledA published post can only have its recycling config updated.
DeleteAny except publishedRemoves the Zernio record. Deleting a published post returns 400; use unpublish to take it down from the platform.
Retryfailed, partialOnly the failed platforms are retried; published platforms are skipped.
Unpublishpublished, partialDeletes the post from one platform. Supported on Threads, Facebook, X, LinkedIn, YouTube, Pinterest, Reddit, Bluesky, Google Business Profile and Telegram. The post becomes cancelled once every platform entry is removed; with published entries left it becomes partial. YouTube deletion is permanent.
Edit publishedpublishedText only; media cannot change. Supported on X (platform value twitter), Discord, Facebook, Reddit, LinkedIn, Telegram, Pinterest, Google Business Profile, YouTube and Slack, each with its own rules: X requires X Premium and a 1-hour window, Pinterest edits are gated behind a Pinterest closed beta. Instagram, Threads, TikTok, Snapchat, WhatsApp and Bluesky expose no edit API.

Tracking transitions with webhooks

Each transition fires a post webhook:

EventFires when
post.scheduledA post enters the scheduled state (created with a schedule, queued, promoted from draft, or retried)
post.publishedAll platforms succeeded
post.partialSome platforms succeeded, some failed
post.failedAll platforms failed
post.cancelledA publishing job is cancelled
post.recycledA recycled post is re-queued
post.platform.published / post.platform.failedPer platform target, as soon as that platform reaches a terminal state, without waiting for the others
post.tiktok.url_resolvedA published TikTok post's public URL becomes available (TikTok resolves URLs asynchronously)
post.platform.deletedA published platform target is later detected as deleted on the platform (poll-driven, roughly hourly)

The per-platform events are the fastest signal: a post targeting 5 platforms emits them one by one as each platform finishes, while the aggregate event waits for all 5. For publishNow: true you need no webhook: the create response is synchronous and already holds the per-platform results and URLs.

If it fails

A 400 on DELETE /v1/posts/{postId} means the post is published:

{
  "error": "Published posts cannot be deleted",
  "type": "invalid_request_error",
  "code": "invalid_resource_state"
}

Take the post down from each platform with unpublish first, or leave it and delete nothing: the record stays as the source of platformPostUrl and analytics.

Related

  • Error handling: the error envelope and the retry endpoint.
  • Idempotency & safe retries: avoid double-posting when you retry creates.
  • Queue scheduling: let Zernio assign the publish time.
  • Post webhooks: the payload of each event above.
Was this page helpful?

Idempotency & Safe Retries

Retry POST /v1/posts safely with the Idempotency-Key header, understand x-request-id retry detection and the 24-hour content-hash dedup, and use Idempotency-Key on the other write endpoints.

Error Handling

The error envelope Zernio returns on a failure, its stable type and code values, HTTP statuses, and how to read and retry publishing failures.

On this page

First callPost statusesWhich status a new post getsPer-platform status and errorsWhat you can do in each stateTracking transitions with webhooksIf it failsRelated