42

I'm designing a REST API for a project where users are always on one of several "plans" - each plan defines some resource limits, such as the max number of users an account may have or the max number of data they may upload. Once one of these limits is reached, users can upgrade their plans (essentially pay up) to get more resources.

I want to return a special status code indicating a situation where the action cannot be performed due to account resource limits, and upgrading the plan will resolve this - for example if a user uses 100% of their storage capacity and try to upload an additional file, they will get this response.

The candidates are, IMHO:

  • 403 Forbidden - however, I would like to distinguish between this case and other cases where the user simply lacks the permission to perform this action.

  • 401 Unauthorized - not a good idea, we're using this for authentication related problems.

  • 402 Payment Required - makes kind of sense but I'm worried about using a non-standard yet reserved status code

  • Something even less standard like 423 Locked as its unlikely we'll use it for anything else in the future

Another option is to go with something very standard such as 403 but indicate the specifics of the error in the response body.

I'm wondering which approach you believe would (a) work best in the long run and (b) would stick more nicely to RESTful principles.

4
  • 1
    There is HTTP 507 Insufficient Storage. Jul 1, 2015 at 9:42
  • RFC4331 might be relevant, it's about quota limits for WebDAV. Jul 1, 2015 at 9:45
  • @CodesInChaos this shouldn't be a 5xx error, and storage was only an example (the real project is not about storage at all in fact, it was just a good analogy).
    – shevron
    Jul 1, 2015 at 12:32
  • 3
    The HTTP 429 Too Many Requests response status code indicates the user has sent too many requests in a given amount of time Sep 30, 2019 at 1:01

3 Answers 3

24

I think 403 is the only reasonable response, though 405 Method Not Allowed or 409 Conflict might be acceptable, I don't think either are as good as 403 which states:

The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity

If you return a 403 error, it'll include some information on why the resource was denied - invalid permission is only the most common case, exceeded limits isn't much different - you don't have permission because your limit was exceeded.

35

I believe 403 is wrong, because 403 is for situations where you aren't getting access to the resource, and there is no way whatsoever to get access. For your customers, there is obviously a way to get access: Pay up.

401 is truly wrong, because not only are you using it for authentication, but that is what it is there for.

Since you are writing an API, I assume that someone else will have to write code that uses the API, and that person needs to read your API spec. You might go with 429 "Too many requests". It is usually intended for rate limiting (where a client can make 100 requests per day, for example), but does reasonably apply to your situation. 402 (Payment required) would also be acceptable, I think. Depends on what tools you expect people to use to use your API. 429 has the risk that a clever tool tries to send fewer requests per minute/hour/day and never succeeds.

BTW according https://www.rfc-editor.org/rfc/rfc6585 the 429 error should also contain an html message describing the nature of the problem, so there's a good chance that the user is actually told what the problem is, if you supply that information in your response.

5
  • 3
    402 is an option but I prefer to reserve 429 for actual rate limiting purposes which we are likely to add in the future
    – shevron
    Jul 1, 2015 at 12:34
  • Google seems to use 403 though I like 429 much better. I've seen some custom implementations of http clients that did some weird stuff on 401 and 403 (for example a website would log the user off if it ever got 401 or 403 from the api). Oct 11, 2016 at 11:21
  • 1
    I also prefer status 429, moreover this status code must not be stored by a cache according to the RFC. The current version of the Google Analytics API (v4) also uses 429.
    – Merwan
    Jun 2, 2020 at 15:41
  • I really like 403 because it tells people to stop sending more requests. Jan 31, 2022 at 2:52
  • besides 429 "Too Many Requests", there could be a use for 425 "Too Early" (RFC 8470) -- "Indicates that the server is unwilling to risk processing a request that might be replayed." -- based on a reputable source called Wikipedia
    – BogdanBiv
    Jul 19, 2022 at 9:01
0

WebDAV uses HTTP 507 Insufficient Storage for this and includes an additional error code for quota exceeded in the request body, to distinguish it from other kinds of storage limitations.

1
  • 21
    It seems counterintuitive to use a 5xx code for this. Jul 1, 2015 at 10:00

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