We are developing a standard REST service using HTTP status codes as its response code if something went wrong. (e.g. invalid user input would return \"400 Bad Request\" to
Wherever you put your feedback, whether in the message body (content) or in a Warning header, be careful to avoid giving any information that might be helpful to an attacker doing penetration testing on your system.
Sometimes less info is better.
I'm in favor of using headers for warning only when the request succeeds in general.
For example a service that get's a user's details, but some of the details come from a third party which often goes down. In our case it was appropriate to leave that section of the user data blank, but show a warning to the user that some data is missing.
So the request returned a 200 Success with a payload that contained everything we could retrieve, but then had warning headers that described the error for the rest.
If this proposal is accepted, it presents an alternative for sending detail error messages. [http://tools.ietf.org/html/draft-nottingham-http-browser-hints]
Despite it being an I-D, it's fairly stable lately, and I see no problem with building your own implementation. (I have done.)
I'm in favour of the general approach. We should assume that the client developer is in a different team from the service developer, maybe in a different timezone etc. Possibly even a different company. It's no good just returning a "no that's a bad request" response, how can the client fix the problem.
So philosophically: tell the client about the things they have a responsibility to fix. Errors that are purely the scope of the server (eg. database connection error, or some logical problem) it's fair just to return a 500 error. And here I would not send any detail back, we don't want to expose details of our internal implementation to the client.
Until now I've been returning data in the body of the response, using JAX/RS:
return Response.status(400).entity("some message here").build();
I'm thinking that your use of headers may actually be a cleaner appraoch.
Why not just change the reason phrase? That's what it is there for. The "Bad Request" text is just the default. If you want to include more information then use the response body. The HTTP spec says you SHOULD include a response body with details of an error.
UPDATE
Based on a more recent reading of RFC 7231 and related material, it appears the only valid reason for changing the reason phrase is to localize the text, not to provide a more specific meaning. Sorry about that.
429 Too Many Requests (RFC 6585) The user has sent too many requests in a given amount of time. Intended for use with rate limiting schemes.
Since you are allowing one request per lifetime, you are implementing a rate limiting scheme, so this is the appropriate HTTP response.
You can also (and are encouraged by the HTTP spec) to customize the HTTP Response body, so you can change "Too Many Requests" to any explanation you want.