Update Banner API
Replace the wide header image on the account behind your registered session. Send the image base64-encoded in the request body; there is no URL-fetch form and no multipart form. Billed at $0.0016 per call. Cost: $0.0016 per call.
POST user/update_banner replaces the wide header image on the account behind your registered twitterapis session. It takes one field, banner, holding the base64-encoded image bytes, and returns ok. The change is immediate and has no undo, so read your current cover_picture with user/info first if you may want it back. It costs $0.0016 a call.
Authorization
bearerAuth 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/user/update_banner" \ -H "Content-Type: application/json" \ -d '{ "banner": "iVBORw0KGgoAAAANSUhEUgAA..." }'{ "ok": true}{ "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
| Unit | Price |
|---|---|
| Per call | $0.0016 |
| Per 1,000 calls | $1.60 |
When to use
Use it to set your own account's header image, for example swapping a campaign banner your system already schedules. It only ever writes the account behind your session. To change the round profile picture instead, use user/update_avatar; to change name, bio, location or link, use user/update_profile.
Notes
- banner is required. A request carrying none of banner, image or data is refused with 400 before anything is sent upstream, and is not billed.
- An image X cannot decode is refused upstream with an error, not with ok: false. Verified against a deliberately malformed payload and against an empty one, both of which were refused.
- Needs a session for the account you are acting 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.
- This takes effect immediately on x.com and there is NO UNDO. X keeps no history of a previous banner, so if you may want the old image back, fetch cover_picture from user/info and save the file before you call this. A successful write DROPS the cached user/info entry for the account, so the read-back below is immediately correct in the ordinary case. One honest limit: that cache lives in the process that served the write, so if your read lands on another instance you may see the previous value for up to two minutes. If a read-back looks unchanged, re-read after the window rather than concluding the write failed. Treating a stale read as a real absence is what destroyed a brand banner once already. Losing one this way is not hypothetical: it is why this note is here. A successful write DROPS the cached user/info entry for the account, so the read-back below is immediately correct in the ordinary case. One honest limit: that cache lives in the process that served the write, so if your read lands on another instance you may see the previous value for up to two minutes. If a read-back looks unchanged, re-read after the window rather than concluding the write failed. Treating a stale read as a real absence is what destroyed a brand banner once already.
- READ THE BANNER BACK WITH user/info, not with anything else. At least one of X's own endpoints reports this field as empty for accounts that plainly have a banner, so a read that returns nothing is not evidence the account has none. user/info is GraphQL-backed and reports it as cover_picture. Allow for the cache window noted below before treating an unchanged value as a failed write.
Related endpoints
- Update Avatar: Replace your own profile picture with a base64-encoded image.
- Update Profile: Change your own display name, bio, location or link. A PARTIAL update.
- User Info by Username: Fetch a full profile by @handle.
FAQ
Can I pass a URL instead of base64?
No. The banner field holds base64-encoded image bytes in the JSON request body. There is no URL-fetch form and no multipart upload; encode the file before you send it.
How do I confirm the new banner actually applied?
Read the account back with user/info and check cover_picture. Use that field specifically: at least one of X's own endpoints reports it empty for accounts that plainly have a banner, so an empty answer from somewhere else does not mean the account has none. The write clears the cached entry, so the read is normally current; if it looks unchanged, re-read after about two minutes before concluding the write failed.
Can I restore my previous banner?
Only if you saved it yourself. X keeps no history, so once the new image is set the old URL stops resolving and the file is gone from our side and yours. Fetch cover_picture from user/info and download it before you call this if that matters.
What size should the image be?
X renders the header as a wide strip, so a 3:1 image is the shape that fills it without cropping; 1500x500 is a common choice and is what our own verification used. X rejects a payload it cannot decode with an error rather than accepting it silently.
Update Avatar POST
Replace the profile picture on the account behind your registered session. Send the image base64-encoded in the request body; there is no URL-fetch form and no multipart form. Billed at $0.0016 per call. Cost: $0.0016 per call.
Overview
Direct Messages: Read your account's DM inbox and the message history of a single conversation, and send new messages, all acting as the account behind your registered session.