I have a RESTful API. There are 3 versions of it: v1, v2, and v3. I am about to publish v4, and we have decided to discontinue v1, meaning that all requests to http://example.com/v1/resource will fail, but calls to http://example.com/v2/resource will continue to work.

What is the appropriate way to indicate failure? I considered using a 410 GONE status code, but that indicates that the resource is no longer available. The resource likely IS still available, though, only it must be requested in a different way.

I also considered a generic 400 status code, but that seemed weird as well. Is there a standard answer for this?

  • There is no HTTP status code for API failure because APIs have nothing to do with HTTP. You say, the resource is still available but it must be requested a different way then, in REST, that is not the same resource so, no, it is not available.
    – Rob
    Commented Aug 22, 2019 at 12:04

4 Answers 4


There doesn't seem to be a standard.

The StackOverflow answer leans towards 410 GONE, but I think 301 MOVED PERMANENTLY is more appropriate.

To make the correct choice, we have to look at your specific case. If your goal is to have all calls being made to API v1 fail without taking any further action, 410 GONE works for that. If you want some continuity, such as redirecting the client to a newer version of your API where their call may succeed, 3XX works, but which do you choose? I think that if you're trying to shut down API v1, 301 MOVED PERMANENTLY helps indicate that better than 303 SEE OTHER because 301 suggests that all future requests should be made to the new url whereas 303 does not indicate whether or not this situation is permanent.

I would recommend engineering the API in such a way that each version remains backwards compatible, so that 301 MOVED PERMANENTLY would transparently keep your API alive and up to date whenever you add new endpoints for new API versions. I think that's what you're trying to do anyway.

HTTP Status Codes

HTTP status code 302 was originally too broad and thus became incorrectly implemented/used, so 303 and 307 were made to distinguish between 302's dual use case. Some APIs use 303 for other purposes.

301 MOVED PERMANENTLY - The 301 (Moved Permanently) status code indicates that the target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs.

302 FOUND - The 302 (Found) status code indicates that the target resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client ought to continue to use the effective request URI for future requests.

303 SEE OTHER - A 303 response to a GET request indicates that the origin server does not have a representation of the target resource that can be transferred by the server over HTTP. However, the Location field value refers to a resource that is descriptive of the target resource, such that making a retrieval request on that other resource might result in a representation that is useful to recipients without implying that it represents the original target resource.

410 GONE - The 410 (Gone) status code indicates that access to the target resource is no longer available at the origin server and that this condition is likely to be permanent. If the origin server does not know, or has no facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) ought to be used instead.

How do existing APIs handle this?

Maybe you can take a page from Google's Youtube API:

When an API request fails, YouTube will return an HTTP 4xx or 5xx response code that generically identifies the failure as well as an XML response that provides more specific information about the error(s) that caused the failure. For each error, the XML response includes a domain element, code element and possibly a location element.

Further reading:

  • 3
    301 seems dangerous. That would cause automatic redirects to a place that may not have the same canonical meaning. Commented Oct 21, 2014 at 21:21
  • 1
    Appreciate the input. All 3XX codes indicate that the client must take an additional action (redirect) by supplying an alternative url in the Location header. It's interesting to note that each code has slightly different redirect behavior; a 303 will redirect a POST to the new location as a GET. I will certainly be updating this answer with more info.
    – perry
    Commented Oct 21, 2014 at 23:27

Redirects are great for resources that have moved. Instead of a 301 permanent redirect (which would indicate a rename without API changes), I would use a 303 "See Other" redirect.


Need to still support legacy without redirects? Even if you are still supporting it and deep down it is still implemented, the 501 seems rather hand in hand to your situation. Those in the know could still use it, while randoms would see the 501 for v1.

10.5.2 501 Not Implemented

The server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource.



I would use 503 with a message that the service is unavailable and indicate to use the newer version. This message can be returned for 50% of the calls and in time gradually increase to 100%.

For a transparent migration, I would use 308 - Permanent redirect, as this method does not modify verb (POST will be POST) unlike 301.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.