Why do I always get 403s when I try to send a direct message? All other API endpoints work



I’ve been commissioned to overhaul and modernize Gwibber (among other things, I am updating it from API 1 to 1.1). I’m mostly done, however sending new direct messages just utterly refuses to work. I can send public tweets, and I can send replies, and I can receive direct messages, but I cannot send them.

I’ve scoured the API docs, and I’ve found various different potential meanings for a 403 error. One page suggested that 403s would be given in response to duplicate requests – well i’ve tried many different direct messages that could not be considered duplicates. Another page suggested that I don’t have DM permissions – well I can access direct_messages.json and direct_messages/sent.json, so I seem to have that permission.

I really don’t understand why this isn’t working, and I’d appreciate it if somebody could look into it for me. The code is here:


Note that all other methods defined in that class demonstrably work, and I have tested them on my live twitter account with success. It is only direct_messages/new that is giving me 403s and I have no idea why. What have I done wrong here?



Have you examined the response body that comes with that HTTP 403? We tend to provide more informative errors if you examine the body.

When attempting to send a direct message, is the target a user that the authenticating user is allowed to send a direct message to?

Looking at your connection code, it looks like you’re making some assumptions that aren’t necessarily true – in _get_url (which could have a better name since it performs more than just getting URLs), you determine whether to perform a POST or not based on whether there is data – in the Twitter API there are plenty of methods that you’ll want to use a POST on but not necessarily have data to provide. It’d be best for you to make setting the HTTP method more explicit.


Thanks for the quick response.

Turns out the people I was trying to message weren’t following me, and that’s not allowed. Didn’t realize that was the case. After I messaged somebody who followed me, it worked fine.

As for POST/GET, I can pass an empty dict into that method to trigger a “POST with no data”, it’s smart enough for that.

Thanks again!


When I try to send message for the first time it is successful, but afterwards it throws error code 403 and forbidden.