Statuses
status tracks where a content object sits in the review-and-publish pipeline.
States
Section titled “States”| Status | Meaning | Set by |
|---|---|---|
draft | Being edited. Not queued to publish. The default on create. | client |
pending_review | Submitted for approval. Visible in the review queue. | client |
approved | Approved. Eligible to be scheduled and published. | client |
scheduled | Has a scheduled_for. The publish cron will claim it. | client |
publishing | The cron has claimed the item and is calling platform APIs. | cron |
published | At least one platform accepted the post. | cron |
rejected | Turned down in review. Not published, still retrievable. | client |
archived | Soft-deleted. Hidden from list results. | DELETE |
Those eight are the full set.
There is no failed status. When every targeted platform rejects a post, the cron returns the item to approved — not to a terminal failure state. Per-leg failure detail lives on the publishing-queue row and in the content.publish_failed webhook, not on the content object.
There is also no deleted status; deletion is archived.
What each endpoint accepts
Section titled “What each endpoint accepts”POST /content—draft(default),pending_review,approved,scheduled.PATCH /content/{id}— the same four plusrejected.- Neither accepts
publishing,published, orarchived. Those belong to the cron and toDELETE.
Transitions are not enforced
Section titled “Transitions are not enforced”The API does not implement a state machine. Any PATCH may move an item from any client-settable status to any other — published straight back to draft, rejected to scheduled, whatever you send. Nothing returns a 409 for an “illegal” content transition.
The practical path is still the obvious one:
draft -> pending_review -> approved -> scheduled -> publishing -> publisheddraft -> approved (skip review)draft -> scheduled (skip both; set scheduled_for too)any -> rejected (turn it down)any -> archived (via DELETE)Campaigns are state-checked — POST /campaigns/{id}/launch rejects anything that is not draft or paused with 409 invalid_state. Content is not.
Publishing
Section titled “Publishing”publishing and published are written by the cron worker, never by clients. Move an item to scheduled (or call POST /content/{id}/publish) and wait.
The cron claims work by atomically flipping scheduled to publishing, so only one worker ever picks up an item. If a claim goes stale — still publishing, untouched for 15 minutes — the next run returns it to scheduled and it is retried.
POST /content/{id}/publish does not run the pipeline inline. It sets the item to approved (or scheduled, if you pass scheduled_for), returns 202, and leaves the actual posting to the cron. See Content.
Re-scheduling
Section titled “Re-scheduling”To move a scheduled item, PATCH it with a new scheduled_for. The cron re-evaluates on the new slot.
Nothing stops you from patching an item that is already publishing, but the cron has claimed it by then and the edit will not stop the in-flight run.
Querying by status
Section titled “Querying by status”curl "https://app.nativpost.com/api/v1/content?status=scheduled&limit=50" \ -H "Authorization: Bearer $NATIVPOST_API_KEY"The filter takes a single value. Repeating ?status=scheduled&status=publishing does not union them — only the first value is read and the second is ignored. To span several statuses, make one request per status.
archived items are excluded from GET /content unconditionally, and there is no parameter to include them. Retrieving one by id with GET /content/{id} still works.