---
title: Publish content
description: Prepare text and media, fan out to explicit account targets, and preserve independent destination outcomes through retries and reconciliation.
---

A publication request records application intent. It has shared content, explicit account targets, optional target overrides, and an idempotency key. Each target receives an independent delivery outcome.

## Prepare locally

Preparation validates known content combinations, references, target ownership, capability declarations, and media inputs without uploading or publishing. It should report missing fields and warnings before a network call. Preparation never crops, truncates, rewrites, changes visibility, or adds a destination to make a request pass.

## Interpret results

`published` requires a destination-specific native post reference. `accepted` and `processing` remain pending. A failed target can coexist with a published target. An uncertain write must be reconciled before a retry that could create public content twice.

The [per-target lifecycle diagram](/concepts/architecture#per-target-publication-lifecycle) shows why a single aggregate status cannot stand in for destination results. Media uploads, video processing, scheduling, cancellation, and removal each have additional backend and platform constraints; consult the adapter capability manifest before enabling them.

Continue with the [platform support matrix](/platforms) and [capability declarations](/reference/capabilities) before selecting destinations.

## Reply and retry scope

Set `replyTo` on a target when destinations reply to different native posts or comments. A request-level `replyTo` applies to all its targets. Every reply reference must use the selected target's account, backend, and platform; mismatches fail preparation before dispatch.

Idempotency fingerprints include target content, options, reply references, and schedules. Changing any of these under a previously claimed logical key produces an idempotency conflict. Provider request keys also include the tenant scope, so shared accounts do not collapse two tenants' independent publication intentions into one provider request.

The client's `concurrency` limit applies to each backend across overlapping reads and writes on that client. A queued cancellation does not dispatch a write. Native adapter access bypasses client coordination and must be managed explicitly by the application.

## Native scheduling on direct adapters

A direct adapter accepts `schedule` only when the platform stores the post and publishes it at the requested time. The SDK does not delay a request itself. Only the YouTube adapter supports this today; see [schedule a video](/platforms/youtube#schedule-a-video). The other direct adapters reject `schedule` during preparation, before any network call, and declare `posts.schedule` in their capability manifests with the reason.

| Platform  | Declaration                  | Reason                                                                                                                                                                                                                                                                                                                                                                              |
| --------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| X         | `not-implemented-by-adapter` | [`POST /2/tweets`](https://docs.x.com/x-api/posts/create-post) has no publish-time field. X schedules Tweets only through the [Ads API `scheduled_tweets` endpoint](https://docs.x.com/x-ads-api/creatives), which needs Ads API approval, an ads account and OAuth 1.0a-signed requests. Those Tweets are promoted-only by default. See [X](/platforms/x#limits-and-requirements). |
| Threads   | `unsupported-by-platform`    | The [publishing reference](https://developers.facebook.com/docs/threads/reference/publishing) has no publish-time parameter, and `threads_publish` publishes immediately.                                                                                                                                                                                                           |
| Bluesky   | `unsupported-by-platform`    | A record is visible once written. The [`app.bsky.feed.post`](https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/feed/post.json) `createdAt` field is a client-declared timestamp and does not delay publication.                                                                                                                                                 |
| Instagram | `unsupported-by-platform`    | [Content publishing](https://developers.facebook.com/docs/instagram-platform/content-publishing) has no publish-time parameter. `media_publish` publishes immediately, and unpublished containers expire after 24 hours.                                                                                                                                                            |
| TikTok    | `unsupported-by-platform`    | [Direct Post `post_info`](https://developers.tiktok.com/doc/content-posting-api-reference-direct-post) has no publish-time field.                                                                                                                                                                                                                                                   |
| LinkedIn  | `unsupported-by-platform`    | The [Posts API](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/posts-api) accepts only `lifecycleState: "PUBLISHED"` on creation and has no publish-time field.                                                                                                                                                                                   |

These sources were checked on 2026-09-24. Because these adapters never create a scheduled post, they do not implement `posts.cancelScheduled`. To publish later on these platforms, run the publish from your own durable job runner, or use a hosted backend that schedules on your behalf.

## Cancel a schedule or remove content

Use the operation that matches the resource you intend to change. These methods authorize the reference's account before network access and check backend ownership before writing.

| Method                              | Reference                                                 | Implemented behavior                                                                                                                                                                        |
| ----------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `posts.cancelScheduled(job)`        | Account-scoped `ScheduledJobRef` from a scheduled outcome | Zernio deletes the future scheduled record. Post for Me retains the record as a draft, preserving its timestamp and content. Direct YouTube clears `publishAt` and keeps the video private. |
| `posts.deleteBackendRecord(record)` | `BackendPostRef` with `recordId`                          | Deletes a draft provider record on Zernio or Post for Me. Scheduled and dispatched records are rejected.                                                                                    |
| `posts.removeFromPlatform(post)`    | `PlatformPostRef` from publication                        | Zernio unpublishes a native post while retaining the backend record, on X, Threads, Bluesky, YouTube, LinkedIn, and Facebook.                                                               |

Direct adapters also implement `posts.removeFromPlatform` for X, Threads, Bluesky, LinkedIn, YouTube, and Instagram with Facebook Login. They delete the native post with the connected account credentials. The direct TikTok adapter does not implement it.

The direct YouTube adapter implements `posts.cancelScheduled` for videos uploaded with `schedule`. It clears the scheduled publish time and leaves the video uploaded and private; it never deletes the video. See [YouTube](/platforms/youtube#cancel-a-scheduled-video) for the quota cost and scope.

On Zernio, native removal needs the backend record ID preserved in `post.native.backendRecordId`. A native post ID alone cannot identify that provider record. Post for Me does not advertise native removal because its record deletion endpoint does not establish that it removes live platform content.

A record shared by multiple destinations is rejected by these mutations. The client will not change another account's schedule or post as a side effect. Schedule cancellation requires a future schedule; once submission is due or underway, reconcile its delivery. The provider controls races between cancellation and dispatch. Cancellation never proves that an already dispatched native post was removed.

Mutations are sent once. A lost response raises `ambiguous_outcome` with `reconcile-first`; inspect the backend before repeating the operation.

## Edit a published post

Editing is a native operation because each platform changes a different part of a post. The direct adapters declare `posts.update` as follows:

| Platform  | Availability            | Behavior                                                                   |
| --------- | ----------------------- | -------------------------------------------------------------------------- |
| X         | available               | `updatePost` edits text on a recent post and returns the new version's ID. |
| LinkedIn  | available               | `updatePost` applies a partial update to the post.                         |
| YouTube   | available               | `updateVideo` replaces video metadata.                                     |
| Threads   | unsupported-by-platform | The Threads API has no edit endpoint.                                      |
| Bluesky   | unsupported-by-platform | The Bluesky AppView ignores post record updates.                           |
| Instagram | unsupported-by-platform | Only `comment_enabled` can be updated on published media.                  |
| TikTok    | unsupported-by-platform | The Content Posting API has no edit endpoint.                              |

Edits are sent once, like the other mutations. See each [platform page](/platforms) for eligibility rules and sources.
