I'm creating a RESTful API for creating users that enforces unique email addresses:
Successful POST /users
: HTTP 201 Created
If I POST
the same email address again, what should the response code be? Is 409 Conflict
the appropriate response code?
Yes, 409 is the most appropriate response code here. Even though you are most likely returning 201 on success, you're still POSTing to a resource which is described as a collection, and POSTing a duplicate email is definitely a conflict with "the current state of the resource" as a collection. You should return a response body with a description of the problem, and hyperlinks to help resolve the problem, if possible.
While the accepted answer is correct in showing the correct status code for the task, I want to add that you are introducing a security vulnerability.
If you return a 409 for account registration, you are just exposing a service for account enumeration.
Depends on the application, if the api is public or not, etc, you may want to return a 201 even if the account wasn't created.
I am not really satisfied with returning a 409 Conflict
for an existing registered email - in my opinion, it's not a client error. So let's take a look at how some big tech companies are handling those cases (at least how they are doing it in their WEB Site APIs).
Gmail (Google) returns a 200 OK
and a JSON object which contains a code which is indicating that the email is already registered.
Facebook is also returning a 200 OK
but re-renders the content in an SPA manner to a recovery page to give the user the option to recover his/her existing account.
Twitter is validating the existing email on-the-fly (via an AJAX call to another resource). The response of the email validation resource is always a 200 OK
. The response contains a JSON object which defines a valid flag to indicate if the email is already registered or not.
Amazon is doing it the same way as Facebook. Returning a 200 OK
and re-rendering the content to a notification page to inform the user that the account already exists and provide him/her possibilities to take further actions like login or password change.
So all these APIs returning always a 200 OK
and presenting to the client/user either additional content to recover their account or an error message which is raised by the body content of the response.
+1 to Barts answer - for security reasons. Usually I would agree that 409 is a good status code for sth. that already exists. But in an environment of user accounts/authentication/authorization etc., I would tend to not exposing the existing user accounts in your database.
Of course there are other mechanisms of handling security at this place. If you do not mind to expose a little number of your accounts, you could add a behavior to your application that returns 401 or 403 on numerous 409-events from one IP.
Another option (in general) is to define a status code on your own to have a 2xx that differs from the existing standard 2xx variants. This could be an option if you do not want to handle an "already exists" as an error. However, this would be regarded as non-standard and would have the same unsafe character like a 409 in your concrete example.
I often use the (WebDAV extension) HTTP 422
Unprocessable Entity:
The request was well-formed but was unable to be followed due to semantic errors