TwitterAPIs Docs
API ReferenceArticles

Publish Article API

Publish a draft article as the account behind your registered session, transitioning it from Draft to Published. WARNING: publishing posts a real, public announcement tweet on the account's timeline. This is not a preview or a private action, and it cannot be undone by re-editing the article: once published, the only way back is Delete Article, which unpublishes the article AND removes the announcement tweet. Requires a registered session. Billed at $0.0016 per call. Cost: $0.0016 per call.

POST article/publish moves a draft Twitter/X article from Draft to Published status. It posts a real, public announcement tweet linking the article to the account's timeline, an action that cannot be reversed by editing again. Requires a registered session and the article's id. Returns ok (boolean) and an article object containing tweet_id and public_url. Costs $0.0016 per call.

POST
/article/publish

Authorization

bearerAuth
AuthorizationBearer <token>

Pass your API key as a bearer token on every request: Authorization: Bearer <API_KEY>.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/article/publish" \  -H "Content-Type: application/json" \  -d '{    "id": "QXJ0aWNsZUVudGl0eToyMDg2NjUwMjI4OTUwNjgzNjQ4"  }'
{  "ok": true,  "article": {    "id": "QXJ0aWNsZUVudGl0eToyMDg2NjUwMjI4OTUwNjgzNjQ4",    "rest_id": "2086650228950683648",    "title": "Why we rebuilt our onboarding from scratch",    "preview_text": "Opening paragraph.",    "lifecycle": "Published",    "content_state": {      "blocks": [        {          "key": "a1b2c",          "text": "Opening paragraph.",          "type": "unstyled",          "depth": 0,          "inlineStyleRanges": [],          "entityRanges": []        }      ],      "entityMap": []    },    "cover_media": null,    "media_entities": [],    "author": {      "id": "44196397",      "username": "elonmusk",      "name": "Elon Musk"    },    "created_at_secs": 1786400000,    "modified_at_secs": 1786400400,    "first_published_at_secs": 1786400400,    "visibility_setting": "Public",    "tweet_id": "2086650300012345678",    "public_url": "https://x.com/i/article/2086650228950683648"  }}
{  "error": "bad_request",  "message": "Missing or malformed parameter. Fix the request before retrying."}
{  "error": "unauthorized",  "message": "The API key is missing, malformed, or revoked. Check the Authorization header."}
{  "error": "insufficient_credits",  "message": "Your balance is exhausted. Top up your credits to continue."}
{  "error": "forbidden",  "message": "The acting account is not authorized for this write action, or has no logged-in session."}
{  "error": "not_found",  "message": "The resource does not exist, for example a deleted tweet or a private account."}
{  "error": "rate_limited",  "message": "Too many requests. Back off and retry with exponential backoff."}
{  "error": "server_error",  "message": "Something failed on our side. Retry with backoff; if it persists, contact support."}

Pricing

UnitPrice
Per call$0.0016
Per 1,000 calls$1.60

When to use

Use this endpoint when a draft article created via article/create is ready to go live and you want to transition it from Draft to Published, triggering the public announcement tweet. Reach for the sibling article/update_content or article/update_title endpoints instead if you still need to edit the draft before publishing, since publish is a one-way action.

Notes

  • WARNING: this posts a real, public announcement tweet on the acting account's timeline. It is not reversible by editing the article again; the only reversal is Delete Article (which unpublishes and removes the announcement tweet) or Unpublish Article (which reverts to Draft but leaves the announcement tweet in place).
  • [VERIFY] Request variable names and the audience/reply_control defaults are inferred from a captured X dialog default, not a captured request; not executed live end-to-end.
  • Needs a session for the account you are publishing as: either register one once (POST /customer/session), or pass per-call inline credentials as x-auth-token and x-ct0 request headers, which let a single API key act as many accounts. Returns 409 session_required if neither is supplied, 401 session_dead when the session has expired.
  • caption is capped at 256 characters by X; longer captions are rejected upstream, not truncated by us.
  • Unpublish Article: Revert a published article back to Draft. The announcement tweet is left in place.
  • Delete Article: Delete an article. A draft is hard-deleted; a published article is unpublished, then its announcement tweet is removed too.
  • Get Article: Read an article via its announcement tweet, or your own via its entity id.
  • Update Article Content: Replace an article's body with a new Draft.js content_state.

FAQ

Does publishing an article delete or replace the announcement tweet if I edit the article afterward?

No. Editing the published article's content does not update or remove the original announcement tweet. The endpoint description states publishing cannot be undone by re-editing, so the tweet stays live on the timeline exactly as it was posted even if the article content changes later.

How do I control who can see the article and who can reply to the announcement tweet?

Use the audience parameter to set who can read the published article and reply_control to set who can reply to the announcement tweet; both default to Everyone if omitted. These are independent settings, so you can restrict article readership without restricting replies, or vice versa.