Docs
Upload a video

Upload a video

Upload a video in 5 MB chunks, wait for X to process it, and get a media ID.

POST/client/media/video

Your 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.

Parameters

  • cookiebody · string · required

    Cookie header of your own logged-in X session. Must contain auth_token and ct0; guest_id is used when present.

  • proxybody · string · required

    Your proxy, format http://user:pass@host:port. The requests to X go out through it. Used only for this request.

  • mediabody · string (base64) · required

    The video file, base64-encoded. MP4 or MOV, up to 512 MB (X's limit; the gateway's 100 MB body limit applies first).

  • media_typebody · string · optional

    MIME type, e.g. video/mp4 or video/quicktime. Optional: the API detects the type from the file's bytes and uses the detected type if this is missing or wrong.

  • video_duration_msbody · integer · required

    Length of the video in milliseconds. Must be under 4 hours; X allows 140 seconds without Premium and refuses longer videos itself.

Body parameters are sent as a JSON object with Content-Type: application/json.

Notes

  • Request bodies are limited to 100 MB at the gateway (413 above that). With base64 overhead that is a video of about 75 MB.
  • Limits (X): MP4 or MOV, up to 512 MB; up to 140 seconds without Premium, under 4 hours with Premium.

Example request

curl -X POST 'https://api.twittrapi.com/client/media/video' \
  --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":"video/mp4","video_duration_ms":12000}'

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.

Simple format (?format=simple or X-Response-Format: simple): {data: {mediaId, mediaKey, expiresAfterSecs}}. Pass mediaId in media_ids of /client/create or /client/reply. When X reports an error inside the wrapper (for example a tweet that is already liked), the usual wrapper is returned unchanged. Schema.

Example response coming soon.

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.
  • 422A required field is missing (including proxy), an ID is not numeric, or the cookie has no ct0. Also: the account is suspended, X rejected the session, or the text was already posted.
  • 407The proxy is unreachable or timed out.
  • 400The file breaks X's limits (not MP4 or MOV, over 512 MB, or video_duration_ms not positive or 4 hours or more). 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)".
  • 422media is not valid base64, or X reports that processing failed.
  • 408X did not finish processing in time. Refunded.
  • X'sAny status X answers with (for example 401, 403, 404): passed through with X's body.

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.