HTTP Methods Explained: GET, POST, PUT, PATCH, DELETE
Photo by Unsplash on Unsplash
Table of Contents
The One-Screen Summary
The first time I built an API, I used POST for basically everything because it "worked." It did work — right up until a flaky network made the client retry, my non-idempotent POST ran twice, and a user ended up with two identical orders. That bug is what finally made these properties click for me. The method you choose isn't just a label; it's a promise about what happens when things go wrong.
Below, I'll go through each method, then the safe-versus-idempotent distinction that trips almost everyone up, and finish with the PUT-versus-PATCH question I still see argued in code review.
The Five You'll Use Every Day
POST submits data to create something new or to kick off a process — registering a user, submitting a form, starting a payment. The server decides the new resource's URL and usually returns it. POST is the catch-all, which is both its strength and the reason people overuse it.
PUT replaces a resource at a known URL with whatever you send. If you PUT a user object to `/users/42`, you're saying "make `/users/42` look exactly like this, replacing what's there." Send a partial object and you risk wiping the fields you left out.
PATCH applies a partial update. You send only the fields that change — `{ "email": "new@example.com" }` — and the rest stays as-is. It's the right verb for "edit this one thing."
DELETE removes the resource at a URL. Straightforward. Calling it again on an already-deleted resource typically returns a 404, which is fine — the end state (gone) is the same either way.
The method you pick also shapes the status code you send back. A POST that creates something should answer 201 Created; a DELETE with nothing to return often answers 204 No Content. I unpacked that whole numbering scheme in HTTP status codes explained, and it pairs directly with the verbs here. If you're still fuzzy on how a request and response fit together in the first place, what an API is lays the groundwork.
Safe vs Idempotent — The Part That Trips People Up
Photo by Unsplash on Unsplash
Safe means the method has no side effects on the server — it only reads. GET, HEAD, OPTIONS, and TRACE are safe. Because they don't change state, a proxy can cache them and a browser can prefetch them without asking. Nothing is safe about POST, PUT, PATCH, or DELETE; they all exist to change something.
Idempotent means making the same request once or many times leaves the server in the same final state. This is the property that saves you when networks misbehave. GET is idempotent (reading twice changes nothing). PUT is idempotent — replacing `/users/42` with the same object twice gives you the same result as doing it once. DELETE is idempotent — the resource is gone after the first call and stays gone. Per the modern spec, RFC 9110 is the reference here, and it lays this out cleanly.
The two that aren't guaranteed idempotent are POST and PATCH. POST creates a new resource each time it runs, so two identical POSTs make two orders — my exact bug from earlier. PATCH can go either way: `{ "status": "paid" }` is idempotent (setting it twice is harmless), but `{ "balance": "+10" }` — an increment — clearly isn't, because running it twice adds twenty.
Why does this matter in practice? Retries. Clients, load balancers, and libraries retry failed requests automatically. If your write is idempotent, a retry is harmless. If it isn't, a retry can duplicate data or double-charge someone. For non-idempotent operations like "place order," the common fix is an *idempotency key* — a unique ID the client sends so the server can recognize a retry and refuse to run it twice. Payment APIs like Stripe do exactly this.
PUT vs PATCH, and Picking the Right One
In the real world, plenty of APIs treat PUT loosely and merge instead of replacing — which is exactly why teams argue. My rule of thumb: use PATCH for "change these specific fields," use PUT when the client genuinely owns and sends the whole resource (config files, a settings blob, a document you're overwriting wholesale). When in doubt, PATCH is the safer default for edits because it won't silently erase data you forgot to include.
A few practical habits that have saved me grief:
- Never let GET change state. If you find yourself writing a "GET /deleteUser?id=42" endpoint, stop — that's how crawlers and prefetchers accidentally nuke your data. - Make writes idempotent where you can. PUT and DELETE come idempotent for free; give POST an idempotency key when a duplicate would hurt. - Match the status code to the verb, and return the resource (or its new URL) so the client isn't left guessing. - When you're debugging a response, format it first. I paste raw API JSON into the ToolsFuel JSON formatter to see the structure before I chase down why a PATCH didn't stick.
Methods are also the piece REST leans on hardest — the whole style is built around applying a small set of verbs to resource URLs. If you're weighing that against a single-endpoint approach, REST vs GraphQL gets into where each shines and why the verb vocabulary matters more in one than the other.
There are a couple of methods I skipped that are worth a mention. HEAD is exactly like GET but returns only the headers, no body — handy for checking whether a resource exists or when it last changed without downloading the whole thing. OPTIONS asks the server which methods a resource supports, and it's the method your browser fires automatically as a CORS preflight before certain cross-origin requests. That preflight is why a request can fail before your real call even leaves the browser; if you've hit that wall, the fix usually lives on the server side, and I walked through it in how to fix a CORS error. Knowing these exist rounds out the picture, even if GET through DELETE are the five you'll actually type.
Frequently Asked Questions
What's the difference between PUT and POST?
POST creates a new resource and lets the server decide its URL, so sending the same POST twice usually makes two resources. PUT targets a specific URL you already know and replaces whatever is there, so sending it twice leaves the same result as sending it once. That idempotency is the practical reason to prefer PUT when the client controls the resource's location, and POST when it doesn't.
Is GET or POST more secure?
Neither is inherently secure — both send data in plain text unless you're on HTTPS, which you always should be. The real difference is exposure: GET puts data in the URL, so it lands in browser history, server logs, and referrer headers, while POST keeps it in the request body. That makes POST the better choice for anything sensitive, but security comes from TLS and auth, not the verb.
When should I use PATCH instead of PUT?
Use PATCH when you only want to change a few fields and leave the rest of the resource untouched — updating just a user's email, for example. PUT is meant to replace the entire resource, so a partial PUT can wipe fields you didn't include. PATCH is the safer default for edits, while PUT fits cases where the client genuinely sends the whole object.
What does idempotent mean for an API?
It means calling the same request one time or many times leaves the server in the same final state. GET, PUT, and DELETE are idempotent, so a retry after a dropped connection is harmless. POST and PATCH aren't guaranteed to be, which is why duplicate submissions can create duplicate data. When you need a safe retry on a non-idempotent write, an idempotency key lets the server ignore the repeat. You can test these calls with the utilities in the [ToolsFuel tools directory](/tools).
Do these methods only apply to REST APIs?
The methods are part of HTTP itself, so any HTTP request uses one, REST or not. REST just leans on them hardest, mapping verbs onto resource URLs as its core design idea. Other styles like GraphQL mostly send everything over POST and handle the read-or-write distinction inside the query instead, so the verbs matter far less there.
Try ToolsFuel
23+ free online tools for developers, designers, and everyone. No signup required.
Browse All Tools