X write
Twitter media upload API for tweets, replies & DMs
Use the Twitter media upload API for images, GIFs, and MP4 videos. Return mediaUrl for tweets and replies or mediaId for one direct message attachment.
- 200
- 202
- 400
- 401
- 402
- 403
- 404
- 409
- 422
- 429
- 500
- 503
POST
Twitter media upload API for tweets, replies & DMs
10 credits per call · All plans from $0.00012/credit
POST /x/media.
This Twitter API media upload route accepts one local file or hosted HTTPS media URL.
A Twitter API upload media request uses one connected X account.
A completed upload returns a media ID and reusable mediaUrl.
Skip this endpoint when a tweet already has public HTTPS media URLs. Call
Create Tweet directly with those URLs.
Use the Twitter API upload media workflow
Sendmultipart/form-data for a file. Send application/json for a hosted
URL. Authenticate with an API key or OAuth bearer token. Add one
Idempotency-Key per intended upload. Any HTTP client works.
Upload a hosted media URL
statusUrl after 202. Store
mediaId, mediaUrl, the account, and the idempotency key.
Handle media types, large videos & multiple images
Supported media files include AVIF, GIF, JPEG, PNG, WebP, and MP4. Every media type requires validation before upload. Match the content type to the file. Use a public URL. Private and reserved addresses are rejected. The download timeout is 30 seconds. The file limit is 15,728,640 bytes. Setis_long_video to true for MP4 files longer than 140 seconds.
Xquik handles the chunked upload and media category internally.
Send one request, then poll its lifecycle.
For multiple images, call once per file. Collect up to 4 mediaUrl values.
Send them together in Create Tweet. DMs accept exactly one media ID. Schedulers
store mediaUrl until send time. This endpoint does not schedule tweets.
Store the Twitter API media upload receipt
Store the account, success, source reference, and idempotency key with each
receipt. For replies, add
reply_to_tweet_id in Create Tweet.
Never send media_ids to Create Tweet. Use public mediaUrl values.
Tweet and reply writes cost 30 credits, plus media surcharges.
DM writes cost 10 credits.
Fix Twitter media upload API errors
Fix invalid fields or content types after 400. Replace credentials after 401. Add credits after 402. Reconnect the X account after 403. Connect a missing account after 404. Keep the original action after 409. Replace unreachable or private URLs after422 media_download_failed. Replace rejected media after
other 422 errors. Honor Retry-After after 429. Check safeToRetry after 500
or 503.
Headers
string
required
Your API key. OAuth bearer authentication is also supported. Generate a key from the dashboard.
string
required
Unique key for this intended write. Reuse it only for an exact network replay.
string
required
Use
multipart/form-data when uploading a file. Use application/json when providing a URL.Body
string
required
A connected X username or account ID. The account performs the upload.
binary
Required without
url. Accepts AVIF, GIF, JPEG, PNG, WebP, or MP4.string
Required without
file. Provide a public HTTPS URL. AI agents and MCP clients can send URLs instead of binary uploads.boolean
Multipart MP4 uploads only. Set
true when the video exceeds 140 seconds. Defaults to false.Response
- 404 Account not found
Connect the requested account, then submit a newly approved write.
Durable write recovery
- Store
id, the nestedhashinrequest,billing, andstatusUrl. - Poll after
Retry-AfterorpollAfterMswhenterminalisfalse. - Trust
safeToRetryandnextActionbefore any new write.
200 Terminal or 202 active
Store terminal results. Poll active actions without creating another write.- After HTTP
200, store the result and settled billing. - After HTTP
202, poll the same action. Never submit another write. - After HTTP
400, fix the named field. Use a new idempotency key. - After HTTP
401, fix authentication. Do not retry unchanged. - After HTTP
402, fund the account before another write. - After HTTP
403, reconnect the account. - After HTTP
409, keep the original action. Use a new key for new input. - After HTTP
422, fix the rejected request before retrying. - After HTTP
429, wait forRetry-After. Preserve the same key. - After HTTP
500, retry only whensafeToRetryistrue. - After HTTP
503, poll whileterminalisfalse.
- 200
- 202
- 400
- 401
- 402
- 403
- 404
- 409
- 422
- 429
- 500
- 503
Twitter media upload API for tweets, replies & DMs