Hello,
Iām trying to use the twitter media API to upload an image and iām struggling to understand how Postman is encoding the variables when using the x-www-form-urlencoded body type.
If i create a variable āmedia=iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYIIā I can generate a 200 response using the x-www-form-urlencoded body
When i put the same body in Raw with a forced x-www-form-urlencoded header I get a 401 Unauthorized (which i think is just a poor error message bubbling up giving my Auth headers arenāt changing.
I presumed this was to do with URLEncoding, so i encoded the value to the below. When i do this in the x-www-form-urlencoded tab i now get a 400 for unsupported media type, and I still get the 401 through the raw body.
Console
When i look into the console for x-www-form-urlencoded I can see the structure it is sending the body in.
However, when i replicate that in raw, i still get a 401 so its doing something different. despite the text being identical, it also looks different in the console, so iām not sure what iām doing differently here.
Top works, bottom doesnt
Does anyone know how to structure the raw body, so it will simulate the same behaviour I get when using the x-www-form-urlencoded tab?
Encoded
iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD%2BwSzIAAAABlBMVEX%2F%2F%2F%2B%2Fv7%2BjQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD%2FaNpbtEAAAAASUVORK5CYII
Request:
POST https://upload.twitter.com/1.1/media/upload.json?
Documentation:
POST media/upload | Docs | Twitter Developer Platform
any ideas? or does anyone have a working collection i can try?
Hi @scales23
It looks to me like this is being sent as JSON from the screenshots you shared. Judging with the use of the colon after media.
Also, when you say top works, bottom doesnt. o you mean the first Request Body in the below screenshot works? How is it different form the one in the bottom?
Thanks for the response @gbadebo-bello
It looks to me like this is being sent as JSON from the screenshots you shared. Judging with the use of the colon after media.
- Should it not be sent as JSON? Do you have an example of how the data should be structured for x-www-form-urlencoded?
These are the different permutations i can think of, but iām not sure what is correct here.
ākeyā:āvalueā
ākeyā:value
key:value
key:āvalueā
ākeyā=āvalueā
ākeyā=value
key=value
key=āvalueā
Also, when you say top works, bottom doesnt. o you mean the first Request Body in the below screenshot works? How is it different form the one in the bottom?
- With regards to the top and bottom screenshots. That was showing how the console looks for the two requests. I was trying to show that when I use the x-www-form-urlencoded body, the console formats the body slightly differently (and the request works), vs when i use the raw body, whilst the data is identical, the formatting is different. This might be a red herring but it was a difference i couldnāt explain.
Just looking at those requests again;
x-www-url-encoded body
Request Headers
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth *****
Cache-Control: no-cache
Postman-Token: 93a600c0-68e9-48fe-9d8d-faa34283043f
Host: upload.twitter.com
Content-Length: 141
Cookie: guest_id=v1%3A171399458995171879; lang=en
Request Body
media: āiVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYIIā
Raw Body
Request Headers
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth ****
Cache-Control: no-cache
Postman-Token: 8c1d7593-a36f-40f1-b175-27322ad09102
Host: upload.twitter.com
Content-Length: 128
Cookie: guest_id=v1%3A171399458995171879; lang=en
Request Body
media: āiVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYIIā
The key difference being the content length. The string is 128, so why does the x-www-form-urlencoded body submit a string of 141.
If i manually set a Content-Length as anything higher than 128 on my raw body request, it hangs and never completes a transaction. If i set it 128 or lower it fails in the same way as previously
What is the difference in how that is calculated compare to the raw body with a Content-Type: x-www-form-urlencoded
Hi @scales23
Iām not sure what the issue is, but Iāll keep looking.
Since youāre using the x-www-form-urlencoded body type and that works, why do you want to use a raw with a forced x-www-form-urlencoded header?
Thank you for supporting. Appreciate it.
It started out as a simple test just to prove i understand how the headers work, and has now turned into a frustrating cycle where on the face of it it should work but it doesnāt. Basically I just want to solve the problem
Iāve made a bit of progress with this using Fiddler. The format of the body is as such;
keyvalue=urlencoded(string)
i.e. media_data=iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD%2BwSzIAAAABlBMVEX%2F%2F%2F%2B%2Fv7%2BjQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD%2FaNpbtEAAAAASUVORK5CYII
Iāve also managed to get a raw body working with this format, but only when I use the authorisation header generated from the x-www-url-encoded search. When i use the one from the raw body it fails.
So my next question @gbadebo-bello is how does the oauth_signature in the Authorisation header get generated between raw / x-www-url-encoded?
Think iāve cracked it.
Looks like parameters are included in the oauth_signature generation when using x-www-form-urlencoded, but they are not when using the raw body.
This document pointed me in the right direction. The key bit being the media_data parameter in the body has to be part of the signature generation too.
The encoded parameters i used for the signature are (note alphabetical order)
media_category=tweet_image&media_data=āMediaDataā&oauth_consumer_key=āConsumer Keyā&oauth_nonce=āNonceā&oauth_signature_method=HMAC-SHA1&oauth_timestamp=āTimestampā&oauth_token=āAccess Tokenā&oauth_version=1.0
In summary the key bits that were missing that i worked through with thisā¦for anyone wanting to use the media upload endpoint;
- Body needs to be structured keyvalue=encoded(pair)
- Content-Type: application/x-www-form-urlencoded
- Content-Length header needs to be sent and the encoded length
- oauth_signature needs to be generated using both url and body parameters
1 Like
Hi @scales23. Good to see youāve been able to resolve this.
Cheers!