Working with statuses/update_with_media

episod
@episod Taylor Singletary

Attaching media to Tweets with POST statuses/update_with_media is easy. A few pointers before getting started:

  • POST statuses/update_with_media is only available on the upload.twitter.com host. You must use upload.twitter.com for this method and this method alone. Status updates without media should still be performed on api.twitter.com.
  • 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. (see examples below)
  • Maximum file size is available in the "photo_size_limit" field from GET help/configuration
  • Maximum number of media (currently 1) per status update is in the "max_media_per_upload" field from GET help/configuration
  • Users have a separate, published daily media upload limit that is indepedent of their unpublished daily status update limits. Details on these limits are communicated in the HTTP headers detailed on POST statuses/update_with_media.

To illustrate the upload process, I've decided to post a status update: "Don't slip up" with a picture of Dick Van Dyke having fallen over an ottoman. The following code sample, which works well with @themattharris' tmhOAuth ( http://github.com/themattharris/tmhOAuth ) demonstrates the process.

  1. require '../tmhOAuth.php';
  2. require '../tmhUtilities.php';
  3. $tmhOAuth = new tmhOAuth(array(
  4.   'consumer_key'    => 'YOUR_CONSUMER_KEY',
  5.   'consumer_secret' => 'YOUR_CONSUMER_SECRET',
  6.   'user_token'      => 'AN_ACCESS_TOKEN',
  7.   'user_secret'     => 'AN_ACCESS_TOKEN_SECRET',
  8. ));
  9.  
  10. // we're using a hardcoded image path here. You can easily replace this with an uploaded image-see images.php example)
  11. // 'image = "@{$_FILES['image']['tmp_name']};type={$_FILES['image']['type']};filename={$_FILES['image']['name']}",
  12.  
  13. $image = "./dickvandyke.jpg';
  14.  
  15. $code = $tmhOAuth->request('POST', 'https://upload.twitter.com/1/statuses/update_with_media.json',
  16.   array(
  17.     'media[]'  => "@{$image}",
  18.     'status'   => "Don't slip up" // Don't give up..
  19.   ),
  20.   true, // use auth
  21.   true  // multipart
  22. );
  23.  
  24. if ($code == 200) {
  25.   tmhUtilities::pr(json_decode($tmhOAuth->response['response']));
  26. } else {
  27.   tmhUtilities::pr($tmhOAuth->response['response']);
  28. }

This process would create a signature base string containing only the OAuth-related fields, as so:

POST&http%3A%2F%2Fupload.twitter.com%2F1%2Fstatuses%2Fupdate_with_media.json&oauth_consumer_key%3DmbmuCGVFTGHZOo5zr5Sx5A%26oauth_nonce%3Df9685243ba64308204b1c14a05950b09%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1313443626%26oauth_token%3D119476949-KQjqYB1QCSC9ZtaTI8RRDDRJdSgk8hMcT4BJMEWi%26oauth_version%3D1.0

Our HTTP connection would look something like (actual multi-part data snipped for readability):

POST http://upload.twitter.com/1/statuses/update_with_media.json HTTP/1.1
User-Agent: themattharris' HTTP Client
Host: upload.twitter.com
Accept: /
Proxy-Connection: Keep-Alive
Authorization: OAuth oauth_consumer_key="mbmuCGVFTGHZOo5zr5Sx5A", oauth_nonce="f9685243ba64308204b1c14a05950b09", oauth_signature="LX%2BcnRvzT5Rm%2BYkPzdhX6I%2Bt9oo%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1313443626", oauth_token="119476949-KQjqYB1QCSC9ZtaTI8RRDDRJdSgk8hMcT4BJMEWi", oauth_version="1.0"
Content-Length: 34411
Content-Type: multipart/form-data; boundary=----------------------------9fa90e137c50
...

In response, the server sends me:

  1. {
  2.     "text":"Don't slip up. http:\/\/t.co\/PjXqx8p",
  3.     "id_str":"103216165765136386",
  4.     "in_reply_to_status_id":null,
  5.     "favorited":false,
  6.     "in_reply_to_status_id_str":null,
  7.     "created_at":"Mon Aug 15 21:27:06 +0000 2011",
  8.     "entities":
  9.     {
  10.         "hashtags":
  11.         [
  12.         ],
  13.         "media":
  14.         [
  15.             {
  16.                 "type":"photo",
  17.                 "url":"http:\/\/t.co\/PjXqx8p",
  18.                 "media_url":"http:\/\/p.twimg.com\/AW6yjk_CQAE0SjQ.jpg",
  19.                 "indices":
  20.                 [
  21.                     15,
  22.                     34
  23.                 ],
  24.                 "id_str":"103216165769330689",
  25.                 "expanded_url":"http:\/\/twitter.com\/oauth_dancer\/status\/103216165765136386\/photo\/1",
  26.                 "display_url":"pic.twitter.com\/PjXqx8p",
  27.                 "media_url_https":"https:\/\/p.twimg.com\/AW6yjk_CQAE0SjQ.jpg",
  28.                 "sizes":
  29.                 {
  30.                     "thumb":
  31.                     {
  32.                         "w":150,
  33.                         "h":150,
  34.                         "resize":"crop"
  35.                     },
  36.                     "small":
  37.                     {
  38.                         "w":500,
  39.                         "h":375,
  40.                         "resize":"fit"
  41.                     },
  42.                     "large":
  43.                     {
  44.                         "w":500,
  45.                         "h":375,
  46.                         "resize":"fit"
  47.                     },
  48.                     "medium":
  49.                     {
  50.                         "w":500,
  51.                         "h":375,
  52.                         "resize":"fit"
  53.                     }
  54.                 },
  55.                 "id":103216165769330689
  56.             }
  57.         ],
  58.         "urls":
  59.         [
  60.         ],
  61.         "user_mentions":
  62.         [
  63.         ]
  64.     },
  65.     "in_reply_to_screen_name":null,
  66.     "source":"\u003Ca href=\"http:\/\/thisismywebsite.com\" rel=\"nofollow\"\u003ETesting app by episod again\u003C\/a\u003E",
  67.     "in_reply_to_user_id_str":null,
  68.     "contributors":null,
  69.     "place":null,
  70.     "retweeted":false,
  71.     "in_reply_to_user_id":null,
  72.     "geo":null,
  73.     "user":
  74.     {
  75.         "follow_request_sent":false,
  76.         "contributors_enabled":false,
  77.         "favourites_count":3,
  78.         "profile_sidebar_fill_color":"DDEEF6",
  79.         "url":"http:\/\/bit.ly\/oauth-dancer",
  80.         "profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/730275945\/oauth-dancer_normal.jpg",
  81.         "location":"San Francisco,
  82.          CA",
  83.         "id_str":"119476949",
  84.         "notifications":false,
  85.         "profile_background_tile":true,
  86.         "description":"",
  87.         "show_all_inline_media":false,
  88.         "geo_enabled":true,
  89.         "lang":"en",
  90.         "created_at":"Wed Mar 03 19:37:35 +0000 2010",
  91.         "profile_link_color":"0084B4",
  92.         "profile_image_url":"http:\/\/a2.twimg.com\/profile_images\/730275945\/oauth-dancer_normal.jpg",
  93.         "listed_count":0,
  94.         "profile_sidebar_border_color":"C0DEED",
  95.         "default_profile":false,
  96.         "time_zone":null,
  97.         "screen_name":"oauth_dancer",
  98.         "profile_use_background_image":true,
  99.         "statuses_count":50,
  100.         "friends_count":12,
  101.         "profile_background_color":"C0DEED",
  102.         "protected":false,
  103.         "default_profile_image":false,
  104.         "following":false,
  105.         "verified":false,
  106.         "profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/80151733\/oauth-dance.png",
  107.         "followers_count":19,
  108.         "name":"OAuth Dancer",
  109.         "id":119476949,
  110.         "is_translator":false,
  111.         "profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/80151733\/oauth-dance.png",
  112.         "utc_offset":null,
  113.         "profile_text_color":"333333"
  114.     },
  115.     "retweet_count":0,
  116.     "coordinates":null,
  117.     "truncated":false,
  118.     "id":103216165765136386,
  119.     "possibly_sensitive":false
  120. }

You can find the resultant tweet here: http://twitter.com/#!/oauth_dancer/status/103216165765136386

Let us know how POST statuses/update_with_media works for you and if you encounter any difficulties. Thanks!

51 weeks 21 hours ago

Replies

GXDiego
@GXDiego Diego Gonzalez

Excellent news. let's try. Thanks!

51 weeks 20 hours ago
arpad45
@arpad45 rac

ahoj

49 weeks 3 days ago
tapbot_paul
@tapbot_paul Paul Haddad

I appreciate posting this along with the sample/headers. Any guidance on when to expect max_media_per_upload to be increased?

51 weeks 20 hours ago
TvdW
@TvdW Tom van der Woerdt

{"request":"\/1\/statuses\/update_with_media.json","error":"Missing or invalid url parameter."}

It's possible that my request is a little bit malformed (it's proper HTTP but I'm uploading the status as text/plain) but this error seems like it could be more helpful.

51 weeks 20 hours ago
jkalucki
@jkalucki John Kalucki

While anything is possible, it's unlikely that max_media_per_upload will be increased anytime soon. Of course, hard coding these values is rarely a good long-term idea.

51 weeks 20 hours ago
tapbot_paul
@tapbot_paul Paul Haddad

OK what about guidance on what to do if the user wants to upload more than one picture. Would you guys expect it to post one via Photos and another via another service, or both via another service?

51 weeks 20 hours ago
TvdW
@TvdW Tom van der Woerdt

Without the ability to upload multiple images, pic.twitter.com isn't a serious replacement for yfrog and/or twitpic.

Also: what about official apps? Do those get the ability to upload multiple pictures? They currently have that, but are you going to strip that out? In the past we've seen that Twitter likes replacing third party features with their own features...

51 weeks 20 hours ago
jkalucki
@jkalucki John Kalucki

All apps, Twitter owned or third-party, will only be able to support one photo per Tweet with this new endpoint.

51 weeks 20 hours ago
TvdW
@TvdW Tom van der Woerdt

Thanks John, but I meant via other services. For me as an app developer it's important to know what the Twitter apps are going to do. Will the Yfrog/Twitpic implementation in the Twitter for iPhone be removed or will the pic.twitter.com be an addition to the current upload services?

51 weeks 19 hours ago
tapbot_paul
@tapbot_paul Paul Haddad

Am I missing something or would an HTTP request be hijack-able if we're not signing the status, etc.. parts of the post? A man in the middle type attack could grab the post and send in its own status/image instead.

Not a huge issue given everyone should be using HTTPS, but just wanted to know if I'm misunderstanding it.

51 weeks 20 hours ago
TvdW
@TvdW Tom van der Woerdt

You are understanding that correctly. However, the OAuth 1.0 specification explicitly mentions that you only sign urlencoded formdata.

51 weeks 19 hours ago
tapbot_paul
@tapbot_paul Paul Haddad

Or GET parameters, though I'm guessing that'd cause other issues.

Perhaps the docs could use a strong warning about only using this method via HTTPS in a production app?

51 weeks 19 hours ago
TvdW
@TvdW Tom van der Woerdt

Actually, posting the status as a GET parameter should work fine, but I doubt you can post the image there too.

51 weeks 19 hours ago
jftest
@jftest just testing

Hi. Could I impose on you to post an upload-payload example that is complete except for the binary data of the image being excised, using both the Authentication header method, and the query-string (sent as form data) method? I'm getting a 406/Unacceptable reply on a call that seems correct, but it's easy enough that I'm missing something that a full example would help.

Thanks.
Jeffrey Friedl

51 weeks 18 hours ago
everpix
@everpix Everpix

I'm trying to use this API from Google API. I am re-using code I had written to POST a photo to Flickr which is also over oauth and with a multipart/form-data format.
Unfortunately, I'm getting "Invalid authorization header" and I absolutely don't understand why.

Here's the full POST data (I only stripped most of the image data):

Making HTTP request:
host = upload.twitter.com
url = https://upload.twitter.com/1/statuses/update_with_media.json
payload = --MsCFc4zoZwMK76tmvFJvTw\r\nContent-Disposition: form-data; name="status"\r\n\r\nCheck out my photo\r\n--MsCFc4zoZwMK76tmvFJvTw\r\nContent-Disposition: form-data; name="media[]"; filename="Photo.jpg"\r\nContent-Type: image/jpeg\r\n\r\n\xff\xd8\xff\xe0\x00\x10...\xd9\r\n--MsCFc4zoZwMK76tmvFJvTw--
headers = {'Content-Length': '184213', 'Accept-Encoding': 'gzip', 'User-Agent': 'AppEngine-Google; (+http://code.google.com/appengine)', 'Host': 'upload.twitter.com', 'Content-Type': 'multipart/form-data; boundary=MsCFc4zoZwMK76tmvFJvTw', 'Authorization': 'OAuth oauth_consumer_key="IkIZwr9DDZvsB97A671LA", oauth_nonce="15952522287459895521", oauth_signature="tk7iEXMK8l1dUtpTNq2nJzTfGqY=", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1313470239", oauth_token="220186573-YZVqXFd4N8w40mteqY3AKoNXs6DcByt7I4ud88Hl", oauth_version="1.0"'}

Any help appreciated!

51 weeks 14 hours ago
episod
@episod Taylor Singletary

When you actually send your HTTP headers, do you percent encode them first? For example, the equals ("=") character in your signature should be "%3D"

51 weeks 5 hours ago
itok_twit
@itok_twit itok@いとーけー

I got an error "Status is a duplicate" when continuously post different pictures with empty status (or same message such as the same hashtag).
Is this by design? Or, what measures are available?

51 weeks 12 hours ago
jkalucki
@jkalucki John Kalucki

Do you get this error if you vary the tweet text?

51 weeks 5 hours ago
itok_twit
@itok_twit itok@いとーけー

No, of course, the error is not occurred with different text. But, I want to post different pictures with the same tweet text.

51 weeks 1 hour ago
jkalucki
@jkalucki John Kalucki

This is odd, because on twitter.com, you can have the same tweet text, as the link varies. Something else must be wrong, but I've no idea what the problem could be.

51 weeks ago
rschu
@rschu René Schulte

You know what really would be awesome. Switching to OAuth 2.0 :)

What is the current X-MediaRateLimit-Remaining?

51 weeks 11 hours ago
jkalucki
@jkalucki John Kalucki

Currently, X-MediaRateLimit-Remaining is 30/day, but it's subject to change at any time.

51 weeks 5 hours ago
richardhyland
@richardhyland Richard Hyland

I presume from this we also can't attach media to direct messages either then?

51 weeks 11 hours ago
jkalucki
@jkalucki John Kalucki

Correct, images can be attached to Tweets, but not to DMs.

51 weeks 5 hours ago
TheUberGuy
@TheUberGuy Paul McDonald

Took a look at the photo upload api and I have a slight problem. On a blackberry device, at least for us 3rd party apps ;-), there are pretty small limits on the number of bytes that can reliably be sent in an http POST, typically around 20k. With the Plixi/Lockerz folks we worked around this with an api that allows multiple, sequential http POSTs to upload the photo. I use this same strategy in mypict.me. Its not pretty, but gets the job done.

Is there any chance you guys might add another endpoint for this type of upload?

50 weeks 6 days ago
TvdW
@TvdW Tom van der Woerdt

Couldn't you work around that by using one of your servers as a proxy?

50 weeks 6 days ago
TheUberGuy
@TheUberGuy Paul McDonald

Certainly possible, but incurs substantial costs in terms of bandwidth fees and additional upload time.

50 weeks 6 days ago
jkalucki
@jkalucki John Kalucki

Paul -- We were totally unaware of this reality for BlackBerry. We're now discussing this internally. Clearly, this isn't going to be trivial to implement.

50 weeks 6 days ago
Giberno333
@Giberno333 Giberno Z

Tested it, working fine in server. but return a 0 code in localhost

50 weeks 6 days ago
episod
@episod Taylor Singletary

Servers don't typically send HTTP 0 codes, but some environmental issues can cause it to seem that way. You might be having some SSL issues in your local environment. This link describes a similar scenario: http://stackoverflow.com/questions/4570973/anything-wrong-with-my-curl-code-http-status-of-0

50 weeks 6 days ago
Giberno333
@Giberno333 Giberno Z

I have no change CURLOPT set and they all as default, they all turn off as 'false'

50 weeks 6 days ago
jftest
@jftest just testing

I had been getting inexplicable "Invalid Unicode value in one or more parameters" errors for all-ASCII tweets, and finally figured it out, so I thought I'd share the unintuitive workaround in case others run into it...

In the "media" multipart section for the photo to upload, you can specify a name for the file. This name is not required by the HTTP standard, nor does it seem to be used by Twitter for anything, but if omitted, you get the "Invalid Unicode value in one or more parameters" error. Setting the name to "foo" (or any non-empty valid utf8 string) avoids the problem.

Twitter folks: is this filename metadata used for anything?
Thanks,
Jeffrey Friedl

50 weeks 6 days ago
jkalucki
@jkalucki John Kalucki

Filed a ticket to look into filenames.

50 weeks 6 days ago
dwhalenenr
@dwhalenenr David Whalen

I have a Oauth library I already use and I'm trying to figure out what I have to change to get this to work. I changed the domain to upload.twitter.com, and I post the image using the media[] fieldname, and I get back "Error creating status" from the API.

What do I have to change in my CURL call to get this to work? Thanks!

DW

50 weeks 6 days ago
cpatil
@cpatil Chetan Patil

Can you provide an example of the Curl cmd?

An error message of "Error creating status" likely indicates:
- an issue with the image (animated gifs aren't allowed and we have had some issues with some kind of jpegs). Please try with a different image.
- a transient issue with the infrastructure.

We are working on providing additional details in the error messages. Please stay tuned.

49 weeks 20 hours ago
jftest
@jftest just testing

Could someone from Twitter describe how image sizes (pixel, not byte) are dealt with? If I upload a photo with, for example, 4000 pixels on the long edge, the largest view I can get via Twitter is 1064 pixels on the long edge. Yet, if I upload an image with 1800 pixels on the long edge, the "large" view is the full 1800-pixels-on-the-long edge size. At what point do you apply a force size reduction? Overall, some best practices for pre-upload image sizing would be appreciated.

Also, what about JPEG quality settings? If Twitter will always force a certain JPEG quality on the largest size made available to the user, I would not want to waste bandwidth uploading with a higher quality setting, so I'd like to hear about what Twitter does here as well.

Finally, what about color spaces? Do you convert everything to sRGB, or do you leave things alone, or do something else? In any case, the version of the image on Twitter has no indication of color space, which means that users are guaranteed to get random color renditions that differ from user to user with no way for the color-savvy user to ensure proper colors for themselves. I would strongly recommend including an embedded color profile if you know the color space of the image, at least for the larger/largest versions presented to the user. If you're not familiar with digital-image color spaces, you need to be: here is a primer: http://regex.info/blog/photo-tech/color-spaces-page1

Thanks.
Jeffrey Friedl

50 weeks 6 days ago
jkalucki
@jkalucki John Kalucki

You can see the largest sizes that we currently support in the https://api.twitter.com/1/help/configuration.json call. This is subject to change, but currently we center "crop" the thumbnails, and then "fit" the other images into the given box size:

  1. "photo_sizes":{"medium":{"h":1200,"w":600,"resize":"fit"},"small":{"h":480,"w":340,"resize":"fit"},"thumb":{"h":150,"w":150,"resize":"crop"},"large":{"h":2048,"w":1024,"resize":"fit"}}

Ff you have an image larger than 2048x1024, you can scale it down and send it up at the highest, or nearly highest, quality compression and probably save time over sending the higher resolution image. This will likely result in the same result quality and save everyone time and money as well.

We always compress somewhat, and we've played with the quality settings a few times. There's no easy answer on this part. Send the highest quality image that your latency budget can tolerate.

On color spaces: We're having a minor corner-case problem with PNG color space conversion stuff, and until that's resolved, I don't know how color management will all turn out. Once I understand what the issues are, and how we're fixing them, I'll try to remember to come back and update this thread.

50 weeks 6 days ago
jftest
@jftest just testing

Thanks much, John.

50 weeks 5 days ago
jftest
@jftest just testing

I'm not seeing these limits enforced, and am wondering if it's really just a misunderstanding on my part. Here's an image that's 2000 pixels wide, by 1331 pixels tall:

https://p.twimg.com/AXFKt0TCEAAKP4B.jpg:large

Based upon the 1024-wide by 2048-tall limit you referenced, I would have expected this wider-than-tall image to be drastically reduced so that it was 1024 pixels wide (and 681 pixels tall).

In doing the test, I was hoping to find out that the limits weren't actually hard-coded to the width/height numbers mentioned, but instead that they were "2048 on the long edge, 1024 on the short edge", but the result I'm actually seeing is not possible with either interpretation, so I'm quite confused.

My goal in asking is to know what kind of pixel-size limit to enforce in my app (for Lightroom) before uploading to Twitter. Users of this app will often want to use the largest size that Twitter will accept.

50 weeks 5 days ago
jkalucki
@jkalucki John Kalucki

Looking into this. Something seems wrong, but I can't figure it out at this early hour. Will get back to this thread with an update.

50 weeks 5 days ago
jftest
@jftest just testing

Would it be possible to include the user's photo-upload quota data (comperable to the X-Mediaratelimit-Remaining in the photo-upload reply header) in a non-upload call, such as account/verify_credentials? Then a client could keep a user informed of their status even before a photo-upload.

Thanks,
Jeffrey Friedl

50 weeks 6 days ago
jkalucki
@jkalucki John Kalucki

I filed a ticket to look into adding this field to other endpoints.

50 weeks 6 days ago
danpalmer
@danpalmer Dan Palmer

Is this done yet? Would be great to know if it is.

47 weeks 1 day ago
jkalucki
@jkalucki John Kalucki

Not done yet. Pretty far down on the untriaged queue.

47 weeks 1 day ago
danpalmer
@danpalmer Dan Palmer

What about the issues several people seem to be having with error 500s coming from this API? i.e. https://dev.twitter.com/discussions/1525

47 weeks 1 day ago
rschu
@rschu René Schulte

Hi, I tried to implement the new API in my WP7 photo effect app. The request looks OK to me, but I get a response "error=Could not authenticate with OAuth.".

I wonder why? The Auth header looks good or what is wrong here?
Here's the request (I truncated the image date):

POST https://upload.twitter.com/1/statuses/update_with_media.json?oauth_consumer_key=0Pf1TSjyOFYZZoOAQtcdvQ&oauth_token=226570571-EhNbpgfDhyakp0T9u030hurFi27iwV3t8TRcvfN4&oauth_nonce=vf28ogfpjw5kwjop&oauth_timestamp=1313614615&oauth_signature_method=HMAC-SHA1&oauth_signature=njSbdKjELfSIpoBpGe3o5m56vck%3D&oauth_version=1.0 HTTP/1.1
Accept: /
Referer: file:///Applications/Install/DE2C9557-9ABC-4B74-ACC7-6D4ADB19B575/Install/
Content-Length: 122360
Accept-Encoding: identity
Authorization: OAuth oauth_consumer_key="0Pf1TSjyOFYZZoOAQtcdvQ",oauth_nonce="vf28ogfpjw5kwjop",oauth_signature="njSbdKjELfSIpoBpGe3o5m56vck%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1313614615",oauth_token="226570571-EhNbpgfDhyakp0T9u030hurFi27iwV3t8TRcvfN4",oauth_version="1.0"
Content-Type: multipart/form-data; boundary=5abd2fbd-280b-4c5a-8705-507ae24b695b
User-Agent: NativeHost
Host: upload.twitter.com
Connection: Keep-Alive
Cache-Control: no-cache

--5abd2fbd-280b-4c5a-8705-507ae24b695b
Content-Disposition: form-data; name="status"

  • with @PicturesLab No FX
    --5abd2fbd-280b-4c5a-8705-507ae24b695b
    Content-Disposition: form-data; name="media[]"; filename="No_FX_2011-08-17_22-56-55.jpg"
    Content-Type: image/jpeg

?????Exif??MM?*?????i??????2???? ???&???????????

...

50 weeks 5 days ago
TvdW
@TvdW Tom van der Woerdt

I noticed a few things while reading through all this (going from the top of the request to the bottom).

  • (something I noticed) you POST to the full URL instead of to the path. Remove "https://upload.twitter.com" from the first line (but, of course, not from the base string). I really don't know whether this would cause trouble with the Twitter API but it's just wrong.
  • On the same line, you are sending information such as the consumer key - but don't you already send those in the Authorization header?
  • "Accept: /" doesn't sound like correct HTTP/1.1 to me
  • @ Authorization: Like mentioned earlier, you're sending this twice
  • User-Agent header does not match Twitter's User-Agent requirements. You are required to include a version number. (That or this rule is from the pre-OAuth time. Still a wise thing to do though)
  • Make sure you are NOT signing the status in your Base String.
50 weeks 5 days ago
rschu
@rschu René Schulte

Thanks, I'm not an expert in HTTP so I'm using a REST library for this :) and it works just fine with other Twitter API or TwitPic and Lockerz. I compared my request with the sample at the bottom of this blog post here. They seem similar. Only the URL params are additionally part of my request, but could this really be the issue?

50 weeks 5 days ago
TvdW
@TvdW Tom van der Woerdt

Yes

50 weeks 5 days ago
rschu
@rschu René Schulte

Thanks for your help! :) The URL parameters were indeed the issue. Works like a charm now.
Actually it's too bad it matters if they're present or not. Why does Twitter don't just skip those.

50 weeks 5 days ago