What HTTP response code to use for failed POST request? - http

What HTTP response code should be returned when a POST request was not successful and a request body was correctly formatted?
For successful POST request i am using 201 - Created, but there is no equivalent not created code.
I am thinking either 400 - bad request but that would actually point user that a request is poorly formatted or 304 - not modified.

What HTTP response code should be returned when a POST request was not successful and a request body was correctly formatted?
If you mean the syntax of the request payload is valid but it cannot be processed due to invalid data, you can use 422:
11.2. 422 Unprocessable Entity
The 422 (Unprocessable Entity) status code means 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.
Remember to provide a good description in the response payload explaining what's wrong with the payload. Refer to the RFC 7807 for details on how to report problems in HTTP APIs.
Updates (according to the comments)
The reason why a POST request would fail is more of a business logic error, for example "account balance too low to withdraw 5.00 USD".
For the situation described in your comment, 403 or 409 would be a better fit.
6.5.3. 403 Forbidden
The 403 (Forbidden) status code indicates that the server understood
the request but refuses to authorize it. A server that wishes to
make public why the request has been forbidden can describe that
reason in the response payload (if any). [...]
6.5.8. 409 Conflict
The 409 (Conflict) status code indicates that the request could not
be completed due to a conflict with the current state of the target
resource. This code is used in situations where the user might be
able to resolve the conflict and resubmit the request. The server
SHOULD generate a payload that includes enough information for a user
to recognize the source of the conflict. [...]

Related

Best practices for API response status codes

I am building an API and I am returning this kind of status codes for each method (e.g., "register_user"):
200 (OK) when the user has been registered successfully
403 (forbidden) when there are missing parameters in the request
409 (conflict) when a user was already registered
In addition to the status code, I return a "message" field explaining what happened. Do you consider returning these codes in this example a good practice? Or should I return 200 in all of them but an error in the "message" field?
The 403 (Forbidden) status code indicates that the server understood
the request but refuses to authorize it. A server that wishes to
make public why the request has been forbidden can describe that
reason in the response payload (if any).
-- RFC 7231, 6.5.3
That doesn't sound like what you've got at all. The other two are reasonable. Missing parameters are typically handled with a 400 response code.

What's the appropriate HTTP status code when the request is missing a required cookie?

I have an API endpoint and the request should have a cookie (not authentication). What would be the correct HTTP status code to return if it isn't present?
I would assume a 400 Bad Request would be the best.
No much details are provided in your question, but I guess 400 (Bad Request) is a good option:
6.5.1. 400 Bad Request
The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error (e.g., malformed request syntax, invalid request
message framing, or deceptive request routing).
However, depending on your requirements, you also could consider the 422 (Unprocessable Entity) status code, defined in the WebDAV specification, which is just an extension of the HTTP protocol:
11.2. 422 Unprocessable Entity
The 422 (Unprocessable Entity) status code means 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.
Just remember providing a good description in the response payload explaining what's missing in the request.
I would consider a 403 forbidden status code for this situation - where everything else is fine but the request is missing a cookie. To copy its details from the linked reference:
The server understood the request but refuses to authorize it.
If authentication credentials were provided in the request, the server considers them insufficient to grant access
Status 401 unauthorized is for when the request lacks authentication credentials. But 401 also requires the response to contain a WWW-Authenticate header field. Based on the question, the request should have a cookie but doesn't, and it isn't a matter of authentication.
Status 400 is when the client request was erroneous, which might be a bit misleading for the scenario the OP describes.
Status 422 might be appropriate, but I think, a bit too generic since it means something on the lines of everything was okay, but the server is unable to process the request.

http status code to use when server suspects posted form data is spam

Leaving aside the question of whether or not you should return "helpful" http status codes to someone who is spamming you, what would the appropriate http response code be in this situation. Let's say that you are scanning the form for blacklisted words and the submission has some.
403 Forbidden seems like the most appropriate code. The description from RFC 2616 says:
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 the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
A better option may be the new 422 Unprocessable Entity code, defined in RFC 4918.
The 422 (Unprocessable Entity) status code means 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.
This blog post recommends it for situations like yours, where there's a semantic problem with the posted content, rather than a syntactic problem.
For me for SCAM or SPAM fits best HTTP 451.
HTTP 451 Unavailable For Legal Reasons is a proposed standard error status code of the HTTP protocol to be displayed when the user requests a resource which cannot be served for legal reasons, such as a web page censored ... The RFC 7725 is specific that a 451 response does not indicate whether the resource exists but requests for it have been blocked, if the resource has been removed for legal reasons and no longer exists, or even if the resource has never existed, but any discussion of its topic has been legally forbidden.

Is Http status code 412 suitable for error based on rules defined in our domain

I have an api endpoint that returns a Voucher object.
The voucher is retrieved from a third party.
There are some conditions, for example an expired date, that we check for / validate on.
So, if a client application requests /voucher/1234 voucher with id 1234 is retrieved from the third party.
If the expired date is < now, we need to return an error.
I want to return standard HTTP errors.
Which would be the most suitable?
I initially thought a 412 would be, but now I'm not sure.
HTTP 412 is used when the server doesn't meet one of the preconditions(If-Match, If-Modified-Since, etc) supplied in the request header.
The very generic way would be to return HTTP 400 + specific error message on invalid fields.
However more and more populer APIs are starting to use HTTP extensions to be more granular with the error feedback to the client. Twitter and GitHub use HTTP 422 Unprocessable Entity as defined in the WebDAV HTTP extension. HTTP 422 says that :
The 422 (Unprocessable Entity) status code means 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.
Your server understands what the user wants to do and understands what the data contains, it just won't let you do that. So, Http 422 looks good for you.

REST response code for invalid data

What response code should be passed to client in case of following scenarios?
Invalid data passed while user registration like wrong email format
User name/ Email is already exists
I chose 403. I also found following that I feel can be used.
Wikipedia:
412 Precondition Failed :
The server does not meet one of the preconditions that the requester
put on the request
Suggest code if I should use other than 403.
400 is the best choice in both cases. If you want to further clarify the error you can either change the Reason Phrase or include a body to explain the error.
412 - Precondition failed is used for conditional requests when using last-modified date and ETags.
403 - Forbidden is used when the server wishes to prevent access to a resource.
The only other choice that is possible is 422 - Unprocessable entity.
I would recommend 422. It's not part of the main HTTP spec, but it is defined by a public standard (WebDAV) and it should be treated by browsers the same as any other 4xx status code.
From RFC 4918:
The 422 (Unprocessable Entity) status code means 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.
If the request could not be correctly parsed (including the request entity/body) the appropriate response is 400 Bad Request [1].
RFC 4918 states that 422 Unprocessable Entity is applicable when the request entity is syntactically well-formed, but semantically erroneous. So if the request entity is garbled (like a bad email format) use 400; but if it just doesn't make sense (like #example.com) use 422.
If the issue is that, as stated in the question, user name/email already exists, you could use 409 Conflict [2] with a description of the conflict, and a hint about how to fix it (in this case, "pick a different user name/email"). However in the spec as written, 403 Forbidden [3] can also be used in this case, arguments about HTTP Authorization notwithstanding.
412 Precondition Failed [4] is used when a precondition request header (e.g. If-Match) that was supplied by the client evaluates to false. That is, the client requested something and supplied preconditions, knowing full well that those preconditions might fail. 412 should never be sprung on the client out of the blue, and shouldn't be related to the request entity per se.
It is amusing to return 418 I'm a teapot to requests that are obviously crafted or malicious and "can't happen", such as failing CSRF check or missing request properties.
2.3.2 418 I'm a teapot
Any attempt to brew coffee with a teapot should result in the error
code "418 I'm a teapot". The resulting entity body MAY be short and
stout.
To keep it reasonably serious, I restrict usage of funny error codes to RESTful endpoints that are not directly exposed to the user.

Resources