Uploading Base64 Encoded Image using /1.1/media/upload.json


I’m stumped why I I keep getting a 401 when trying to use “/1.1/media/upload.json” when the same authorication header works for “/1.1/statuses/home_timeline.json.”

Th header is comprised of:

  1. oauth_version
  2. oauth_consumer_key
  3. oauth_token
  4. oauth_timestamp
  5. oauth_nonce
  6. oauth_signature_method

My headers look like:

"Authorization": 'OAuth oauth_consumer_key="' + oauth_consumer_key + '", oauth_nonce=' + nonce + ', oauth_signature=' + encodedSig + ', oauth_signature_method="HMAC-SHA1", oauth_timestamp=' + timestamp + ',oauth_token="' + oauth_token + '", oauth_version="1.0"'
'Content-Transfer-Encoding': 'base64'
'Content-Type': 'application/x-www-form-urlencoded'

The only value in the body is the “media_data”: “XXXXXXXXX”. Can anyone post what the proper header is or code on how to upload a Base64 encoded string? I’m it this way because I’m on “Parse.com” and they don’t support multipart form posts.


Did you add “write” access to your application credentials? Read-only is the default.


Yes, I have read, write and direct message.


Is there an endpoint media/upload? All I see is statuses/update_with_media.


Yes, it’s here:


Per the documentation, statuses/update_with_media is now deprecated in favour of the new upload endpoint which supports multiple items attached to a tweet.

I’ll take a look into this asap.

Media/upload POST Base 64
Upload image in a tweet

Libraries taken from here: https://github.com/abraham/twitteroauth
Check your image limit here: https://dev.twitter.com/rest/reference/get/help/configuration

The glitch is to send base64_encode data and the size to not exceed the image limitation (default is 3MB) otherwise you will receive “not recognized.” error.

Here is the code (only the image upload thing) which worked for me:


$filePath = '/absolute path to the file/';
$url = 'https://upload.twitter.com/1.1/media/upload.json';
$method = 'POST';
$parameters = array(
    'media' => base64_encode(file_get_contents($filePath)),
$request = OAuthRequest::from_consumer_and_token($connection->consumer, $connection->token, $method, $url, $parameters);
$request->sign_request($connection->sha1_method, $connection->consumer, $connection->token);

$response = $connection->http($request->get_normalized_http_url(), $method, $request->to_postdata());
if ($connection->format === 'json' && $connection->decode_json) {
    $response = json_decode($response);



And using nodejs what this could to be ?


We’ve added support for uploading base64-encoded media as of today on the POST media/upload endpoint. See this post for more details.



Can you explain:

'Because the method uses multipart POST, OAuth is handled a little differently. POST or query string parameters are not used when calculating an OAuth signature basestring or signature. Only the oauth_* parameters are used.'

If i use the signature generator tool ALL parameters are USED to create the signature. https://dev.twitter.com/oauth/tools/signature-generator

But as you can see and test. It breaks the BASE64 data at 99 characters.


(edited - please read our community guidelines before posting here and respect other users, thanks)

The Signature tool pre-dates the Media upload documentation, so you should pay attention to the specific information in the endpoint documentation.

Is there a reason for building your own OAuth request, or could you use one of the third-party API client libraries that could do that heavy lifting for you?


Hi there,

I have much respect for others that’s not the issue here.The documentation is wasting my time by being not accurate and its missing tons of information. Anyway, I can’t use a third party library so I have to build it from scratch. Like i did for Facebook, Yammer, LinkedIN etc etc. And all work quite well since they have good documentation.

Actually, the generator is right. Or at least, looks right. Because If i only use the oauth_* fields to create the signature it will always fail with every request. I can however use the INIT command and other API endpoints so that way i know my signature creation is correct and your documentation fails.

Even the simple 1 file <= 3MB upload method just does not work. I get either; ‘media’ field is required (which is actually in the post body). or i get could not authenticate you (when i follow the oauth_* statement of your docs), service is busy, internal error 501 but not and never the response i expect to get when following your great documentation.

So, to make at least this simple single file upload working I want to ask you;

  • What are the mandatory parameters and how should they look;
  • What is the recommended encoding (rawurlencoding or rfc3986 )
  • What headers are used for the post (other then oAuth)
  • What parameters are used in the creation of the signature

I hope anyone here can at least answer these questions.