ScreenshotNeo

BlogGuides

PUT vs. POST: What’s the Difference?

PUT sets the state of a known resource and is idempotent; POST asks a resource to process a submission and may not be safe to repeat.

By the ScreenshotNeo team30 September 20269 min read

PUT vs. POST: What's the Difference?

PUT asks a server to create or replace the state of the resource at a URI the client already knows. POST asks the target resource to process submitted content according to its own rules. PUT is idempotent by HTTP semantics; POST is not guaranteed to be. Choose based on the intended operation, not the shortcut “PUT updates, POST creates.” Either method can create a resource, and POST has uses beyond creation. Actual behavior depends on what the API endpoint implements.

This distinction matters most when you design an API or decide whether a client can safely retry a request after a timeout. The definitions come from RFC 9110, section 9.3.3 (POST) and section 9.3.4 (PUT).

1. The direct distinction

Question PUT POST
What does the method mean? Create or replace the target resource state with the state defined by the request representation. Ask the target resource to process the request representation according to its own semantics.
Who picks the target URI? The client knows the URI of the resource it wants to set. The client addresses a processing or collection resource; the server may choose a URI for a newly created resource.
Idempotent by HTTP semantics? Yes: repeating an identical request has the same intended effect as making it once. Not guaranteed. A particular POST endpoint may nevertheless define repeat-safe behavior.
Can create a resource? Yes. A successful PUT that creates the target representation returns 201 Created. Yes, among several possible uses.

For example, if a client wants the server-side profile at /users/42 to have a specified state, PUT expresses that intent. If the client submits an order to /orders and the server assigns the new order’s URI, POST expresses that the collection should process the submission. These are examples of API design, not universal endpoint contracts.

PUT targets a known resource state; POST asks the target to process a submission.
PUT targets a known resource state; POST asks the target to process a submission.

2. Why “update versus create” is misleading

PUT is not limited to updating an existing resource. Its target can have no current representation; a successful PUT can create one at that known URI. Conversely, POST is not limited to creating a new resource. RFC 9110 describes POST uses including submitting form fields to a data-handling process, posting a message, creating a resource whose URI the server selects, and appending data to an existing representation.

The useful question is not “Does this operation create or update?” It is “Does the client define the desired state of a known target, or is it asking the target to perform a resource-specific action on this submission?”

3. Idempotency and safe retries

An operation is idempotent when making the same request more than once has the same intended server effect as making it once. PUT is defined as idempotent. This does not mean the server has no incidental side effects: it may log every request or record revisions. It means the requested state-setting effect is the same.

A lost response creates retry uncertainty, especially for POST operations that are not repeat-safe.
A lost response creates retry uncertainty, especially for POST operations that are not repeat-safe.

This is useful when a client loses the connection before receiving a response. The server might have completed the first PUT even though the client does not know that. Retrying the same PUT is generally appropriate because it asks for the same target state again.

POST is not guaranteed idempotent. If a POST creates a payment, order, message, or other item, repeating it might perform the action again. Do not automatically retry an uncertain POST unless the endpoint documents repeat-safe behavior or the client has another reliable way to determine that the first attempt was not applied. Some APIs provide their own idempotency mechanism; that is an API-specific contract, not a property you can assume from the HTTP method alone.

Neither method guarantees that every request reaches the application or succeeds. Idempotency is about the intended effect of repetitions, not transport delivery, authorization, validation, or endpoint availability. See RFC 9110, section 9.2.2 for the standard’s guidance on idempotent methods and retries.

4. Complete examples: the same resource, two different intents

These examples use illustrative API paths and JSON fields. The server must implement the stated contract; HTTP does not require an arbitrary endpoint to accept both methods. Set API_BASE to your service and provide credentials as required by that service.

PUT: set a known resource’s state

curl -i -X PUT "https://api.example.test/users/42" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  --data '{"name":"Ada Lovelace","active":true}'
import requests

url = "https://api.example.test/users/42"
payload = {"name": "Ada Lovelace", "active": True}
response = requests.put(
    url,
    json=payload,
    headers={"Authorization": "Bearer YOUR_TOKEN"},
    timeout=20,
)
response.raise_for_status()
print(response.status_code)
print(response.text)
const url = 'https://api.example.test/users/42';
const response = await fetch(url, {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  body: JSON.stringify({ name: 'Ada Lovelace', active: true })
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
console.log(response.status, await response.text());

POST: submit content for target-specific processing

curl -i -X POST "https://api.example.test/orders" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  --data '{"sku":"book-123","quantity":1}'
import requests

url = "https://api.example.test/orders"
payload = {"sku": "book-123", "quantity": 1}
response = requests.post(
    url,
    json=payload,
    headers={"Authorization": "Bearer YOUR_TOKEN"},
    timeout=20,
)
response.raise_for_status()
print(response.status_code)
print(response.headers.get("Location"))
print(response.text)
const response = await fetch('https://api.example.test/orders', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  body: JSON.stringify({ sku: 'book-123', quantity: 1 })
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
console.log(response.status, response.headers.get('Location'), await response.text());

The sample paths and payloads are not real service endpoints. In a real integration, follow the API’s documentation for URI structure, accepted representation, authentication, response body, and status codes. Do not infer an API’s behavior solely from the method name.

5. Choosing a method in API design

  1. Identify the target resource. Is there a stable URI for the exact resource whose state the client intends to set? If so, PUT is a natural fit.
  2. Write down the operation’s meaning. If the target processes a submission, appends an item, triggers work, or assigns the URI of a new resource, POST may express that intent.
  3. Define replacement semantics. Say whether the request representation describes the target’s intended state, and specify what omitted fields mean. Do not assume a partial update convention from the word PUT; define the accepted representation and behavior in your API contract.
  4. Document repeat behavior. State whether clients may retry after a timeout. PUT’s method semantics help; for POST, define any endpoint-specific safeguards and how clients can resolve an uncertain result.
  5. Document responses. Describe success and error responses, including whether a PUT created the representation. A successful creation by PUT returns 201 Created under RFC 9110. Do not promise that every successful PUT has that status.
  6. Check method support. A server chooses which methods a resource supports. A standardized definition does not mean every endpoint accepts PUT and POST.

6. Common mistakes and edge cases

Calling PUT “update” and POST “create”

This slogan breaks when PUT creates a missing target or POST appends data, submits a form, or asks for processing. Describe the operation’s semantics instead.

Assuming a successful PUT makes every later GET byte-for-byte identical

PUT says the target state is created or replaced with the state defined by the request representation. A server may have dynamic representations or concurrent changes, so a later GET is not necessarily a byte-for-byte echo. Define the resource representation and concurrency behavior in the API contract.

Retrying POST after a timeout

The client may not know whether the server applied the first attempt. Repeating can duplicate an operation. Consult the endpoint’s retry contract or first determine the original outcome where possible.

Assuming PUT has no observable side effects

Idempotency is about the intended effect. Logs, audit records, or revision history can still show each request.

Sending a method an endpoint does not support

Method definitions do not establish endpoint permissions or accepted payload formats. Read the API documentation and inspect the actual response rather than switching verbs at random.

7. Troubleshooting

Symptom Likely cause What to do
405 Method Not Allowed The target resource does not allow that method. Check the endpoint contract and any Allow response header; use the documented method.
404 Not Found on PUT The URI may be wrong, or this API may not allow creation at a client-selected target. Verify the target URI and API behavior. If the service assigns resource URIs, it may define a collection POST instead.
400 Bad Request or 415 Unsupported Media Type The request representation is malformed or its media type is unsupported. Validate the body, set the documented Content-Type, and send the schema the endpoint accepts.
401 or 403 Credentials are missing, invalid, expired, or lack permission for that target or method. Check the API’s authentication instructions and scope; do not treat a method change as an authorization fix.
Duplicate result after retry A non-idempotent POST may have been applied before the connection failed. Check the operation’s status or documented deduplication mechanism before retrying again.
PUT returns an unexpected status The response reflects whether the operation created or changed a representation, or follows API-specific behavior. Read the endpoint contract; do not require 201 for a replacement.

8. Performance, reliability, and cost

PUT and POST are HTTP semantics, not performance guarantees. The method alone does not tell you how fast an endpoint is, how much it costs, or whether it is reliable. Payload size, server work, network conditions, rate limits, and the service’s implementation determine those outcomes. Keep request bodies purposeful, use the endpoint’s documented timeout and rate-limit guidance, and avoid retries that could duplicate non-idempotent operations.

For reliability, design clients around uncertainty: a missing response does not prove the server did nothing. PUT gives a standardized repeatable intended effect when the same request is sent again. POST requires more care unless that specific operation is documented as repeat-safe. For cost-sensitive operations, check the service’s billing and duplicate-request rules; HTTP itself defines no price model.

9. A practical decision checklist

  • The client knows the URI of the resource whose state it wants to set: consider PUT.
  • The request means “make this target have this state”: PUT expresses that intent.
  • The target should process a submission, append information, or choose a new resource URI: consider POST.
  • A request may be retried after a lost response: establish whether repeating it is safe before implementing retries.
  • The API docs specify a different method or behavior: follow that documented contract.

10. Or skip the browser setup

If the job behind your API integration is collecting a page image for a report, preview, or agent workflow, you can capture it with one request through ScreenshotNeo. Its screenshot endpoint uses GET with a URL; see the API docs.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));
  • Cookie banners are accepted and removed before capture, along with known newsletter popups and chat widgets; each cleanup step can be turned off.
  • Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Responses identify page verdict and billing status in headers.
  • An MCP server gives AI agents tools to take screenshots, inspect page info, and capture PDFs.
  • The free plan includes 1,000 shots monthly with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan.

Create a free ScreenshotNeo account and get 1,000 screenshots a month with no card.

11. FAQ

Can PUT create a resource?

Yes. PUT can create the representation at its target URI. When a successful PUT creates it, the origin server returns 201 Created.

Is POST always unsafe to retry?

It is not guaranteed idempotent by HTTP semantics. A particular endpoint may define safe repeat behavior, so check that endpoint’s contract.

Does PUT mean the request replaces every field?

PUT expresses creation or replacement of target state using the enclosed representation. The API must define the representation and how omitted fields are handled; do not assume an undocumented partial-update rule.

Can an API reject PUT even if the method is standardized?

Yes. The resource determines which methods it supports and what representations it accepts.