What status code should I set for UPDATE
(PUT
) and DELETE
(e.g. product successfully updated)?

- 398,270
- 210
- 566
- 880

- 35,055
- 30
- 109
- 163
10 Answers
For a PUT request: HTTP 200, HTTP 204 should imply "resource updated successfully". HTTP 201 if the PUT request created a new resource.
For a DELETE request: HTTP 200 or HTTP 204 should imply "resource deleted successfully".
HTTP 202 can also be returned by either operation and would imply that the instruction was accepted by the server, but not fully applied yet. It's possible that the operation fails later, so the client shouldn't fully assume that it was success.
A client that receives a status code it doesn't recognize, but it's starting with 2 should treat it as a 200 OK.
If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.
A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity.
Source: IETF: RFC-9110 Method Definitions
HTTP 200 OK: Standard response for successful HTTP requests. The actual response will depend on the request method used.
HTTP 204 No Content: The server successfully processed the request, but is not returning any content

- 1,248
- 8
- 17

- 337,827
- 72
- 505
- 443
-
51Very useful post! However I am wondering what should be the HTTP status code is the request sent by the client is valid (DELETE http://mySite/entity/123) and the entity to delete does not exist. – Martin Dec 30 '11 at 21:27
-
93@Martin: In that case, the service should return an HTTP 404. Strictly speaking, a DELETE or a GET request for a resource that does not exist is **not** a "valid" request - ie. the client should not re-attempt that request because it will never succeed... The HTTP protocol defines 2 categories of problems - those with a 4xx status code, where the client must modify the request before retrying it, and those with a 5xx status code, which indicate that the service ran into trouble and the client should/could retry the same exact request without changing it. – Daniel Vassallo Dec 30 '11 at 21:44
-
7@Martin, Daniel I think you are looking at what a successful call for DELETE is. If you look at DELETE as "make sure the resource is deleted", then it is successful whether or not the resource existed before the call or not. – Jeff Martin Aug 13 '12 at 16:58
-
18@JeffMartin That may be so from the standpoint of the user, but as far as the server is concerned, if the resource does not exist, the server should return 404. – Randolpho Oct 11 '12 at 17:29
-
2Ceph returns 201 for successful creation with PUT. – lethalman Oct 14 '13 at 16:20
-
18@Randolpho, Idempotence is all about getting the same result whether you invoke an operation once or multiple times. The client is asking you to ensure that the resource is deleted. What's the benefit of returning 404? Why does it need to know either way? Now the client logic has to handle two separate response codes instead of one. – Gili Oct 15 '13 at 07:25
-
5@Gili I'm not sure I understand the question. 404 has a specific meaning: the request was bad because the resource did not exist. Allowing a success code gives the client the incorrect belief that the resource *did* exist and was deleted. And a client sure better handle *all* possible response codes than just one if it wants to be a robust and non-error-prone client. – Randolpho Oct 15 '13 at 20:46
-
33@Gili: perhaps [the wiki](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods_and_web_applications) will explain better: *Methods PUT and DELETE are defined to be idempotent... note that idempotence refers to the state of the system after the request has completed, so while the action the server takes (e.g. deleting a record) or the response code it returns may be different on subsequent requests, the system state will be the same every time.* – Randolpho Oct 15 '13 at 20:50
-
7@Randolpho, if you user wants to check the existence of a resource it should use `GET` or `If-Match` headers. It is my understanding that `DELETE` is equivalent to `rm` on Linux: delete the file if it exists, otherwise do nothing. The only time `DELETE` should fail is if the resource exists but it cannot be deleted for some reason (e.g. you don't have sufficient permissions). – Gili Oct 15 '13 at 21:07
-
Guys, don't forget that if you send a 204 as response to a successful PUT, you do not receive any content back. In my case, I didn't realise this (even as the http status code states it is a NO content :) ). So if you want to send a success message back, I would recommend a 206 which sends partial content. Otherwise send a 200 – Mattijs Jun 11 '14 at 04:44
-
1PUT could be 201 if the resource did not exist and has therefore been created. – marcv May 30 '16 at 17:41
-
5@Gili, did you mean `rm -f` on Linux? `rm` will give you an error if the file doesn't exist. – Franklin Yu Dec 16 '16 at 07:05
-
4DanielVassallo, @Randolpho I disagree. With a PUT or a DELETE the client is asking for a certain state to be present on the server. DELETE is not about the deletion but rather "I want this resource to not exist". With a 2xx response, the server informs the client that its request was successful, the state has been attained. By sending a 404, you are "overloading" the status code to inform the client about what the state on the server was before its request, and what the server had to do to attain that state. If it helps your particular business case, go for it, but 2xx is more correct. – Fletch Sep 15 '17 at 08:20
-
1Keep in mind a 204 response, can not have any content in the body! "The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields." https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html – Melroy van den Berg May 04 '21 at 14:03
-
There is a separate Q&A that revolves around what should be the status of subsequent DELETE calls. Spoiler: the answers mostly agree on 404 as idempotency is defined in term of effects on the server. https://stackoverflow.com/q/6439416/2157640 – Palec Sep 17 '21 at 13:59
Short answer: for both PUT and DELETE, you should send either 200 (OK) or 204 (No Content).
Long answer: here's a complete decision diagram (click to magnify).

- 1,921
- 2
- 18
- 21

- 24,821
- 10
- 45
- 52
-
45The diagram is amazing. Is there a higher resolution version for printing out? – KiKi Jun 25 '12 at 10:07
-
1In the context of POST of an existing resource, another SO discussion (http://stackoverflow.com/questions/3825990/http-response-code-for-post-when-resource-already-exists) suggests to send 409 Conflict or 302 Found instead of appending the content. – koppor Jan 10 '13 at 14:37
-
Maybe this? https://raw.github.com/andreineculau/http-decision-diagram/master/v4/http-decision-diagram-v4.png High res and pretty nice – Dmitry Minkovsky Aug 27 '13 at 05:43
-
7I'm curious if the 204 and 200 response after a delete occurs should be reversed, and if they are correct as is, why? Deleted? -> Response includes an entity? -> yes -> 204 No Content; no -> 200 OK – matth Sep 09 '13 at 14:20
-
501 and 405 should both be checked before 401 and 403. Updated version has it correct: https://raw.github.com/for-GET/http-decision-diagram/master/httpdd.png – docksteaderluke Feb 24 '16 at 17:52
-
2@docksteaderluke Awesome stuff, but why there is no POST code there? – george007 Jul 29 '16 at 14:04
-
@doremi: [RFC 5789](https://tools.ietf.org/html/rfc5789) suggests that (like most HTTP methods) it's up to the developer. However, it also explicitly states that responding with 200 (OK) or 204 (No Content) is completely appropriate. – rinogo Aug 30 '16 at 17:15
-
1I think "Deleted? / Response includes an entity? / Yes & No" labels should be swapped? No response entity should lead to 204. – Steve S Feb 08 '17 at 15:59
-
This diagram is awesome. But he don't say 200 for put and post ... for put and post it should be 201 in most case ( rest full application and you can get your entity with a get server/entity/{id} ) but it's ok for 200 on DELETE – amdev Jun 06 '17 at 14:14
-
Updated the diagram to the latest version as it was repeatedly referenced in comments as more accurate. Also, added a link to the original source. – Haralan Dobrev Sep 16 '17 at 08:39
-
This diagram is beautiful. Does anybody know what tool was used to create it? We need to generate some of these. – Joshua Pinter May 23 '19 at 14:36
-
@joshuapinter To answer myself, it looks like Omnigraffle was used to create this graph, I think: https://github.com/for-GET/http-decision-diagram/blob/master/httpdd.graffle – Joshua Pinter May 23 '19 at 14:38
-
@JoshuaPinter this was created with aiSee. Sadly the tool is no longer available as a standalone product. I used to work with graphs a lot back in the day, and no other tool was up to the task. Maybe some are now, but I wouldn't know. It's been ten years. Time flies. – ЯegDwight May 24 '19 at 18:47
-
@JoshuaPinter actually I withdraw that previous comment. I only just noticed that the image has since been replaced by a different one with a link to its source. – ЯegDwight May 24 '19 at 18:51
-
1Keep in mind a 204 response, can not have any content in the body! "The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields." https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html – Melroy van den Berg May 04 '21 at 14:03
-
Is there some documentation on the vocabulary used in the diagram? Such as what terms like ["to_content" in N8](https://github.com/for-GET/http-decision-diagram/blob/master/httpdd.fsm.json#L2950) mean? – Vaibhav Mishra Jun 25 '21 at 00:41
-
Here are some Tips:
DELETE
200 (if you want send some additional data in the Response) or 204 (recommended).
202 Operation deleted has not been committed yet.
If there's nothing to delete, use 204 or 404 (DELETE operation is idempotent, delete an already deleted item is operation successful, so you can return 204, but it's true that idempotent doesn't necessarily imply the same response)
Other errors:
- 400 Bad Request (Malformed syntax or a bad query is strange but possible).
- 401 Unauthorized Authentication failure
- 403 Forbidden: Authorization failure or invalid Application ID.
- 405 Not Allowed. Sure.
- 409 Resource Conflict can be possible in complex systems.
- And 501, 502 in case of errors.
PUT
If you're updating an element of a collection
- 200/204 with the same reasons as DELETE above.
- 202 if the operation has not been commited yet.
The referenced element doesn't exists:
PUT can be 201 (if you created the element because that is your behaviour)
404 If you don't want to create elements via PUT.
400 Bad Request (Malformed syntax or a bad query more common than in case of DELETE).
401 Unauthorized
403 Forbidden: Authentication failure or invalid Application ID.
405 Not Allowed. Sure.
409 Resource Conflict can be possible in complex systems, as in DELETE.
422 Unprocessable entity It helps to distinguish between a "Bad request" (e.g. malformed XML/JSON) and invalid field values
And 501, 502 in case of errors.

- 1
- 1

- 3,442
- 1
- 19
- 34
-
12This answer is made up almost entirely of two large quotes, but there's no attribution. Where are you quoting from? – Quentin Jan 24 '18 at 06:41
-
Is 204 a proper status to return for a PUT request, if the state is not changed effectively? For example, you ask to deactivate a user but the user is already inactive. – Ε Г И І И О Mar 05 '18 at 11:37
-
The PUT request is idempotent, so you can return a 204, because the object *has changed* in the system. PUT is not PATCH, so you're not sure what field do you want to change. You can send back a 501 - 502, if your design needs to know if the object was **exactly** the same as the object in the request but... I don't really like it.. I prefer 204 or, if you want to deactivate an user, without changing more fields, maybe you can use PATCH. – Alfonso Tienda Mar 05 '18 at 13:02
-
1I'd add HTTP 422 Unprocessable Entity. It helps to distinguish between a "Bad request" (e.g. malformed XML/JSON) and invalid field values. – vdboor Apr 19 '18 at 14:18
-
@AlfonsoTienda what to return on DELETE when parent resource is missing? (e.g. if we receive DELETE {{restful-api-base}}/departments/1/colleagues/2 should we say 404 no such department 1 or say 204 deleted even though department 1 is non existent and we are trying to delete the colleague 2 of it) – festiv Feb 10 '22 at 21:06
-
I think this is a question of design, but I should return 404 in this case – Alfonso Tienda Feb 14 '22 at 12:34
RFC 2616 describes which status codes to use.
And no, it's not always 200.

- 776,304
- 153
- 1,341
- 1,358
Here's some status code, which you should know for your kind of knowledge.
1XX Information Responses
- 100 Continue
- 101 Switching Protocols
- 102 Processing
- 103 Early Hints
2XX Success
- 200 OK
- 201 Created
- 202 Accepted
- 203 Non-Authoritative Information
- 204 No Content
- 205 Reset Content
- 206 Partial Content
- 207 Multi-Status
- 208 Already Reported
- 226 IM Used
3XX Redirection
- 300 Multiple Choices
- 301 Moved Permanently
- 302 Found
- 303 See Other
- 304 Not Modified
- 305 Use Proxy
- 306 Switch Proxy
- 307 Temporary Redirect
- 308 Permanent Redirect
4XX Client errors
- 400 Bad Request
- 401 Unauthorized
- 402 Payment Required
- 403 Forbidden
- 404 Not Found
- 405 Method Not Allowed
- 406 Not Acceptable
- 407 Proxy Authentication Required
- 408 Request Timeout
- 409 Conflict
- 410 Gone
- 411 Length Required
- 412 Precondition Failed
- 413 Payload Too Large
- 414 URI Too Long
- 415 Unsupported Media Type
- 416 Range Not Satisfiable
- 417 Expectation Failed
- 418 I'm a teapot
- 420 Method Failure
- 421 Misdirected Request
- 422 Unprocessable Entity
- 423 Locked
- 424 Failed Dependency
- 426 Upgrade Required
- 428 Precondition Required
- 429 Too Many Requests
- 431 Request Header Fields Too Large
- 451 Unavailable For Legal Reasons
5XX Server errors
- 500 Internal Server error
- 501 Not Implemented
- 502 Bad Gateway
- 503 Service Unavailable
- 504 gateway Timeout
- 505 Http version not supported
- 506 Varient Also negotiate
- 507 Insufficient Storage
- 508 Loop Detected
- 510 Not Extended
- 511 Network Authentication Required

- 3,255
- 27
- 43
In addition to 200 and 204, 205 (Reset Content) could be a valid response.
The server has fulfilled the request and the user agent SHOULD reset the document view which caused the request to be sent ... [e.g.] clearing of the form in which the input is given.

- 21,801
- 10
- 54
- 70
Since the question delves into if DELETE "should" return 200 vs 204 it is worth considering that some people recommend returning an entity with links so the preference is for 200.
"Instead of returning 204 (No Content), the API should be helpful and suggest places to go. In this example I think one obvious link to provide is to" 'somewhere.com/container/' (minus 'resource') "- the container from which the client just deleted a resource. Perhaps the client wishes to delete more resources, so that would be a helpful link."
http://blog.ploeh.dk/2013/04/30/rest-lesson-learned-avoid-204-responses/
If a client encounters a 204 response, it can either give up, go to the entry point of the API, or go back to the previous resource it visited. Neither option is particularly good.
Personally I would not say 204 is wrong (neither does the author; he says "annoying") because good caching at the client side has many benefits. Best is to be consistent either way.

- 13,270
- 8
- 79
- 72

- 9,873
- 5
- 66
- 75
{
"VALIDATON_ERROR": {
"code": 512,
"message": "Validation error"
},
"CONTINUE": {
"code": 100,
"message": "Continue"
},
"SWITCHING_PROTOCOLS": {
"code": 101,
"message": "Switching Protocols"
},
"PROCESSING": {
"code": 102,
"message": "Processing"
},
"OK": {
"code": 200,
"message": "OK"
},
"CREATED": {
"code": 201,
"message": "Created"
},
"ACCEPTED": {
"code": 202,
"message": "Accepted"
},
"NON_AUTHORITATIVE_INFORMATION": {
"code": 203,
"message": "Non Authoritative Information"
},
"NO_CONTENT": {
"code": 204,
"message": "No Content"
},
"RESET_CONTENT": {
"code": 205,
"message": "Reset Content"
},
"PARTIAL_CONTENT": {
"code": 206,
"message": "Partial Content"
},
"MULTI_STATUS": {
"code": 207,
"message": "Multi-Status"
},
"MULTIPLE_CHOICES": {
"code": 300,
"message": "Multiple Choices"
},
"MOVED_PERMANENTLY": {
"code": 301,
"message": "Moved Permanently"
},
"MOVED_TEMPORARILY": {
"code": 302,
"message": "Moved Temporarily"
},
"SEE_OTHER": {
"code": 303,
"message": "See Other"
},
"NOT_MODIFIED": {
"code": 304,
"message": "Not Modified"
},
"USE_PROXY": {
"code": 305,
"message": "Use Proxy"
},
"TEMPORARY_REDIRECT": {
"code": 307,
"message": "Temporary Redirect"
},
"PERMANENT_REDIRECT": {
"code": 308,
"message": "Permanent Redirect"
},
"BAD_REQUEST": {
"code": 400,
"message": "Bad Request"
},
"UNAUTHORIZED": {
"code": 401,
"message": "Unauthorized"
},
"PAYMENT_REQUIRED": {
"code": 402,
"message": "Payment Required"
},
"FORBIDDEN": {
"code": 403,
"message": "Forbidden"
},
"NOT_FOUND": {
"code": 404,
"message": "Not Found"
},
"METHOD_NOT_ALLOWED": {
"code": 405,
"message": "Method Not Allowed"
},
"NOT_ACCEPTABLE": {
"code": 406,
"message": "Not Acceptable"
},
"PROXY_AUTHENTICATION_REQUIRED": {
"code": 407,
"message": "Proxy Authentication Required"
},
"REQUEST_TIMEOUT": {
"code": 408,
"message": "Request Timeout"
},
"CONFLICT": {
"code": 409,
"message": "Conflict"
},
"GONE": {
"code": 410,
"message": "Gone"
},
"LENGTH_REQUIRED": {
"code": 411,
"message": "Length Required"
},
"PRECONDITION_FAILED": {
"code": 412,
"message": "Precondition Failed"
},
"REQUEST_TOO_LONG": {
"code": 413,
"message": "Request Entity Too Large"
},
"REQUEST_URI_TOO_LONG": {
"code": 414,
"message": "Request-URI Too Long"
},
"UNSUPPORTED_MEDIA_TYPE": {
"code": 415,
"message": "Unsupported Media Type"
},
"REQUESTED_RANGE_NOT_SATISFIABLE": {
"code": 416,
"message": "Requested Range Not Satisfiable"
},
"EXPECTATION_FAILED": {
"code": 417,
"message": "Expectation Failed"
},
"IM_A_TEAPOT": {
"code": 418,
"message": "I'm a teapot"
},
"INSUFFICIENT_SPACE_ON_RESOURCE": {
"code": 419,
"message": "Insufficient Space on Resource"
},
"METHOD_FAILURE": {
"code": 420,
"message": "Method Failure"
},
"UNPROCESSABLE_ENTITY": {
"code": 422,
"message": "Unprocessable Entity"
},
"LOCKED": {
"code": 423,
"message": "Locked"
},
"FAILED_DEPENDENCY": {
"code": 424,
"message": "Failed Dependency"
},
"PRECONDITION_REQUIRED": {
"code": 428,
"message": "Precondition Required"
},
"TOO_MANY_REQUESTS": {
"code": 429,
"message": "Too Many Requests"
},
"REQUEST_HEADER_FIELDS_TOO_LARGE": {
"code": 431,
"message": "Request Header Fields Too"
},
"UNAVAILABLE_FOR_LEGAL_REASONS": {
"code": 451,
"message": "Unavailable For Legal Reasons"
},
"INTERNAL_SERVER_ERROR": {
"code": 500,
"message": "Internal Server Error"
},
"NOT_IMPLEMENTED": {
"code": 501,
"message": "Not Implemented"
},
"BAD_GATEWAY": {
"code": 502,
"message": "Bad Gateway"
},
"SERVICE_UNAVAILABLE": {
"code": 503,
"message": "Service Unavailable"
},
"GATEWAY_TIMEOUT": {
"code": 504,
"message": "Gateway Timeout"
},
"HTTP_VERSION_NOT_SUPPORTED": {
"code": 505,
"message": "HTTP Version Not Supported"
},
"INSUFFICIENT_STORAGE": {
"code": 507,
"message": "Insufficient Storage"
},
"NETWORK_AUTHENTICATION_REQUIRED": {
"code": 511,
"message": "Network Authentication Required"
}
}

- 3,365
- 26
- 26
-
512 seems a bit off, it's not standardized and I would assume a validation error being in the 4xx range (like 422). Where did you get this list? – Elmer Feb 19 '21 at 07:17
Generally, 200 OK
and 201 Created
are the best suited for a successful PUT
request.
For DELETE
method, 202 Accepted
and 204 No Content
would be the best choice.

- 497
- 3
- 7