Skip to content

How do you post a tweet with an image using the API?

Last updated August 3, 2026

Posting an image is two steps, never one. Upload the file first to receive a media id, poll the status route until processing reports success, then create the post referencing that id. On TwitterAPIs the upload takes base64 in media_data, the create call bills at $0.0016, and both run as an X session you register once or pass per request.

Every rate here is the pricing TwitterAPIs publishes, $0.0008 per call and $0.04 per 1,000 tweets (source: twitterapis.com/pricing).

Why can a post not carry an image in one call?

Because the picture and the post are separate resources. The file has to exist on the platform, and be finished processing, before anything can reference it. So the upload call returns an identifier rather than a published post, and the create call carries that identifier instead of the bytes. Every client library that appears to do it in one step is running both calls for you underneath.

What does the upload call actually take?

A POST to the media upload route with a JSON body holding media_data, the file encoded as base64. An optional media_category field describes what the asset is. Omit the payload and the response is an explicit 400 saying to provide media_data as a base64-encoded image, which is the fastest way to confirm you are hitting the right route with the wrong shape.

How do you know the upload has finished processing?

The upload response returns a media id and a processing block. For anything that needs transcoding the asset is not immediately usable, so poll the status route with that media id until the reported state reads as succeeded. Referencing an id before that point is the common cause of a create call failing for no obvious reason, because the asset simply was not ready yet.

What credentials does an image post need?

More than a read. Public reads need only the API key. Anything that acts as an account, including uploading a file and publishing a post, runs through an X session. Register one and it is held encrypted at rest with AES-256-GCM until you replace it, or pass the session per request and it is never stored. The upload and the status poll both read through that same session.

What does an image post cost compared with a read?

Publishing sits in the premium band at $0.0016 for the create call, twice the standard read rate, because a create carries more work than a lookup. The upload and the status poll are separate calls in their own right. There is no monthly floor to clear before any of it runs, so a handful of image posts a day costs cents rather than a plan.

The three calls behind one image post

StepWhat it doesWhat comes back
UploadSends the file as base64 in media_dataA media id and a processing block
Status pollChecks the asset by media idA state that must read succeeded
CreatePublishes the post referencing the idThe published post, billed at $0.0016
CredentialAn X session, registered or per requestEncrypted at rest, or never stored
Upload the media file(s) using either the recommended chunked upload (images/GIF/video), or the older simple upload (images only).
X Developer Platform, media upload documentation. Source

Questions and answers

Can you attach an image directly in the post request?
No. The file has to be uploaded first and finish processing, and the post then references the media id that upload returned. There is no single call that accepts both the picture and the text. Libraries that look like they do are running the same two calls internally.
What format does the upload expect?
A JSON body with the file encoded as base64 in media_data, plus an optional media_category describing the asset. Sending the request without that field returns a 400 telling you to provide media_data as a base64-encoded image, which is a useful check that the route is reachable.
Why does the post fail right after a successful upload?
Usually because the asset had not finished processing. The upload returns a media id straight away, but transcoding continues afterwards. Poll the status route with that id until the state reads succeeded, then publish. Referencing an id too early is the single most common cause of this failure.
Does uploading media need more than an API key?
Yes. Public reads run on the key alone, but anything acting as an account needs an X session, either registered once and held encrypted at rest with AES-256-GCM, or passed per request and never stored. The upload, the status poll, and the create all use that session.
What does publishing a post with an image cost?
The create call sits in the premium band at $0.0016, double the standard read rate. The upload and the status poll are separate calls of their own. Nothing has to be prepaid as a monthly plan, so a low volume of image posts costs a few cents.
Is there a limit on how many image posts you can publish?
No platform window applies to publishing here, so the practical bound is credit balance. On the official API the write allowance is the constraint instead, since post creation is quoted at 10,000 per 24 hours per app with a much tighter per-user figure underneath it.

Start with $0.50 in free credits

No credit card. Roughly 12,500 tweets to test every endpoint.