Twitter Response Codes Simplified
November 10, 2009
I recently attended an AtlantaPHP meet-up where Ben Ramsey talked about “The Hidden Gems in HTTP”. That gave me the idea to explain the response codes you might see when using the Twitter API, and give some practical examples too.
We will be using PHP and cURL to access the API. If you aren’t too familiar, please read this post.
Each heading is exactly what you will find in the Twitter API documentation, along with my own explanation and some examples.
200 OK: Success!
Let’s say I want to get a list of my followers, I can use the code example below, and if I get a 200 OK return code I know that my request has been successful.
//Create the connection handle
$curl_conn = curl_init();
//Set up the URL to query Twitter $user_followers = "https://twitter.com/statuses/followers/nicdev.xml";
//Set cURL options
curl_setopt($curl_conn, CURLOPT_URL, $user_followers); //URL to connect to curl_setopt($curl_conn, CURLOPT_GET, 1); //Use GET method curl_setopt($curl_conn, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); //Use basic authentication curl_setopt($curl_conn, CURLOPT_USERPWD, 'username:password'); //Set u/p curl_setopt($curl_conn,CURLOPT_HEADER,1); //Get the header. This is key to getting the response code!<strong></strong>
curl_setopt($curl_conn, CURLOPT_RETURNTRANSFER, 1); //Return the result as string.
// Result from querying URL. Will parse as xml $output = curl_exec($curl_conn);
// close cURL resource. It's like shutting down the water when you're brushing your teeth. curl_close($curl_conn);
echo $output;
If you are following along you will now have a pretty messy screen full of information about your followers. The part of the response we are interested in, it’s in the first line.
HTTP/1.1 200 OK Date: Tue, 10 Nov 2009 13:51:56 GMT Server: hi X-RateLimit-Limit: 20000 X-Transaction: 1257861116-80037-4182 Status: 200 OK
The 200 OK code let’s us know it’s all good, and our request has been successfully processed.
304 Not Modified: There was no new data to return.
This one is a bit trickier. In short, a 304 code means that there is no new data to a request. I attempted to send the request repeatedly through a “for loop” but I got a 200 OK every time. I tried to search for bug reports so I could try to reproduce it, but no dice. Maybe they don’t really provide 304′s? If you know a way of getting it to reply 304, please comment.
400 Bad Request: The request was invalid. An accompanying error message will explain why. This is the status code will be returned during rate limiting.
Well, Twitter imposes all sorts of limits on the amount of API calls you can make, and this is a good thing. The limits imposed are workable, and can be increased if you are a developer and ask nicely. The default limit is 150/hour on any given account, so it was easy to reproduce.
Change the script as follows, and refresh the page.
//Replace the line $output = curl_exec($curl_conn); with the following block of code.
for($i = 0; $i < 160; $i++)
{
$output = curl_exec($curl_conn);
$output = substr($output, 0, 200);
echo $output."<br />";
}
You will probably get a lot of 200 codes followed by 400′s.
HTTP/1.1 400 Bad Request Date: Tue, 10 Nov 2009 14:43:40 GMT Server: hi X-RateLimit-Limit: 150 Status: 400 Bad Request X-RateLimit-Remaining: 0 X-Runtime: 0.01104 Content-Type: application/xml;
401 Not Authorized: Authentication credentials were missing or incorrect.
Does as it says, and there’s a great way of testing it out, the verify_credentials method. Simply pass it a bad username and password and you’ll have a 401 error to call your own.
//Change this part in the original script.
//Set up the URL to query Twitter
$user_followers = "http://twitter.com/account/verify_credentials.xml";
//Don't forget to change the credentials to something invalid
Here’s the result
HTTP/1.1 401 Unauthorized Date: Tue, 10 Nov 2009 15:16:24 GMT Server: hi Status: 401 Unauthorized
403 Forbidden: The request is understood, but it has been refused. An accompanying error message will explain why. This code is used when requests are being denied due to update limits.
You simply tweet too much! Again, you hit a rate limit that is pretty forgiving for most people. The following piece of code will actually post just one tweet to your account, which will most likely get a 200 OK code; I’m posting in in case you were looking for a short script to post updates to Twitter. The second one will actually try to post more messages than it’s allowed in order to purposely get a 403 code.
Please note that because Twitter checks you aren’t sending the exact same message repeatedly, I’m changing the text in every post.
One tweet:
//Create the connection handle
$curl_conn = curl_init();
//Set up the URL to query Twitter
$api_call = "http://twitter.com/statuses/update.xml"; $options = "status=This is a test status made with PHP"; //The actual message is a required parameter
//Set cURL options
curl_setopt($curl_conn, CURLOPT_URL, $api_call); //URL to connect to curl_setopt($curl_conn, CURLOPT_POST, 1); //Use POST curl_setopt($curl_conn, CURLOPT_POSTFIELDS, $options); curl_setopt($curl_conn, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); //Use basic authentication curl_setopt($curl_conn, CURLOPT_USERPWD, 'username:password..'); //Set u/p curl_setopt($curl_conn, CURLOPT_HEADER,1); //Get the header. This is key to getting the response code!
curl_setopt($curl_conn, CURLOPT_RETURNTRANSFER, 1); //Return the result as string.
// Result from querying URL. Will parse as xml
$output = curl_exec($curl_conn);
echo $output;
// close cURL resource. It's like shutting down the water when you're brushing your teeth. curl_close($curl_conn);
Many, many tweets.
//Create the connection handle
$curl_conn = curl_init();
//Set up the URL to query Twitter
$api_call = "http://twitter.com/statuses/update.xml";
//Set cURL options
curl_setopt($curl_conn, CURLOPT_URL, $api_call); //URL to connect to curl_setopt($curl_conn, CURLOPT_POST, 1); //Use POST curl_setopt($curl_conn, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); //Use basic authentication curl_setopt($curl_conn, CURLOPT_USERPWD, 'username:password'); //Set u/p curl_setopt($curl_conn, CURLOPT_HEADER,1); //Get the header. This is key to getting the response code!
curl_setopt($curl_conn, CURLOPT_RETURNTRANSFER, 1); //Return the result as string.
for($i=0;$i < 160;$i++)
{
$options = "status=This is a test status made with PHP to reach a 403".md5($i); //Change the message on each iteration
curl_setopt($curl_conn, CURLOPT_POSTFIELDS, $options);
$output = curl_exec($curl_conn);
$output = substr($output,0,200);
echo $output;
}
// close cURL resource. It's like shutting down the water when you're brushing your teeth. curl_close($curl_conn);

HTTP/1.1 403 Forbidden Date: Tue, 10 Nov 2009 18:54:52 GMT Server: hi X-Transaction: 1257879292-55915-20315 Status: 403 Forbidden Last-Modified: Tue, 10..
In case you haven’t noticed this is spamming, and it uses a lot of resources unnecessarily, so don’t do it, please.
404 Not Found: The URI requested is invalid or the resource requested, such as a user, does not exist.
This one is very simple. You’re looking for something that’s just not there. To try it out, go to the original script and change the request to a user you know doesn’t exist. For example @nicdev1232342
$user_followers = "https://twitter.com/statuses/followers/nicdev1232342.xml";
HTTP/1.1 404 Not Found Date: Tue, 10 Nov 2009 19:16:49 GMT Server: hi X-RateLimit-Limit: 150 X-Transaction: 1257880609-95984-9773 Status: 404 Not Found
406 Not Acceptable: Returned by the Search API when an invalid format is specified in the request.
Either the dpcumentation is wrong, or I’m too slow to understand. I tried making a request for followers using an non-existing format of .noformat, and all I got was a lousy 403. Again, if someone knows how to get this one to fire, please let me know and I’ll update the post.
$user_followers = "https://twitter.com/statuses/followers/nicdev.noformat";
I wanted a 406!
HTTP/1.1 403 Forbidden Date: Tue, 10 Nov 2009 19:23:03 GMT Server: hi X-Transaction: 1257880983-50850- 1216 Status: 403 Forbidden
500 Internal Server Error: Something is broken. Please post to the group so the Twitter team can investigate.
This one you can’t reproduce at will, but if you play with the Twitter API long enough you’re bound to run into it.
502 Bad Gateway: Twitter is down or being upgraded.

503 Service Unavailable: The Twitter servers are up, but overloaded with requests. Try again later. The search and trend methods use this to indicate when you are being rate limited.
The following script will run a search for the term “argentina” against the Twitter search API. Search limits are independent of other limits, and will return a 503 as opposed to a 403 when reaching the rate limit.
$curl_conn = curl_init();
//Set up the URL to query Twitter
$api_call = "http://search.twitter.com/search.json?&amp;amp;amp;amp;amp;amp;amp;q=argentina";
//Set cURL options
curl_setopt($curl_conn, CURLOPT_URL, $api_call); //URL to connect to curl_setopt($curl_conn, CURLOPT_GET, 1); //Use GET curl_setopt($curl_conn, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); //Use basic authentication curl_setopt($curl_conn, CURLOPT_USERPWD, 'username:password'); //Set u/p curl_setopt($curl_conn, CURLOPT_HEADER,1); //Get the header. This is key to getting the response code!
curl_setopt($curl_conn, CURLOPT_RETURNTRANSFER, 1); //Return the result as string.
for($i=0;$i < 160;$i++)
{
$output = curl_exec($curl_conn);
$output = substr($output,0,200);
echo $output."<br />";
}
// close cURL resource. It's like shutting down the water when you're brushing your teeth. curl_close($curl_conn);
This one was a true surprise. While running the script that loops around 160 times I received many 200′s, followed by a 502 Bad Gateway, followed by a 503 Service Unavailable (what I was expecting), and then again by a bunch of 200′s. It seems to me that the rate limit on search is very forgiving.
HTTP/1.1 200 OK Date: Tue, 10 Nov 2009 19:49:38 HTTP/1.1 502 Bad Gateway Date: Tue, 10 Nov 2009 19:49:42
HTTP/1.0 503 Service Unavailable
HTTP/1.1 200 OK Date: Tue, 10 Nov 2009 19:50:01
I hope you enjoyed the post and that it’ll help you when writing applications for Twitter, or any other app that relies on response codes. To finish here are some great resources.
- Twitter API Documentation – Good docs and a great community built around it.
- Scripting Twitter With cURL – Tech@Sakana
Tags: api, http, responsecodes, rest, twitter















