HTTP status code for update and delete?
Asked Answered
E

10

1828

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

Evasion answered 26/2, 2010 at 15:16 Comment(0)
G
2750

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.

PUT

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.

DELETE

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

Source: List of HTTP status codes: 2xx Success

Grade answered 26/2, 2010 at 15:18 Comment(15)
Very useful post! However I am wondering what should be the HTTP status code is the request sent by the client is valid (DELETE mySite/entity/123) and the entity to delete does not exist.Saintly
@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.Grade
@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.Willms
@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.Rescission
Ceph returns 201 for successful creation with PUT.Octosyllabic
@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.Penile
@Penile 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.Rescission
@Gili: perhaps the wiki 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.Rescission
@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).Penile
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 200Discredit
PUT could be 201 if the resource did not exist and has therefore been created.Straightedge
@Gili, did you mean rm -f on Linux? rm will give you an error if the file doesn't exist.Sphingosine
DanielVassallo, @Rescission 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.Lewak
Keep 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." w3.org/Protocols/rfc2616/rfc2616-sec10.htmlYodle
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://mcmap.net/q/45868/-status-code-when-deleting-a-resource-using-http-delete-for-the-second-time/2157640Plasterwork
G
1007

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).

HTTP 1.1 decision diagram

Source: https://github.com/for-GET/http-decision-diagram

Gemperle answered 26/2, 2010 at 15:23 Comment(17)
The diagram is amazing. Is there a higher resolution version for printing out?Fortunia
In the context of POST of an existing resource, another SO discussion (#3826490) suggests to send 409 Conflict or 302 Found instead of appending the content.Adelia
Maybe this? raw.github.com/andreineculau/http-decision-diagram/master/v4/… High res and pretty niceMweru
I'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 OKInescutcheon
501 and 405 should both be checked before 401 and 403. Updated version has it correct: raw.github.com/for-GET/http-decision-diagram/master/httpdd.pngBacksaw
@Backsaw Awesome stuff, but why there is no POST code there?Broussard
@doremi: RFC 5789 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.Civil
I think "Deleted? / Response includes an entity? / Yes & No" labels should be swapped? No response entity should lead to 204.Adebayo
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 DELETEIonogen
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.Maker
This diagram is beautiful. Does anybody know what tool was used to create it? We need to generate some of these.Muskmelon
@joshuapinter To answer myself, it looks like Omnigraffle was used to create this graph, I think: github.com/for-GET/http-decision-diagram/blob/master/…Muskmelon
@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.Akihito
@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.Akihito
Keep 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." w3.org/Protocols/rfc2616/rfc2616-sec10.htmlYodle
Is there some documentation on the vocabulary used in the diagram? Such as what terms like "to_content" in N8 mean?Jacks
first link is brokenGq
T
185

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.

Tebet answered 24/9, 2013 at 12:14 Comment(6)
This answer is made up almost entirely of two large quotes, but there's no attribution. Where are you quoting from?Lempira
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.Flout
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.Tebet
I'd add HTTP 422 Unprocessable Entity. It helps to distinguish between a "Bad request" (e.g. malformed XML/JSON) and invalid field values.Stunk
@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)Cordalia
I think this is a question of design, but I should return 404 in this caseTebet
C
20

RFC 2616 describes which status codes to use.

And no, it's not always 200.

Cymatium answered 26/2, 2010 at 15:20 Comment(0)
M
17

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
Mythos answered 5/7, 2019 at 10:56 Comment(0)
O
11

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.

Oxygen answered 8/1, 2013 at 21:15 Comment(0)
C
6

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.

Chimerical answered 29/5, 2015 at 2:2 Comment(0)
W
3

In June 2014 RFC7231 obsoletes RFC2616. If you are doing REST over HTTP then RFC7231 describes exactly what behaviour is expected from GET, PUT, POST and DELETE

Wistful answered 22/11, 2016 at 15:52 Comment(0)
F
2
{
    "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"
    }
}
Fluke answered 9/11, 2020 at 12:33 Comment(1)
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?Illyrian
P
0

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.

Perales answered 11/11, 2021 at 12:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.