Q:

Getting 401 on Twitter OAuth POST requests

I am trying to use Twitter OAuth and my POST requests are failing with a 401 (Invalid OAuth Request) error.
For example, if I want to post a new status update, I am sending a HTTP POST request to https://twitter.com/statuses/update.json with the following parameters - 
status=Testing&oauth_version=1.0&oauth_token=xxx&
oauth_nonce=xxx&oauth_timestamp=xxx&oauth_signature=xxx&
oauth_consumer_key=xxx&in_reply_to=xxx&oauth_signature_method=HMAC-SHA1`

My GET requests are all working fine. I can see on the mailing lists that a lot of people have had identical problems but I could not find a solution anywhere.
I am using the oauth.py Python library.

A:

I just finished implementing twitter OAuth API from scratch using Java. Get and post requests work OK. You can use this page http://www.hueniverse.com/hueniverse/2008/10/beginners-gui-1.html to check signature and HTTP headers. Just enter your keys and tokens and check output. It seems twitter works exactly as described on this post. Be careful with spaces and UTF-8 symbols, for example Java encodes space as "+" but OAuth requires %20

A:

Make sure your app access type is read & write.
On your app settings page (ex. http://twitter.com/apps/edit/12345) there's a radio button field like this:
Default Access type: Read & Write / Read-only
If you check 'Read-only' then status update API will return 401.

A:

I second the answer by Jrgns. I has exactly the same issue. When reading the example Twitter provides, it's actually clear. However their pseudo code is misleading. In Python this worked for me :
def encodekeyval(key, val):
    key = urllib.quote(key, '')
    val = urllib.quote(val, '')
    return urllib.quote(key + '=' + val, '')

def signature_base_string(urlstr, oauthdata):
    sigstr = 'POST&' + urllib.quote(urlstr,'') + '&'
    # retrieve "post" data as dictionary of name value pairs
    pdata = oauthdata.getpdata()
    # need to sort parameters
    pstr = '%26'.join([encodekeyval(key, pdata[key]) for key in sorted(pdata.keys())])
    return sigstr + pstr

