PUT vs POST
PUT vs POST for REST APIs: idempotency, which one creates vs replaces a resource, and the mistake most APIs make.
Last updated
The short answer
POST creates a new resource and lets the server assign its URL, so calling it twice can create two resources. PUT replaces a resource at a URL the client already knows, and calling it twice with the same body should leave the server in the same state — that's what 'idempotent' buys you.
| Dimension | PUT | POST |
|---|---|---|
| Idempotent | Yes — repeat calls, same result | No — repeat calls, more resources |
| Target URL | Specific resource (/orders/42) | Collection (/orders) |
| Semantics | Replace the resource entirely | Create a new subordinate resource |
| Who picks the ID | Client already knows it | Server usually assigns it |
| Typical success status | 200 OK or 204 No Content | 201 Created |
| Partial update | Not intended — that's PATCH | Common in practice (loosely) |
Choose PUT when
- →You're updating a resource at a URL the client already owns, like saving a user's profile at /users/42.
- →You want retries to be free — a dropped connection and a resubmit should never create duplicates.
- →You're replacing the entire resource representation, not patching one field.
Choose POST when
- →You're creating a new resource and letting the server assign its ID and URL, like submitting a new order.
- →The action isn't really a resource update at all — triggering a job, sending an email, processing a payment.
- →You're sending data that doesn't map cleanly onto REST resource semantics, like a search with a large payload.
The catch nobody mentions
Idempotent doesn't mean 'safe' or 'side-effect free' — a PUT handler that decrements a counter each call, rather than setting an absolute value, breaks the idempotency guarantee even though the verb promises it. Using PUT doesn't make retries safe automatically; your handler has to actually implement replace-with-this-representation semantics for the guarantee to hold.