I'm creating a RESTful API that will process a number of user interactions, including placing orders using stored credit cards.
In the case of a successful order, I'm returning a 200 OK, and in the case where the order request is malformed or invalid I'm returning a 400 Bad Request. But what should I return if there is a problem during the actual processing of the order?
- Client POSTS order to server for a user resource. If user does not exist, 404 Not Found is returned.
- Order format and information is validated. If not valid, 400 Bad Request is returned.
- Order is processed. If the order is successful, a 201 Created is returned for the order. If an unexpected error is encountered, a 500 Server Error is returned.
The last step is the problem - what do I return if the order doesn't complete for any other reason? Possible scenarios could include:
- Product is sold out
- User maximum order limit reached
- Credit card transaction failure (insufficient funds, etc.)
This doesn't seem like it would be appropriate for either a 400 or 500. If anything I could see it as a 400 if there's no better code - the request was invalid according to the business rules. It just doesn't seem accurate.
Edit: Also found this existing discussion of the same topic. All of the answers there seem to point to using status codes for this type of violation, with some discussion between using 400, 409, or the 422 extension.
I know this question is old, but I came up with the very same question today. If my user runs out of credits, what status code should my REST API return?
I tend to lean towards
402 Payment Required
:According to Wikipedia:
And indeed they do:
Error type:
Error code:
The server understands the content type of the request entity (hence a 415 Unsupported Media Type status code is inappropriate), and the syntax of the request entity is correct (thus a 400 Bad Request status code is inappropriate) but was unable to process the contained instructions.
For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
https://httpstatuses.com/422
I do'nt think 400 can be used for all the business scenario. It can be used for basic data input validation. Beyond that we might have hard to time fit other business logic into this error code. The error handled by this are mostly design time errors which developer will encounter possibly during the coding of the client.
Let's say all parameters are correct and let's say we are passing user account number into the request.
So request is now no longer a bad request, the server is able to accept the request. But now it is refusing to fulling the request based on new information available which is - account does not have sufficient balance.
I would suggest we should use 403 with appropriate error message in those scenarios.
Other possible error code could be 409 conflict. But that is used in scenarios where the resource is in in consistent state.
You should use 400 for business rules. Don't return 2xx if the order was not accepted. HTTP is an application protocol, never forget that. If you return 2xx the client can assume the order was accepted, regardless of any information you send in the body.
From RESTful Web Services Cookbook:
I'll leave it to you to decide between 4xx and 5xx, but you should use an error status code.
I go with 406
Not Acceptable
.Here's a 4xx list:
How about
424 Failed Dependency
? The spec describes it as:You can tell the client (or pretend) that you have internal actions which are supposed to create the order, and deduct the balance, and that one of those actions failed, and hence the request failed.
As far as I can see, "action" is quite a broad term, and can be used in a variety of situations, including insufficient stock, insufficient credit, or warehouse party night.
Another option might be
422 Unprocessable Entity
:Trying to request an item which is out of stock, or when you have insufficient credit, could be considered a mistake at the semantic level.
Arguably insufficient stock or warehouse party night could be considered temporary states, so the request could be retried again later. That situation can be indicated by
503 Service Unavailable