# How to Post a Tweet With an Image Using the API Canonical: https://www.twitterapis.com/answers/how-to-post-a-tweet-with-an-image-api Description: Posting an image takes two calls: upload the file for a media id, poll until processing succeeds, then create the post referencing that id. Generated: 2026-09-14T03:00:38.121Z --- 1. [Home](/) 2. / [Answers](/answers) 3. / How do you post a tweet with an image using the API? # How do you post a tweet with an image using the API? Last updated August 3, 2026 Posting an image is two steps, never one. Upload the file first to receive a media id, poll the status route until processing reports success, then create the post referencing that id. On TwitterAPIs the upload takes base64 in media\_data, the create call bills at $0.0016, and both run as an X session you register once or pass per request. Every rate here is the pricing TwitterAPIs publishes. The billed rate is $0.0008 per call; $0.04 per 1,000 tweets is derived from it at a full 20-tweet page, which is the default page size rather than a guaranteed yield (source: [twitterapis.com/pricing](/pricing)). ## Why can a post not carry an image in one call? Because the picture and the post are separate resources. The file has to exist on the platform, and be finished processing, before anything can reference it. So the upload call returns an identifier rather than a published post, and the create call carries that identifier instead of the bytes. Every client library that appears to do it in one step is running both calls for you underneath. ## What does the upload call actually take? A POST to the media upload route with a JSON body holding media\_data, the file encoded as base64. An optional media\_category field describes what the asset is. Omit the payload and the response is an explicit 400 saying to provide media\_data as a base64-encoded image, which is the fastest way to confirm you are hitting the right route with the wrong shape. ## How do you know the upload has finished processing? The upload response returns a media id and a processing block. For anything that needs transcoding the asset is not immediately usable, so poll the status route with that media id until the reported state reads as succeeded. Referencing an id before that point is the common cause of a create call failing for no obvious reason, because the asset simply was not ready yet. ## What credentials does an image post need? More than a read. Public reads need only the API key. Anything that acts as an account, including uploading a file and publishing a post, runs through an X session. Register one and it is held encrypted at rest with AES-256-GCM until you replace it, or pass the session per request and it is never stored. The upload and the status poll both read through that same session. ## What does an image post cost compared with a read? Publishing sits in the premium band at $0.0016 for the create call, twice the standard read rate, because a create carries more work than a lookup. The upload and the status poll are separate calls in their own right. There is no monthly floor to clear before any of it runs, so a handful of image posts a day costs cents rather than a plan. Publishing bills at $0.0016 a call, per our own rate card. ## The three calls behind one image post Step What it does What comes back Upload Sends the file as base64 in media\_data A media id and a processing block Status poll Checks the asset by media id A state that must read succeeded Create Publishes the post referencing the id The published post, billed at $0.0016 Credential An X session, registered or per request Encrypted at rest, or never stored > Upload the media file(s) using either the recommended chunked upload (images/GIF/video), or the older simple upload (images only). X Developer Platform, media upload documentation. [Source](https://docs.x.com/x-api/media/introduction) ## Questions and answers Can you attach an image directly in the post request? No. The file has to be uploaded first and finish processing, and the post then references the media id that upload returned. There is no single call that accepts both the picture and the text. Libraries that look like they do are running the same two calls internally. What format does the upload expect? A JSON body with the file encoded as base64 in media\_data, plus an optional media\_category describing the asset. Sending the request without that field returns a 400 telling you to provide media\_data as a base64-encoded image, which is a useful check that the route is reachable. Why does the post fail right after a successful upload? Usually because the asset had not finished processing. The upload returns a media id straight away, but transcoding continues afterwards. Poll the status route with that id until the state reads succeeded, then publish. Referencing an id too early is the single most common cause of this failure. Does uploading media need more than an API key? Yes. Public reads run on the key alone, but anything acting as an account needs an X session, either registered once and held encrypted at rest with AES-256-GCM, or passed per request and never stored. The upload, the status poll, and the create all use that session. What does publishing a post with an image cost? The create call sits in the premium band at $0.0016, double the standard read rate. The upload and the status poll are separate calls of their own. Nothing has to be prepaid as a monthly plan, so a low volume of image posts costs a few cents. Is there a limit on how many image posts you can publish? The same 600-requests-a-minute ceiling applies to publishing as to every other route, so in practice the bound is your credit balance. On the official API the write allowance is the constraint instead, since post creation is quoted at 10,000 per 24 hours per app with a much tighter per-user figure underneath it. ## Keep reading - [Per-call pricing](/pricing?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-post-a-tweet-with-an-image-api) - [Best practices for production jobs](/blogs/twitterapis-best-practices?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-post-a-tweet-with-an-image-api) - [Quickstart](/quickstart?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-post-a-tweet-with-an-image-api) - [REST API documentation](https://docs.twitterapis.com/docs) - [How do you send a DM with the Twitter API?](/answers/how-to-send-a-dm-with-the-twitter-api?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-post-a-tweet-with-an-image-api) - [How do you download a video from a tweet?](/answers/how-to-download-a-video-from-a-tweet-api?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-post-a-tweet-with-an-image-api) ### Start with $0.50 in free credits No credit card. Roughly 12,500 tweets to test every endpoint. [Get your API key](/signup?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-post-a-tweet-with-an-image-api)[See pricing](/pricing?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-post-a-tweet-with-an-image-api) [ TwitterAPIs ](/) The cheapest pay-as-you-go Twitter and X API. $0.0008 per call, which works out to $0.04 per 1,000 tweets on a full 20-tweet page. No subscriptions and no developer account. ## Product / API - [Pricing](/pricing) - [Cost Calculator](/twitter-api-cost-calculator) - [Rate Limits](/twitter-api-rate-limits) - [MCP Server](/mcp) - [Integrations](/integrations) - [Language Clients](/sdk) - [Changelog](/changelog) - [Status](/status) ## Developers - [Documentation](https://docs.twitterapis.com) - [API Reference](https://docs.twitterapis.com/docs/reference/search/tweet-advanced-search) - [User Info](https://docs.twitterapis.com/docs/reference/user-reads/user-info) - [User Tweets](https://docs.twitterapis.com/docs/reference/user-reads/user-tweets) - [Advanced Search](https://docs.twitterapis.com/docs/reference/search/tweet-advanced-search) - [Verified Followers](https://docs.twitterapis.com/docs/reference/follower-graph/user-verified-followers) ## Resources / Compare - [Answers](/answers) - [Reviews](/reviews) - [Free Tools](/tools) - [Twitter ID Finder](/tools/twitter-id-finder) - [Get a Twitter API Key](/twitter-api-key) - [Official X API Comparison](/twitter-api-pricing) - [Twitter API Use Cases](/twitter-api-usecases) - [Twitter API Alternatives](/twitter-api-alternatives) - [Twitter Unofficial API](/twitter-unofficial-api) - [Twitter Free API](/twitter-free-api) - [TwitterAPIs vs twitterapi.io](/twitterapis-vs-twitterapi-io) - [TwitterAPIs vs GetXAPI](/twitterapis-vs-getxapi) - [TwitterAPIs vs TweetAPI](/twitterapis-vs-tweetapi) - [TwitterAPIs vs TwexAPI](/twitterapis-vs-twexapi) - [TwitterAPIs vs RapidAPI](/twitterapis-vs-rapidapi) ## Legal - [About](/about) - [Security](/security) - [Trust](/privacy-and-data-handling) - [Terms of Service](/terms-of-service) - [Affiliates](/affiliates) - [Contact](/contact) - [Jobs](/jobs) © 2026 TwitterAPIs. All rights reserved. TwitterAPIs is an independent third-party API for developers and researchers. Not affiliated with, endorsed by, or sponsored by X Corp. All systems operational