🌐 HTTP Method Reference
What each HTTP method means, whether it's considered safe (no server side-effects) or idempotent (repeating it has the same effect as doing it once), and typical use.
Why the safe and idempotent columns matter
They are not academic labels - infrastructure acts on them. A safe method changes nothing on the server, so proxies and CDNs may cache it and crawlers will follow it. An idempotent method can be repeated with the same end state, so clients, load balancers and proxies are free to retry it after a dropped connection.
safe + idempotent GET HEAD OPTIONS TRACE cacheable, retried freely
idempotent only PUT DELETE safe to retry, changes state
neither POST PATCH CONNECT a retry may duplicate the effect
Every safe method is idempotent; the reverse does not hold. That asymmetry is why a
link that deletes a record must never be a plain GET: a prefetcher or an
antivirus scanner will follow it.
Picking one in practice
- PUT replaces, POST creates.
PUT /users/42writes the whole resource at a URL you already know;POST /usersasks the collection to make one and tell you its new URL in theLocationheader. - HEAD must match GET. The same headers, including
Content-Length, with the body omitted - which is what makes it useful for checking a file's size or timestamp before downloading it. - OPTIONS is mostly CORS. Browsers send it as a preflight before any cross-origin request that is not a simple GET or form POST.
Frequently asked questions
What is the difference between PUT and POST?
PUT is idempotent and addresses a specific resource, so sending it twice leaves one record in the same state. POST is not, so a double submission can create two records - which is why payment endpoints use an idempotency key.
Is PATCH idempotent?
It depends on the patch document. A JSON Merge Patch that sets fields to fixed values is idempotent in practice; an operation such as "append to this array" or "increment this counter" is not. The spec therefore lists PATCH as not idempotent.
Can a GET request have a body?
It is not forbidden, but it has no defined meaning, and proxies, caches and some servers drop it or reject the request. Put the parameters in the query string, or use POST if the payload is genuinely too large for a URL.