Create Tweet
Post tweets with text, images, and videos via API. $0.002 per call. GetXAPI create tweet endpoint with media upload examples.
/twitter/tweet/createThis endpoint costs $0.002 per API call.
For 100% success rate, pass your own proxy via the proxy field. Using a custom proxy posts the tweet from your own clean IP and gives the most reliable results.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
auth_token | string | Yes | User's auth token |
ct0 | string | No | Optional current CSRF token cookie. When provided with twid, skips server-side credential resolution. |
twid | string | No | Optional current user ID cookie, for example u=1234567890. Must be provided with ct0. |
text | string | Yes | Tweet text |
reply_to_tweet_id | string | No | Tweet id to reply to |
quote_tweet_url | string | No | Full URL of the tweet to quote (e.g. https://x.com/username/status/123456) |
quote_tweet_id | string | No | Tweet ID to quote — resolved to URL automatically. Use quote_tweet_url for faster requests |
proxy | string | No | Your proxy URL (e.g. http://user:pass@host:port) |
media_ids | array of strings | No | Pre-uploaded Twitter media ids |
media_urls | array of strings | No | URLs to images/videos — fetched and uploaded automatically |
media | array of objects | No | Base64-encoded media — uploaded automatically |
media[].data | string | Yes* | Base64-encoded file content |
media[].type | string | Yes* | MIME type (e.g. image/png, video/mp4) |
verify_premium | boolean | No | Default false. When true and a long video (>2:20) is detected in the upload, we verify the auth_token's account is on X Premium and return 403 if it isn't. See Long video. |
community_id | string | No | Numeric community ID. Posts the tweet to a community that the auth_token's user is already a member of. See Community posting. |
* Required when using the media field.
Notes
- If you already have current
ct0andtwid, send both to skip the extra server-side credential bootstrap fromauth_token. If either one is omitted, the server resolves them fromauth_tokenas before. Stale or invalid supplied values are not validated upfront and may fail on the actual Twitter action instead of returning an early401. - Creates a tweet for the auth token owner.
- Proxy: Pass your own proxy URL to post the tweet using your IP instead of the server's.
- Quote tweets: Use
quote_tweet_urlto quote by URL, orquote_tweet_idto quote by ID (resolved to URL automatically). - Supports 3 ways to attach media (can be mixed in a single request):
media_ids— use if you already have Twitter media idsmedia_urls— pass image/video URLs, the server fetches and uploads them to Twittermedia— pass base64-encoded files inline
- For videos, the server handles chunked upload (INIT → APPEND → FINALIZE) and waits for processing to complete.
- If X rejects the mutation, this endpoint returns
502.
Long video (2:20–4 hours)
Long videos are handled automatically. We parse the duration from the MP4 header and route uploads longer than 2 minutes 20 seconds through X's long-video pipeline internally. No extra fields needed — just send your video the same way you'd send a short one.
For non-MP4 files or unusual encodings where duration can't be parsed, the standard short-video upload path is used as a fallback (and would fail at the tweet attachment step if the actual video is longer than 2:20).
verify_premium — opt-in Premium check
Pass verify_premium: true to confirm the auth_token's account is on X Premium before performing a long-video upload:
- We detect the video duration. If it's >2:20, we verify the account's Premium status before uploading.
- If the account is not on Premium, we return
403and don't start the upload — your credits are not deducted. - For videos ≤2:20, the check is skipped (no Premium requirement).
- The check runs against the caller's own
auth_token(counts toward the auth_token's rate limit, not yours). - Results are cached for 1 hour per
auth_token, so repeated calls aren't penalized.
Community posting
Pass community_id to post into one of X's communities. The numeric ID can be lifted from the community URL on x.com — e.g. https://x.com/i/communities/1641395384835780609 → community_id: "1641395384835780609".
Requirements & behavior:
- The
auth_token's user must already be a member of the community. Non-members get a403from X — we do not auto-join. - Both short (≤280) and long-form (>280, requires Premium) posts to a community are supported. We auto-pick the right underlying mutation based on text length.
- Moderation queue: some communities require moderator review before posts go live. When that happens, X returns a successful response with no tweet ID. We surface this as HTTP 202 with
status: "pending_moderation"and thecommunity_idechoed back. You won't get atweet_iduntil/unless the moderator approves the post.
Media Limits
Images (all tiers)
| Limit | |
|---|---|
| Max per tweet | 4 images |
| File size | 5 MB (JPEG/PNG), 15 MB (GIF) |
| Formats | JPEG, PNG, GIF, WEBP |
| Recommended size | 1600 × 900 px (16:9) |
GIFs (all tiers)
| Limit | |
|---|---|
| Max per tweet | 1 GIF |
| File size | 15 MB (mobile), 5 MB (web) |
Videos
| Free | Premium | Premium+ | |
|---|---|---|---|
| Max duration | 2 min 20 sec | ~3 hours | 4 hours (web/iOS) |
| File size | 512 MB | 8 GB | 16 GB |
| Android max | 2:20 | 10 min | 10 min |
| Resolution | 1080p | 1080p (≤2h), 720p (2–4h) | Same as Premium |
| Formats | MP4, MOV | MP4, MOV | MP4, MOV |
| Max per tweet | 1 video | 1 video | 1 video |
Limits depend on the X account tier of the auth_token owner. Most accounts are free tier (2 min 20 sec video, 512 MB max).
Response (200)
{
"status": "success",
"msg": "Tweet created successfully",
"data": {
"id": "2019384131067818211",
"text": "Hello world!",
"createdAt": "Thu Feb 05 12:14:29 +0000 2026",
"pending_moderation": false,
"community_id": null
}
}When community_id is provided and the post lands directly in the community, community_id echoes the ID in the response.
Response (202) - Community moderation queue
Returned only when community_id is provided and the target community has moderator approval enabled. The post was accepted by X but isn't visible yet — no id is issued until a moderator approves.
{
"status": "pending_moderation",
"msg": "Post submitted to community moderator queue. It will appear once approved.",
"data": {
"id": null,
"text": "your text",
"createdAt": null,
"pending_moderation": true,
"community_id": "1641395384835780609"
}
}Error Responses
400 - Missing fields
{
"error": "Missing required field: text"
}401 - Invalid auth_token
{
"error": "Invalid auth_token - could not extract userId"
}409 - Duplicate tweet
X rejected the post because the exact same text was already tweeted recently from that account. X blocks identical back-to-back tweets as spam prevention. Change the text slightly (add a timestamp, vary the wording) or wait ~15 minutes for X's duplicate window to expire.
{
"error": "Status is a duplicate.",
"twitter_error_code": 187
}403 - Not a community member
You passed community_id for a community the auth_token's user isn't a member of (or has been restricted from). X's code 440 is mapped to HTTP 403 here.
{
"error": "Authorization: User is not authorized to post to this community (440)",
"twitter_error_code": 440
}403 - Reply restricted
The original tweet author restricted who can reply to their tweet.
{
"error": "Authorization: The original Tweet author restricted who can reply to this Tweet. (433)",
"twitter_error_code": 433
}429 - Daily tweet limit
The account has hit X's daily posting cap (~2400 tweets/day). Wait and retry later.
{
"error": "You are over daily status update limit.",
"twitter_error_code": 344
}503 - Try again later
{
"error": "Action could not be completed at this time. Please try again later."
}502 - Mutation rejected by X
{
"error": "Tweet creation failed - Twitter did not return a tweet ID"
}403 - verify_premium failed
verify_premium: true was set, and the auth_token's account is not on X Premium. Returned before the upload starts — credits are not deducted.
{
"error": "Account is not X Premium. Long-video upload (>2:20) is intended for Premium accounts to avoid risking the account. Either remove `verify_premium`, use a video ≤2:20, or use a Premium account."
}400 - Long video with unparseable duration
If you upload a video whose duration we can't parse from the MP4 header (unusual encoding, fragmented MP4, corrupted file), we fall back to the standard short-video path. If the video is actually longer than 2:20, Twitter accepts the upload but rejects the tweet attachment with error 324:
{
"error": "BadRequest: Duration too long, maximum:2.minutes+20.seconds, actual:3.minutes (MediaId: snf:2058029045372379136) (324)",
"twitter_error_code": 324
}If you key error handling off the Twitter code, use the twitter_error_code field — the human message format may change without notice. This case is rare; standard MP4 files always parse cleanly.
Examples
Text only
curl -X POST "https://api.getxapi.com/twitter/tweet/create" \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_token": "your_auth_token",
"text": "Hello world!"
}'const response = await fetch("https://api.getxapi.com/twitter/tweet/create", {
method: "POST",
headers: {
Authorization: "Bearer API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
auth_token: "your_auth_token",
text: "Hello world!",
}),
});
const data = await response.json();
console.log(data);import requests
response = requests.post(
"https://api.getxapi.com/twitter/tweet/create",
headers={"Authorization": "Bearer API_KEY"},
json={
"auth_token": "your_auth_token",
"text": "Hello world!",
},
)
print(response.json())With media URL
curl -X POST "https://api.getxapi.com/twitter/tweet/create" \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_token": "your_auth_token",
"text": "Check this out",
"media_urls": ["https://example.com/photo.jpg"]
}'With base64 media
curl -X POST "https://api.getxapi.com/twitter/tweet/create" \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_token": "your_auth_token",
"text": "Photo upload",
"media": [{"data": "iVBORw0KGgo...", "type": "image/png"}]
}'Quote tweet
curl -X POST "https://api.getxapi.com/twitter/tweet/create" \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_token": "your_auth_token",
"text": "Interesting take!",
"quote_tweet_url": "https://x.com/elonmusk/status/2019264360682778716"
}'With your own proxy
curl -X POST "https://api.getxapi.com/twitter/tweet/create" \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_token": "your_auth_token",
"proxy": "http://user:pass@host:port",
"text": "Posted via my own proxy!"
}'Reply with media
curl -X POST "https://api.getxapi.com/twitter/tweet/create" \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_token": "your_auth_token",
"text": "Great thread!",
"reply_to_tweet_id": "2019264360682778716",
"media_urls": ["https://example.com/reaction.mp4"]
}'Long video (3 minutes)
Posting a 3-minute video. We auto-detect the duration from the MP4 header and route it through X's long-video pipeline internally.
curl -X POST "https://api.getxapi.com/twitter/tweet/create" \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_token": "your_auth_token",
"text": "3-minute deep dive",
"media_urls": ["https://example.com/long-video.mp4"]
}'Long video with Premium check
Same as above, but ask us to verify Premium before uploading. Returns 403 if the account is not on Premium — credits are not deducted.
curl -X POST "https://api.getxapi.com/twitter/tweet/create" \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_token": "your_auth_token",
"text": "3-minute deep dive",
"media_urls": ["https://example.com/long-video.mp4"],
"verify_premium": true
}'Post to a community
The auth_token's user must already be a member of the community.
curl -X POST "https://api.getxapi.com/twitter/tweet/create" \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_token": "your_auth_token",
"text": "Hello from the API",
"community_id": "1641395384835780609"
}'