Publishing and post statuses
Each variant publishes on its own — immediately with Post now, or automatically at its scheduled time. Either way the same pipeline runs: WriteMars checks the posting account and approvals, refreshes the account's token, calls the platform API, and records the result on the variant and in the activity log.
Publish now vs. scheduled
- Post now — select the variant's tab on the post detail page, then click Post now in the property pane (Publish in the bottom bar on small screens). It publishes that one channel immediately. Via the API:
POST …/variants/<variant_id>/publish/. - Scheduled — a background job checks every 30 seconds and publishes variants whose time has come.
Before anything posts, the variant needs an active connected account assigned — without one the publish fails with a clear error. And if the channel requires sign-off, Post now doesn't bypass it: instead of publishing, the variant moves to needs_approval (the app confirms with "Sent to the channel's approvers") and goes out once an approver releases it. See approvals.
What each platform receives
| Platform | What gets published |
|---|---|
The variant's content through LinkedIn's versioned posts API, with the variant's visibility setting — public (default), connections, or logged_in. Supported images attached to the variant publish with the post. | |
| X (Twitter) | The content as the opening tweet, then any thread tweets as chained replies, in order. Supported images attached to each tweet publish with that tweet. All tweets are validated against the account's text limit up front. |
LinkedIn needs text or at least one supported image. X needs text or at least one supported image on every tweet in the thread. Non-image files are kept with the post for team context and are not published to the platforms.
The status lifecycle
draft ──▶ scheduled ──▶ publishing ──▶ published
▲ │ │
└───────────┘ └────────▶ failed
(schedule cleared) (fix & retry)
draft ──▶ needs_approval ──▶ scheduled (channel requires sign-off)
▲ │
└───────────┘ (rejected / changes requested)
| Status | Meaning |
|---|---|
draft | Being written. No publish time set (clearing a schedule returns here). |
needs_approval | Awaiting approval — the variant targets a channel that requires sign-off, and a request sits with the channel's approvers. Approving moves it to scheduled (a past-due time publishes within ~30 seconds); rejecting returns it to draft with the reviewer's comment, schedule time kept. See approvals. |
scheduled | Queued — has a future scheduled_at; the scheduler will publish it. |
publishing | The platform call is in flight. All edits are rejected until it finishes; a variant stuck here for over 5 minutes (e.g. a crashed worker) is moved to failed for review — not retried, since the platform call may already have gone out and re-running it could double-post. |
published | Live. The variant stores the publish time and the platform post URL — shown as a Published post banner with a View post link above the editor, and as a link on the channel's row in the schedule summary. Schedule and status are locked from then on. |
failed | The platform rejected it. The error message is stored on the variant and shown under the editor and on the schedule summary row. |
Publish results also raise notifications for success and failure, and every transition is logged in the post's activity feed (with System as the actor for scheduled publishes).
When publishing fails
A failed variant is not stuck: fix the cause — reconnect an expired account or shorten an over-length tweet — then Post now again or reschedule it (failed variants can be scheduled like drafts). Common errors and fixes are collected in publishing failures.
One platform failing never blocks the others — each channel publishes independently.