I'm writing a web service with REST schemantics where the user with a standards compliant web browser will be filling a form which is processed by the server. To avoid double submit if the user presses Reload after receiving the response, the server always replies to any form submission (HTTP POST) with HTTP status 303 and gives user visible response with the following HTTP GET request. I'm currently using HTTP status 200 OK for the returned page.
This seems to work fine in all browsers in practice both for logically failed and successful forms with human users. However, I'm wondering, is the HTTP status 200 really the correct status code for the GET request, if the original form submission was not actually accepted?
For example, the form might contain a field for email addess and if the user enters non-acceptable email (whatever validation the server is doing during the POST submission), the form should be re-rendered via the GET request (after 303 response in between) and the problematic field should be hightlighted (I can do this server-side just fine). However, Using HTTP status 200 for the rendered view seems a bit weird because the form submission logically failed.
It would seem logically better if I could use some 400 series status code for the actual POST request but I have to use HTTP 303 status code to get the correct schemantics to switch from POST request to GET request.
Should the GET request use something else but HTTP status 200 when the previous POST request before 303 redirect technically succeeded but logically/schemantically failed? If I were to reply to the POST request with HTTP status 303 and reply to the following GET request with HTTP status 422, would that cause problems with some user agents? Technically the returned page is totally okay (to allow 200 OK) but the form content as filled by the user was unacceptable and I'll be prefilling all the other form data but password fields on the re-rendered form to match original user input. And nothing was actually stored on the server side so 422 would make sense, too.
One existing question What's an appropriate HTTP status code to return by a REST API service for a validation failure? seems to be about the same thing but without using HTTP status 303 response for the initial request in the middle of the sequence.