RESTful API & Web Service Statuses

Written on 10:41:00 PM by S. Potter

As I have browsed and read newsgroups, mailing lists, articles and even books related to RESTful APIs and Web Services very few tackle the issue of which HTTP status messages are most relevant for the communication at hand. Below is a list of the few HTTP status codes that I most commonly use in the development of my own APIs and Web Services for my clients:

  • 404 “Resource Not Found”: Yes, you read that right. When a resource of a specific given ID does not exist in our datastore (whether due to it being an invalid ID or due to the resource having been deleted from our datastore). For example, “GET /people/2349594934896107” may not exist in our database, so what do we display? Just the bare “people/show” view with a flash message saying no person with that ID exists? I should say not – at least not in our RESTful world. However, if we are using something like acts_as_paranoid or home-grown paranoid delete mechanism and we know the resource used to exist in our datastore, we could respond with 410 “Gone”. The benefit of this is that we are communicating something useful back to the RESTful consumer, whether that is an end-user or another application or web service.
  • 401 “Unauthorized”: Returned when consumer either did not provide credentials to view restricted resource or the authentication and/or authorization failed. This assumes your application uses the Basic or Digest HTTP Authentication scheme as according to the HTTP protocol the server needs to respond with specific HTTP headers in various circumstances of returning this status code.
  • 503 “Service Unavailable”: Used when taking the site down for maintenance. I find this very handy indeed when upgrading the RESTful web services I deploy at work. For my projects I create a stub Rails application that responds with a 503 for each valid type of request that comes in. Clients of my services are usually services themselves or other applications, so this helps client developers that consume my web services know that this is a temporary blip and should be due to schedule maintenance (and a good reminder for them to check the emails I sent them over the weekend instead of ignoring them). The best and easiest way to do this is to create a new routes.rb file that contains all valid requests and points it to a controller/action that responds with a 503.
  • 201 “Created”: Very handy, especially in the context of designing RESTful web services. Status should be sent when replying to a POST that created a new resource on the server.
  • 202 “Accepted”: Yes, slightly obscure, but very handy. Signals to consumer of application (whether end-user human or REST client application) that a long running/executing job has been submitted for processing, but we do not yet know the outcome of the “job” or “process”. Of course, as with all of the above, to an end-user we would render a nicely designed web page telling them this, but if for some reason a bot (authorized or not) or web services client accessed our application, they would be able to determine some useful information from the status.
Please let me know any other HTTP status codes you find most useful when designing RESTful APIs. Update [2007-08-20]: Below are another couple of HTTP status codes, explanations and examples to aid in the more consistent development of true RESTful APIs:
  • 301 "Moved Permanently": This is a good one when deprecating RESTful APIs. For example, say you are no longer going to support the resource (and all related individual CRUD and custom methods) /corporate_bonds and instead provide the following resource "/bonds/:type" where :type might include corporate, municipal and government. Whenever a valid request is made to the "/corporate_bond" resource I will return a 301 HTTP status to the consumer to inform them that they need to use the new API.
  • 307 "Temporary Redirect": This is a nifty little status when you have temporarily suspended a resource, for example a "/users" resource. If a user is delinquent on their latest monthly installment, you want to start redirecting all calls to their profile, etc. to a temporary page that informs consumers of the RESTful site that this account is not current. There are probably many other good uses of this too. If you know of one, please leave a comment and educate me further.

If you enjoyed this post Subscribe to our feed


  1. Unknown |

    What's your opinion of 403? When is a 403 more appropriate then a 401?

  2. S. Potter |

    Great question and I don't know why I didn't address it in the original blog post.

    From the documentation on HTTP protocol I have read 403 "Forbidden" is most appropriate when the request is not able to be fulfilled. The HTTP docs says something like the following for a 403 status code:
    "Authorization will not help and the request SHOULD NOT be repeated."

    An example might be when you have configured your web application (via web server configuration or within your own application) to not fulfill certain requests if either SSL is (or is not) used OR if the client is (or is not) in a range of IP addresses.

    So 403 is not appropriate when the requirement is simply that a client must login successfully to the web application.

    I hope this helps.

  3. Anonymous |

    More generally:

    401 is for when you've not provided authentication credentials for a resource that requires them, or the ones you've provided are invalid for some reason.

    403 is for when you've provided authentication, and it's valid, but it's not sufficient for access to whatever resource you're requesting.

    It's the different between authentication and authorization.

  4. S. Potter |

    Exactly. I prefer to give specific examples since generic explanations often need background. You would be surprised how often I meet even experienced developers who didn't know the difference between authentication and authorization.


Post a Comment