Debugging and troubleshooting APIs is something that any developer that works with APIs has to go through at some point. In an ideal world, APIs would always return a 200 OK with just the right data that we need, or in case of a failure, it would return us the perfect status code and error message allowing us to easily understand what went wrong.
In reality, APIs don't always work like that. API developers might have constraints that do not allow them to implement the most informative status code or error message, API errors can be triggered by real-world conditions that are hard to account or test for, and sometimes ourselves, as API users, can make requests with typos or mistakes that APIs just don't know how to handle.
In this post, we're going to focus on API users and what they can do to debug common API errors they might encounter when testing and working with APIs, whether these APIs are public or private.
When working with APIs, every HTTP request that is sent to the server will be responded to with an HTTP status code. HTTP status codes can be grouped into five different categories, by looking at their first digit:
1xx - Informational
2xx - Success
3xx - Redirection
4xx - Client Error
5xx - Server Error
We're going to be focusing on the 4xx client error codes in this post, as they are the more common errors we might see when working with APIs, and which can usually be solved by the API user itself. We'll also talk a little bit about the 5xx error category at the end.
Before we dive into the specifics of a few HTTP status codes, there are certain tips that we can apply to any API debugging attempt.
Use a tool that allows you to make, edit, replay, and inspect API calls. There are quite a few that I can recommend, such as Runscope itself, Postman, Paw, Insomnia, cURL, HTTPie. Most of these tools are free or have trials, and they can save you a ton of time when debugging errors.
Another advantage of using a tool that allows you to make and replay API requests is they can help you isolate an issue due to a bad API call, or something in your app environment (a configuration issue, firewall, etc.) preventing the API call from returning a 200 status code.
I remember when I first started developing mobile apps, I would sometimes run a Windows Phone app in debug mode and go through several steps to get to an API call I was trying to debug. Don't be like me.
I can't stress this enough, and not only because I enjoy writing documentation, but please read the docs.
I have been guilty of not following this advice as well but, reading the docs can be the difference between being stuck with an issue for 1 hour, or making a successful API call and moving on to your next task.
API documentation, when thorough and well-written, will give you all the answers you might need to successfully work with an API. How to authenticate, how to get an access token, what methods and endpoints are supported, and even what errors you might encounter and how to fix them.
Copy and pasting code snippets from API documentation, or StackOverflow answers, is really easy, but be careful with those.
Examples can be outdated and contain general errors or use an old API version that's not supported anymore. Copy+pasting code has an even trickier issue where certain characters might completely change how your API call works.
I had an error once where I copy+pasted a piece of text as a query parameter to an API request that should have included a ' symbol. Except that the text editor I was using converted the ' symbol to a ’ symbol (it might be hard to see, but they are different). When I pasted the text to my API call, that caused it to keep returning a 400 error, and it probably took me 30 minutes to debug.
Now, let's get to the less general advice, and dig in into specific status codes!
A 400 status code means that the server could not process an API request due to invalid syntax. A few possibilities why this might happen are:
- A typo or mistake while building out the request manually, such as mistyping the API endpoint, a header name or value, or a query parameter. This can also be caused if the request is missing a required query parameter, or the query parameter value is invalid or missing
- A malformed JSON body, for example, missing a set of double-quotes, or a comma. If you need to make an API request with a JSON body, I highly recommend writing it using a linter, whether you use a web editor or code editor plugin
- The request is missing authentication information, or the Authorization header provided could not be validated
The main advice when debugging a 400 Bad Request error is to review every piece of text. Make sure there are no typos in the endpoint, headers (name and values), and body. If you copied and pasted any part of your API request, pay extra attention that they don't include any mistakes or random characters that could be causing an issue.
Our last bullet point above (missing authentication information) is a good example of something you might see when working with multiple APIs. One API might send you a 400 status code for a request that has invalid authentication credentials, while another one might send you a 401 unauthorized status code, which can be used specifically for that purpose.
The 400 bad request status code sometimes is used as a catch-all for multiple types of errors. So if you have checked your API request for any invalid syntax and haven't found any errors, try to see if any of the other 4xx status code solutions could help you with debugging.
The 401 Unauthorized status code is returned when the API request is missing authentication credentials or the credentials provided are invalid.
APIs can be fickle, and that's especially true when creating and formatting the Authorization header. OAuth 2 tokens, for example, need to be prepended with "Bearer" for them to work:
Authorization: Bearer your_api_token
It's also important when using HTTP Basic authentication to pay close attention to the syntax of the header value. The form is as follows:
Authorization: Basic base64_encode(username:password)
Another thing to be mindful of, for cases where you only have a username, or only a password, make sure to include the colon (":") before encoding. Otherwise, the authentication will fail.
The 403 Forbidden status code looks similar to the 401 code, but they shouldn't be confused with each other.
Usually, when you see the 403 status code, the API request that is being made includes some form of authorization. But, different from the 401 status code, the server does recognize the authorization credentials and accepts is as valid. The issue this time is that the authenticated user cannot access the resource for that endpoint. For example, the user might be trying to access account-level information that's only viewable by the account administrator, and the credentials being passed on the API request are for a regular user account.
Another reason this status code might be returned is in case the user did not request an API access token with the correct permissions.
To fix the API call for those two situations, make sure that the credentials you are using have the access-level required by the endpoint, or that the access token has the correct permissions.
A less common reason we might see this error is if we're not explicit about the Accept header value. Some APIs require you to include those headers on requests. That way, the server knows what information the client is sending, and also what format they expect to receive in return.
404 Not Found one of those status codes that we don't have to be working with APIs to see. But, specifically for APIs, it can usually mean a few different things:
- The endpoint does not exist
- The endpoint exists, but the resource cannot be found
- The endpoint exists and the resource can be found, but the user does not have the required permissions to access it, and so the server returns a 404 status code
For the first two cases, there's not much we can do as an API user, except double-check that the endpoint really does exist in the documentation, or double-check that there are no misspellings or typos.
For the third case, the advice is similar to what we covered in the previous status code, 403. Make sure that the authorization credentials you are using actually have access to that endpoint, as some APIs might return a 404 error instead of 403.
The 429 Too Many Requests is one of the longer ones, and it's also self-explanatory. We're calling the API too often.
It's common for public and 3rd-party APIs to include some form of rate-limiting. That is a way to limit how many requests the user can make over a period of time. This serves to protect the API provider from having a user of making too many API calls, which can take up too many resources and potentially cause API slowdowns or even crashes for all users.
If you run into this error, there are several things that you can try to fix it:
- A Retry-After header might be included, indicating the Date or time in seconds when the user can retry the request
- Check the API documentation for the specifics of their rate-limiting. Sometimes, users might be able to give additional forms of authentication, upgrade their accounts, or reach out to the API support team to increase the rate limits
- Caching API responses is another strategy that can help mitigate this error. If you're working with an API and you don't rely on always up-to-date information, caching the response every x amount of seconds/minutes/hours/days and displaying the saved API response can you help you avoid limits or surcharges
5xx status codes generally mean that the server has encountered an error, and can't resolve the API request being made. Some of the more common status codes you might encounter are:
- 500 Internal Server Error
- 502 Bad Gateway
- 503 Service Unavailable
- 504 Gateway Timeout
A 5xx status usually means that the error is on the server side, not on the user side of things. So the general advice is to:
- Try again later. The server might be under too much load at the moment
- Check the API status page, if one is available, for more information if there's maintenance going on, or the API is down
We've covered just a few of the most common HTTP status codes you might encounter when debugging or troubleshooting APIs. Hopefully, with this information, you will feel more comfortable when encountering those issues and know about the tips and tricks you can use to find the solution.
If you have any other issues you would like to see added here, or any additional tips that you might have for fixing API errors, we'd love to hear from you!