Change your header image
Upload an image and set it as the header (banner) of your account.
/client/profile/bannerYour account, your proxy, your risk.
Account actions run with the session cookie of your own X account and go out through your own proxy. Use only accounts you control and follow X's rules. Automated posting, following or liking can get the account limited or suspended; that is between you and X. Treat the cookie like a password: it gives full access to the account. Trial keys cannot call these endpoints.
The image is uploaded like /client/media and then set as your banner in one call. X shows headers at 3:1 (1500 x 500 recommended); x.com crops in the browser before uploading, so crop the image yourself first.
Parameters
cookiebody · string · requiredCookie header of your own logged-in X session. Must contain auth_token and ct0; guest_id is used when present.
proxybody · string · requiredYour proxy, format http://user:pass@host:port. The requests to X go out through it. Used only for this request.
mediabody · string (base64) · requiredThe image file, base64-encoded. JPEG, PNG or GIF, up to 5 MB, between 200 x 100 and 8192 x 8192 pixels (1500 x 500 recommended).
media_typebody · string · optionalMIME type, e.g. image/jpeg or image/png. Optional: the API detects the type from the file's bytes and uses the detected type if this is missing or wrong.
Body parameters are sent as a JSON object with Content-Type: application/json.
Notes
- Limits (X): JPEG, PNG or GIF, up to 5 MB, between 200 x 100 and 8192 x 8192 pixels. X does not animate GIFs in headers.
Example request
curl -X POST 'https://api.twittrapi.com/client/profile/banner' \
--header 'X-API-KEY: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{"cookie":"auth_token=...; ct0=...","proxy":"http://user:pass@host:port","media":"<base64>","media_type":"image/jpeg"}'import httpx
resp = httpx.post(
"https://api.twittrapi.com/client/profile/banner",
headers={"X-API-KEY": "YOUR_API_KEY"},
json={
"cookie": "auth_token=...; ct0=...",
"proxy": "http://user:pass@host:port",
"media": "<base64>",
"media_type": "image/jpeg",
},
timeout=60,
)
print(resp.status_code, resp.json())const resp = await fetch("https://api.twittrapi.com/client/profile/banner", {
method: "POST",
headers: { "X-API-KEY": process.env.TWITTRAPI_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
cookie: "auth_token=...; ct0=...",
proxy: "http://user:pass@host:port",
media: "<base64>",
media_type: "image/jpeg",
}),
});
console.log(resp.status, await resp.json());Base URL https://api.twittrapi.com, key in the X-API-KEY header. The SDKs do not wrap account actions, so the examples are plain HTTP calls.
Response
Wrapper built by the API: {"status_code": <X status>, "response": "<X response body as a string>"}. The HTTP status is X's status when X answered 4xx or 5xx, otherwise 200. Parse response a second time to get X's JSON. On success response is your updated user object; the new header is in profile_banner_url.
Simple format (?format=simple or X-Response-Format: simple): {data: User}: your profile with the new bannerUrl, the same User object as the read endpoints. When X reports an error inside the wrapper (for example a tweet that is already liked), the usual wrapper is returned unchanged. Schema.
In the raw format, field names and nesting come from X and can change without notice. See Response format; the simple format keeps a fixed schema.
Errors
- 400The body is not valid JSON.
- 400The file breaks X's limits (not JPEG, PNG or GIF; over 5 MB; smaller than 200 x 100 or larger than 8192 x 8192 pixels; or a damaged image header). Checked before anything is sent to X, refunded. The error names the limit and the file's value, e.g. "Banner must be between 200x100 and 8192x8192 pixels (got 120x60)" or "Profile photo must be at most 2 MB (got 3.4 MB)".
- 422cookie or proxy is missing, or the cookie has no ct0. media is missing, not valid base64, or empty. Also: the account is suspended, or X rejected the session.
- 407The proxy is unreachable or timed out.
- X'sX refused the change: answered with X's status and {"error": "X refused the profile update: <X's reason>"}; when the image upload itself fails: "X refused the image upload: <reason>".
Errors every endpoint can return (401, 402, 403, 404, 408, 409, 429, 5xx), and which of them are charged, are on the Errors page. Calls that fail with 400, 408, 409 or a 5xx error are refunded.