X (Twitter)

How to Post to X via API

The request flow for publishing to X programmatically.

Quick answer

To post to X via API: connect the account through X’s OAuth screen — either with your own X developer app (OAuth 1.0a consumer credentials, X bills you directly) or PostGate’s shared app (per-action workspace credits) — then send POST /api/posts with the body, profile ID, and media, and poll the target until it reaches a terminal state.

This is the complete flow for publishing to X programmatically: what credentials you need, how to connect a profile, how to create the post, how the per-action billing works, and how to confirm delivery. If you already have a connected profile and just want the one request, jump to X API: Post a Tweet.

01

What do you need before you start?

Two options. Bring your own X developer app with OAuth 1.0a enabled — the “API Key” / “API Key Secret” consumer credentials from the X developer portal, not the OAuth 2.0 client ID/secret pair — and X bills your app directly with no PostGate credit cost. Or skip app registration entirely and use PostGate's shared app, in which case each post and analytics read draws down your workspace credit balance instead. Create a PostGate workspace to get a profile group ID before connecting.
02

How do I connect the X account?

Start the connection flow against your profile group. PostGate redirects the account owner through X's OAuth screen and returns them to your return_url once authorized.
Start connectionPostGate API
curl -X POST https://postgate.studio/api/profiles/connect \
  -H "Authorization: Bearer $POSTGATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "x",
    "profile_group_id": "grp_acme123",
    "return_url": "https://app.example.com/settings/social"
  }'
03

How do I create the post?

Send the body text, the connected profile ID, and any media as public URLs or pre-uploaded media IDs. Set draft: true to save it for review instead of publishing immediately, or a scheduled_at timestamp to queue it.
Publish nowPostGate API
curl -X POST "https://postgate.studio/api/posts?profile_group_id=grp_acme123" \
  -H "Authorization: Bearer $POSTGATE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: launch-post-x-002" \
  -d '{
    "post": { "body": "Launch day. 🚀" },
    "profiles": ["pro_x123"],
    "media": ["https://cdn.example.com/launch.jpg"]
  }'
04

How does the per-action cost work?

X is billed differently from every other platform PostGate supports: it charges per post and per analytics read, not a flat subscription. That charge lands on your own X developer app if you brought one, or on your PostGate workspace credit balance if you used the shared app. See X API Pricing Tiers for the exact current prices.
05

How do I confirm delivery?

A post response is asynchronous per target. Poll it until every target reaches a terminal state — published, failed, or skipped — and read the permalink and platform post ID off the target once it's live.
Check statusPostGate API
curl https://postgate.studio/api/posts/post_01JXYZ \
  -H "Authorization: Bearer $POSTGATE_API_KEY"
06

Where to go from here

Need more than one connected post? See X Thread API. Uploading large video? See X API Chunked Media Upload. Hitting 429s at volume? See X API Rate Limit.

Frequently asked questions

Do I need my own X developer app to post via API?

No — there are two options. Bring your own X developer app with OAuth 1.0a enabled (the “API Key” / “API Key Secret” consumer credentials from the X developer portal, not the OAuth 2.0 client ID/secret pair) and X bills your app directly with no PostGate credit cost. Or skip app registration entirely and use PostGate’s shared app, where each post and analytics read draws down your workspace credit balance instead.

How is the X API billed?

X is billed differently from every other platform PostGate supports: it charges per post and per analytics read, not a flat subscription. That charge lands on your own X developer app if you brought one, or on your PostGate workspace credit balance if you used the shared app.

Can I draft or schedule an X post instead of publishing immediately?

Yes. Set draft: true to save the post for review instead of publishing immediately, or set a scheduled_at timestamp to queue it for a future time.

How do I confirm an X post was actually delivered?

A post response is asynchronous per target. Poll the post until every target reaches a terminal state — published, failed, or skipped — and read the permalink and platform post ID off the target once it’s live.

Build it with PostGate

One API for every social platform your customers care about — sandboxed, documented, and ready today.

Start building Read the docs