<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Heitor Tashiro Sergent</title>
    <description>The latest articles on Forem by Heitor Tashiro Sergent (@heitorburger).</description>
    <link>https://forem.com/heitorburger</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2825%2FWayra-103-square-big.jpg</url>
      <title>Forem: Heitor Tashiro Sergent</title>
      <link>https://forem.com/heitorburger</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/heitorburger"/>
    <language>en</language>
    <item>
      <title>How to Debug Common API Errors</title>
      <dc:creator>Heitor Tashiro Sergent</dc:creator>
      <pubDate>Fri, 01 Mar 2019 00:33:39 +0000</pubDate>
      <link>https://forem.com/heitorburger/how-to-debug-common-api-errors-2lkc</link>
      <guid>https://forem.com/heitorburger/how-to-debug-common-api-errors-2lkc</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fs99l2pv9recwqqyo0zvl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fs99l2pv9recwqqyo0zvl.jpg" alt="A toy hammer"&gt;&lt;/a&gt;&lt;br&gt;
Photo by &lt;a href="https://unsplash.com/photos/wFsbpYoGjOI?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Markus Spiske&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;In this post, we're going to focus on &lt;strong&gt;API users&lt;/strong&gt; 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.&lt;/p&gt;
&lt;h2&gt;
  
  
  Status Codes
&lt;/h2&gt;

&lt;p&gt;When working with APIs, every HTTP request that is sent to the server will be responded to with an &lt;a href="https://httpstatuses.com/" rel="noopener noreferrer"&gt;HTTP status code&lt;/a&gt;. HTTP status codes can be grouped into five different categories, by looking at their first digit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;1xx - Informational&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;2xx - Success&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;3xx - Redirection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;4xx - Client Error&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;5xx - Server Error&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;
  
  
  General Tips
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;
  
  
  Use an API Testing Tool
&lt;/h3&gt;

&lt;p&gt;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 &lt;a href="https://www.runscope.com/" rel="noopener noreferrer"&gt;Runscope&lt;/a&gt; itself, &lt;a href="https://www.getpostman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt;, &lt;a href="https://paw.cloud/" rel="noopener noreferrer"&gt;Paw&lt;/a&gt;, &lt;a href="https://insomnia.rest/" rel="noopener noreferrer"&gt;Insomnia&lt;/a&gt;, &lt;a href="https://curl.haxx.se/" rel="noopener noreferrer"&gt;cURL&lt;/a&gt;, &lt;a href="https://httpie.org/" rel="noopener noreferrer"&gt;HTTPie&lt;/a&gt;. Most of these tools are free or have trials, and they can save you a ton of time when debugging errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F75rd9jktzkb8wu6sigs9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F75rd9jktzkb8wu6sigs9.png" alt="The Runscope editor, showing it set up to make a GET request to the Star Wars API endpoint https://swapi.co/api"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Runscope example)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4uhdnds2wtoizxrqe0gv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4uhdnds2wtoizxrqe0gv.png" alt="A terminal example, showing a GET request made to the Star Wars API endpoint    https://swapi.co/api via cURL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(curl example)&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;
  
  
  Read the Docs
&lt;/h3&gt;

&lt;p&gt;I can't stress this enough, and not only because I enjoy writing documentation, but &lt;strong&gt;please read the docs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;
  
  
  Be Careful with Copy+Pasting
&lt;/h3&gt;

&lt;p&gt;Copy and pasting code snippets from API documentation, or StackOverflow answers, is really easy, but be careful with those.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Now, let's get to the less general advice, and dig in into specific status codes!&lt;/p&gt;
&lt;h2&gt;
  
  
  400 Bad Request
&lt;/h2&gt;

&lt;p&gt;A 400 status code means that the server could not process an API request due to &lt;strong&gt;invalid syntax&lt;/strong&gt;. A few possibilities why this might happen are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;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&lt;/li&gt;
&lt;li&gt;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 &lt;a href="https://jsonlint.com/" rel="noopener noreferrer"&gt;web editor&lt;/a&gt; or &lt;a href="https://atom.io/packages/linter-jsonlint" rel="noopener noreferrer"&gt;code editor plugin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The request is missing authentication information, or the Authorization header provided could not be validated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;
  
  
  401 Unauthorized
&lt;/h2&gt;

&lt;p&gt;The 401 Unauthorized status code is returned when the API request is missing authentication credentials or the credentials provided are invalid.&lt;/p&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization: Bearer your_api_token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization: Basic base64_encode(username:password)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another thing to be mindful of, for cases where you only have a username, or only a password, make sure to &lt;a href="https://stripe.com/docs/api/authentication" rel="noopener noreferrer"&gt;include the colon&lt;/a&gt; (":") before encoding. Otherwise, the authentication will fail.&lt;/p&gt;

&lt;h2&gt;
  
  
  403 Forbidden
&lt;/h2&gt;

&lt;p&gt;The 403 Forbidden status code looks similar to the 401 code, but they shouldn't be confused with each other.&lt;/p&gt;

&lt;p&gt;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 &lt;strong&gt;does recognize the authorization credentials&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;Another reason this status code might be returned is in case the user did not request an API access token with the &lt;strong&gt;correct permissions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  404 Not Found
&lt;/h2&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The endpoint does not exist&lt;/li&gt;
&lt;li&gt;The endpoint exists, but the resource cannot be found&lt;/li&gt;
&lt;li&gt;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&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  429 Too Many Requests
&lt;/h2&gt;

&lt;p&gt;The 429 Too Many Requests is one of the longer ones, and it's also self-explanatory. We're calling the API too often.&lt;/p&gt;

&lt;p&gt;It's common for public and &lt;a href="https://developer.foursquare.com/docs/api/troubleshooting/rate-limits" rel="noopener noreferrer"&gt;3rd-party APIs&lt;/a&gt; to include some form of &lt;strong&gt;rate-limiting&lt;/strong&gt;. 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.&lt;/p&gt;

&lt;p&gt;If you run into this error, there are several things that you can try to fix it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After" rel="noopener noreferrer"&gt;&lt;em&gt;Retry-After&lt;/em&gt; header&lt;/a&gt; might be included, indicating the Date or time in seconds when the user can retry the request&lt;/li&gt;
&lt;li&gt;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&lt;/li&gt;
&lt;li&gt;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&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5xx Error Codes
&lt;/h2&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;500 Internal Server Error&lt;/li&gt;
&lt;li&gt;502 Bad Gateway&lt;/li&gt;
&lt;li&gt;503 Service Unavailable&lt;/li&gt;
&lt;li&gt;504 Gateway Timeout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Try again later. The server might be under too much load at the moment&lt;/li&gt;
&lt;li&gt;Check the API status page, if one is available, for more information if there's maintenance going on, or the API is down&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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, &lt;a href="//mailto:help@runscope.com"&gt;we'd love to hear from you&lt;/a&gt;!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>6 Common API Errors</title>
      <dc:creator>Heitor Tashiro Sergent</dc:creator>
      <pubDate>Mon, 06 Feb 2017 17:59:49 +0000</pubDate>
      <link>https://forem.com/heitorburger/6-common-api-errors</link>
      <guid>https://forem.com/heitorburger/6-common-api-errors</guid>
      <description>&lt;p&gt;Have you ever used an API that returned an HTML error page instead of the JSON you expected, causing your code to blow up? What about receiving a 200 OK status code with a cryptic error message in your response?&lt;/p&gt;

&lt;p&gt;Building an API can be as quick as serving fast food. Frameworks like Express, Flask, and Sinatra combined with Heroku or &lt;a href="https://zeit.co/now" rel="noopener noreferrer"&gt;zeit's now&lt;/a&gt; help any developer have an API up and running in a few minutes.&lt;/p&gt;

&lt;p&gt;However, building a truly secure, sturdy, hearty API, can take a little more work, just as a chef takes more time when crafting a great meal. You need great docs, clear and concise error messages, and to meet developers' expectations of how your API should work.&lt;/p&gt;

&lt;p&gt;On the other side of the table, we have developers interacting with these APIs. And we, as developers, sometimes make mistakes. We can make false assumptions about how an endpoint should work, not read the docs closely enough, or just not have enough coffee that morning to parse an error message. That's where Runscope comes in.&lt;/p&gt;

&lt;p&gt;Our &lt;a href="https://www.runscope.com/api-monitoring" rel="noopener noreferrer"&gt;testing and monitoring tools&lt;/a&gt; can help you uncover issues that would otherwise stay hidden by a lack of integration tests, or real-world use case scenarios. Working with thousands of developers to resolve their API problems has given us unique insight into issues they often see when integrating and interacting with APIs.&lt;/p&gt;

&lt;p&gt;Here's our list of 6 common mistakes that can catch you off guard, why they happen, and how you can avoid them:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Using http:// instead of https://
&lt;/h2&gt;

&lt;p&gt;Forgetting a single "s" can get you in a lot of trouble when testing an API. Some APIs may only support HTTPS, while others may support HTTP for some endpoints and not others.&lt;/p&gt;

&lt;p&gt;Even when an API supports both, you might still run into some errors. For example, some APIs redirect HTTP traffic to their HTTPS counterpart, but not all frameworks will be configured to follow a 302 status code. &lt;a href="https://github.com/request/request#requestoptions-callback" rel="noopener noreferrer"&gt;Node.js &lt;code&gt;request&lt;/code&gt; module&lt;/a&gt;, for example, will follow GET redirects by default, but you have to explicitly set &lt;code&gt;followAllRedirects&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; if you want to follow redirects to POST and other methods.&lt;/p&gt;

&lt;p&gt;APIs may also stop supporting HTTP, so it's important to stay up-to-date with any changes. Good API providers will let users know beforehand via email and any social media channels they have. Another step you can take is to use a tool like &lt;a href="https://www.hitchhq.com/" rel="noopener noreferrer"&gt;Hitch&lt;/a&gt;, which lets you follow certain APIs and be notified if anything changes.&lt;/p&gt;

&lt;p&gt;If you're asking yourself if your API should support HTTPS, then the answer is yes. The process for getting certificates used to be a hassle, but with solutions like &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let's Encrypt&lt;/a&gt; and &lt;a href="https://www.cloudflare.com/" rel="noopener noreferrer"&gt;Cloudflare&lt;/a&gt;, there's no excuse to not support HTTPS. If you're unsure why you should do it, or don't think you should because you're not transmitting any sensitive data, I highly recommend reading "&lt;a href="https://https.cio.gov/everything/" rel="noopener noreferrer"&gt;Why HTTPS for Everything?&lt;/a&gt;" from CIO.gov.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Unexpected error codes
&lt;/h2&gt;

&lt;p&gt;A good API error message will allow developers to quickly find why, and how, they can fix a failed call. A bad API error message will cause an increase in blood pressure, along with a high number of support tickets and wasted time.&lt;/p&gt;

&lt;p&gt;I ran into this issue a couple of weeks ago while trying to retrieve an API's access token. The code grant flow would return an error message saying that my request was invalid, but it wouldn't give me any more details. After an hour banging my head against the wall, I realized I hadn't paid attention to the docs and forgot to include an Authorization header with a base64 encoded string of my application's client_id and client_secret. &lt;/p&gt;

&lt;p&gt;Good usage of HTTP status code and clear error messages may not be sexy, but it can be the difference between a developer evangelizing your API and an angry tweet.&lt;/p&gt;

&lt;p&gt;Steve Marx had this to say in "&lt;a href="https://blogs.dropbox.com/developers/2015/04/how-many-http-status-codes-should-your-api-use/" rel="noopener noreferrer"&gt;How many HTTP status codes should your API use?&lt;/a&gt;": "...developers will have an easier time learning and understanding an API if it follows the same conventions as other APIs they're familiar with." As an API provider, you don't have to implement 70+ different status codes. Another great advice by Steve is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Following this pragmatic approach, APIs should probably use at least 3 status codes (e.g. 200, 400, 500) and should augment with status codes that have specific, actionable meaning across multiple APIs. Beyond that, keep your particular developer audience in mind and try to meet their expectations."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.twilio.com/" rel="noopener noreferrer"&gt;Twilio&lt;/a&gt; is a great example of best practices for &lt;a href="https://www.twilio.com/docs/api/errors#debugging-calls-to-the-rest-api" rel="noopener noreferrer"&gt;status code and error messages&lt;/a&gt;. They go the extra mile and include links in their responses, so the error message is concise while still providing the developer with more information in case they need it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;21211&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The 'To' number 5551234567 is not a valid phone number."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"more_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.twilio.com/docs/errors/21211"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As API consumers, we need to be careful and not assume that an API 200 status code means the request made a successful call and returned the information we want. Some APIs, like Facebook's Graph API, always return a 200 status code, with the error being included in the response data. So, when testing and monitoring APIs, always be careful and don't automatically assume that a 200 means everything is ok™.&lt;/p&gt;

&lt;p&gt;Another great resource about response handling is Mike Stowe's blog post on "&lt;a href="http://blogs.mulesoft.com/dev/api-dev/api-best-practices-response-handling/" rel="noopener noreferrer"&gt;API Best Practices: Response Handling&lt;/a&gt;."&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Using the incorrect method
&lt;/h2&gt;

&lt;p&gt;This is an easy one, but surprisingly common. A lot of times this can be blamed on poor documentation. Maybe the endpoints do not explicitly say what methods are supported between GET/POST/PUT etc., or they have the wrong verb.&lt;/p&gt;

&lt;p&gt;Tools can also play tricks on you if you're not careful. For example, let's say you want to make a GET request with a request-body (not a great practice, but it happens). If you make a curl request using the -d option, and don't use the &lt;code&gt;-XGET&lt;/code&gt; flag, it will automatically default to POST and include the &lt;code&gt;Content-Type: application/x-www-form-urlencoded&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;This post by Daniel Stenberg (author and maintainer of curl) on "&lt;a href="https://daniel.haxx.se/blog/2015/09/11/unnecessary-use-of-curl-x/" rel="noopener noreferrer"&gt;Unnecessary use of curl -X&lt;/a&gt;" also illustrates another possibility you might run into this issue when dealing with redirects: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"One of most obvious problems is that if you also tell curl to follow HTTP redirects (using -L or –location), the -X option will also be used on the redirected-to requests which may not at all be what the server asks for and the user expected."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Other times, we might fall into past assumptions and just use the wrong method. For example, the Runscope API uses POST when creating new resources, such as test steps or environments, and PUT when modifying them. But Stripe's API uses POST methods when creating and &lt;a href="https://stripe.com/docs/api#update_customer" rel="noopener noreferrer"&gt;updating objects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Both approaches are valid, and &lt;a href="https://stormpath.com/blog/put-or-post" rel="noopener noreferrer"&gt;Stormpath&lt;/a&gt; has a great blog post talking about their differences, and how to handle them as an API provider. No matter which one you choose, just be consistent throughout your API and make sure to have correct and up-to-date docs, so your users don't run into this error.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Sending invalid authorization credentials
&lt;/h2&gt;

&lt;p&gt;APIs that implement OAuth 2, such as &lt;a href="https://developer.paypal.com/docs/api/auth-headers/" rel="noopener noreferrer"&gt;PayPal&lt;/a&gt;, usually require the developer to include an &lt;code&gt;Authorization&lt;/code&gt; header for each request. It's common to confuse that with &lt;code&gt;Authentication&lt;/code&gt; instead (I did exactly that while making the GIFs for our last blog post.), so if your request is failing, make sure you're using the correct word.&lt;/p&gt;

&lt;p&gt;Another issue that pops up with Authorization headers is actually constructing it correctly. OAuth 2 tokens need to be prepended with "Bearer" for them to work:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Authorization: Bearer your_api_token&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Authorization: Basic base64_encode(username:password)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Common mistakes include forgetting the 'Basic ' (note the space) prefix, not encoding the username and password or forgetting the colon between them. If an API provider only requires a username without a password (like Stripe, where your API key is the username), you'll need that pesky colon after the username, even if there's no password.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Not specifying Content-Type or Accept header
&lt;/h2&gt;

&lt;p&gt;Accept and Content-Type headers negotiate the type of information that will be sent or received between a client and server. Some APIs will accept requests that don't contain any of those headers, and just default to a common format like JSON or XML.&lt;/p&gt;

&lt;p&gt;Other APIs are a little more strict. Some might return a 403 error if you're not explicit about the Accept header value, and 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.&lt;/p&gt;

&lt;p&gt;This issue can also be cause some confusion if you are testing your API with different tools. curl, for example, along with other popular testing tools, will automatically include an &lt;code&gt;Accept&lt;/code&gt; header for any MIME type: &lt;code&gt;*/*&lt;/code&gt; with every request. We, at Runscope, don't add a default Accept header, so this can get you different results when testing the same endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. APIs returning invalid content type when there is an error
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic1.squarespace.com%2Fstatic%2F51814c87e4b0c1fda9c1fc50%2Ft%2F588f6f433e00be6360b38288%2F1485964419721%2Fhtml-response-3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic1.squarespace.com%2Fstatic%2F51814c87e4b0c1fda9c1fc50%2Ft%2F588f6f433e00be6360b38288%2F1485964419721%2Fhtml-response-3.jpg" alt="An API response with a full HTML page in the body parameter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I can say that this is one of my pet peeves with APIs. Seeing that &lt;code&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/code&gt; line in a response makes my blood pressure go sky high.&lt;/p&gt;

&lt;p&gt;Well, sometimes that's my fault. If you forget to send an &lt;code&gt;Accept&lt;/code&gt; header with your request, the API can't be sure what response format you're expecting.&lt;/p&gt;

&lt;p&gt;For API providers, some frameworks and web servers default to HTML. For example, &lt;a href="https://symfony.com/" rel="noopener noreferrer"&gt;Symfony&lt;/a&gt;, a PHP framework, defaults to returning a 500 HTML error. So if you're creating an API that has no business returning HTML, make sure to check the defaults error response.&lt;/p&gt;

&lt;p&gt;Another reason this might happen may not have to do with your API, but with the routing mesh or load balancer that sits in front of your API. For example, if you have a nginx instance fronting your API and it encounters a request timeout or other error, it may return an HTML error before your API instances even have a chance to know what's going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;These are some of the most common mistakes we have seen across multiple APIs. This list could go on for much longer, so if there's some other error you came across and managed to fix it, please share it with us &lt;a href="https://twitter.com/Runscope" rel="noopener noreferrer"&gt;@Runscope&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As API providers and API consumers, these mistakes can sometimes go unnoticed and waste thousands of debugging hours. To get more visibility into your APIs and avoid getting stuck in bad redirects or unexpected error codes, check out our API testing and monitoring tools with a &lt;a href="https://www.runscope.com/signup" rel="noopener noreferrer"&gt;free trial account&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>monitoring</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
