Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

PUT replaces the representation of a known resource with the representation in your request. PATCH applies a documented set of changes to the resource that exists now. Use PUT when you can construct the complete desired state at a known URI; use PATCH when you need to change selected fields or send transformation instructions. PUT is idempotent by HTTP semantics, while PATCH is not inherently idempotent.

PUT and PATCH at a glance

Axis PUT PATCH
Payload meaning A complete replacement representation Change instructions or a partial representation defined by the patch format
Typical scope Replace the resource at a known URI; it may create the representation when none exists Modify selected parts of an existing resource; creation depends on the patch format and server contract
Idempotency Idempotent by HTTP method definition Not inherently idempotent, although a particular PATCH can be designed to be idempotent
Retry posture Identical retries generally have the same intended effect Retry only when repeating the operation is safe and concurrency is controlled
Concurrency Use validators such as ETags and conditional requests to avoid replacing newer state Use a strong ETag with If-Match when the patch was based on a previous read
Atomicity The requested replacement is the target state The server must apply the complete patch atomically: all changes or none

These are HTTP method semantics. Your API’s schema still decides which fields are required, what an omitted field means, how arrays are handled, and which media types are accepted.

What PUT means

RFC 9110 (June 2022) defines PUT as a request to create or replace the state of the target resource with the representation enclosed in the request. The client normally knows the target URI, such as /users/42 or /orders/9001.

Complete representation, not an automatic merge

A PUT body should describe the final representation the client wants stored. For example, if a user resource has name, email and timezone, a replacement request should account for all three according to the API contract. Omitting a property might clear it, trigger a validation error, or be treated specially by an application; HTTP itself does not define a universal merge rule.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Creation and client-chosen URIs

PUT can create a representation when no current representation exists, provided the server allows that operation. It is suited to client-known, repeatable identifiers. If the server should choose a new URI after receiving the representation, RFC 9110 generally points to POST instead.

PUT is idempotent, not safe

Repeating the same PUT is intended to have the same effect as sending it once. A server may still record each request in logs, update audit timestamps or trigger other side effects. Idempotent does not mean read-only: MDN classifies PUT as unsafe because it changes server state.

What PATCH means

RFC 5789 (March 2010) defines PATCH for partial resource modification. The request entity contains instructions for transforming the resource currently held by the origin server. MDN summarizes the practical distinction as partial modification with PATCH versus complete replacement with PUT.

The patch document controls the meaning

PATCH does not prescribe one body shape. The media type and API documentation must define the format. A service might accept a merge-style JSON object such as {"email":"new@example.com"}, or require a JSON Patch operation list such as [{"op":"replace","path":"/email","value":"new@example.com"}]. Those formats differ in how they represent deletion, null, arrays and nested values.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

PATCH is not automatically idempotent

RFC 5789 says PATCH is neither safe nor inherently idempotent. A patch that sets status to closed can be repeatable; a patch that appends an item, increments a counter or generates a new value may produce a different result each time. Treat retries as an application decision, not a property you can infer from the method name.

Atomic application

The server must apply a PATCH document atomically. If any part of the complete change set cannot be applied, none of its changes should be applied. This does not mean multiple unrelated HTTP requests are one transaction; it applies to the single patch document being processed.

Choosing the method

  1. Choose PUT when the client can build the complete desired representation, the resource URI is known, and replacement semantics are intended.
  2. Choose PATCH when only part of a resource changes or the operation is naturally expressed as instructions.
  3. Specify the patch format with Content-Type and documentation. Define omitted fields, explicit nulls, array operations, validation and conflict behavior.
  4. Define a concurrency policy. Use ETag/If-Match or an equivalent mechanism when stale clients must not overwrite newer edits.
  5. Test repeatability and rollback. Verify what happens when an identical request is retried, validation fails halfway through a patch, or the resource changed between read and write.

Examples

  • Replacing a complete profile document fetched from the server: PUT.
  • Changing only a customer’s notification preference: PATCH.
  • Uploading a representation to a client-assigned object key: usually PUT.
  • Applying several conditional field edits based on a previously read version: PATCH with a strong ETag.

Concrete request examples

PUT with cURL

curl -i -X PUT "https://api.example.com/users/42" 
  -H "Authorization: Bearer TOKEN" 
  -H "Content-Type: application/json" 
  --data '{"id":42,"name":"Amina Patel","email":"amina@example.com","timezone":"UTC"}'

The body represents the intended final user state. Whether an omitted server-managed property is preserved or rejected is determined by that API.

PATCH with a merge-style document

curl -i -X PATCH "https://api.example.com/users/42" 
  -H "Authorization: Bearer TOKEN" 
  -H "Content-Type: application/merge-patch+json" 
  --data '{"timezone":"Europe/London"}'

This is valid only if the service documents JSON Merge Patch (or an equivalent format). Do not assume every JSON API interprets a partial object this way.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

PATCH with JSON Patch operations

curl -i -X PATCH "https://api.example.com/users/42" 
  -H "Authorization: Bearer TOKEN" 
  -H "Content-Type: application/json-patch+json" 
  --data '[{"op":"replace","path":"/timezone","value":"Europe/London"}]'

Operation names, paths and array behavior come from the JSON Patch contract implemented by the server.

Conditional replacement with an ETag

curl -i -X PUT "https://api.example.com/users/42" 
  -H "Authorization: Bearer TOKEN" 
  -H "If-Match: "u42-v7"" 
  -H "Content-Type: application/json" 
  --data '{"id":42,"name":"Amina Patel","email":"amina@example.com","timezone":"UTC"}'

If the current representation no longer matches that strong validator, a correctly implemented server rejects the request instead of silently overwriting the newer version.

Python with requests

import requests

url = "https://api.example.com/users/42"
headers = {
    "Authorization": "Bearer TOKEN",
    "Content-Type": "application/json",
    "If-Match": '"u42-v7"',
}
replacement = {
    "id": 42,
    "name": "Amina Patel",
    "email": "amina@example.com",
    "timezone": "UTC",
}
put_response = requests.put(url, json=replacement, headers=headers, timeout=30)
put_response.raise_for_status()

patch_headers = {**headers, "Content-Type": "application/merge-patch+json"}
patch_response = requests.patch(
    url, json={"timezone": "Europe/London"},
    headers=patch_headers, timeout=30
)
patch_response.raise_for_status()
print(patch_response.status_code, patch_response.text)

Node.js with fetch

const url = 'https://api.example.com/users/42';
const common = {
  'Authorization': 'Bearer TOKEN',
  'If-Match': '"u42-v7"'
};

const put = await fetch(url, {
  method: 'PUT',
  headers: { ...common, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    id: 42, name: 'Amina Patel',
    email: 'amina@example.com', timezone: 'UTC'
  })
});
if (!put.ok) throw new Error(`PUT failed: ${put.status}`);

const patch = await fetch(url, {
  method: 'PATCH',
  headers: { ...common, 'Content-Type': 'application/merge-patch+json' },
  body: JSON.stringify({ timezone: 'Europe/London' })
});
if (!patch.ok) throw new Error(`PATCH failed: ${patch.status}`);
console.log(await patch.text());

Concurrency: preventing lost updates

The risky sequence is read, edit, write. Client A and client B can both read version 7; A writes version 8; B then sends a full PUT or a patch based on stale data. Without a precondition, B may overwrite A or apply an operation to the wrong base.

Use ETags with If-Match

After a GET, retain the response’s ETag and send it in If-Match. The server should perform the update only when the validator still matches. A mismatch commonly produces 412 Precondition Failed. The client can fetch the latest representation, reconcile the user’s changes, and retry with the new validator.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why PATCH needs special care

RFC 5789 specifically recommends a conditional request with a strong ETag when a patch depends on a known base representation. A patch that says “replace the value at this path” may be wrong after another client has changed that path; the precondition turns that silent conflict into an explicit one.

PUT also needs validators

Idempotency does not protect against stale data. A complete replacement can still erase a newer edit, so apply the same validator discipline to PUT whenever overwriting newer state would be harmful. A successful response may return a new validator for the next request.

Partial PUT and Content-Range

RFC 9110 notes that some servers support partial PUT using Content-Range, but this is inconsistent and depends on private agreements. It is not backward-compatible with the original PUT definition: a server that does not support that convention may process the request as a complete replacement. For interoperable partial updates, use PATCH with a documented patch format rather than assuming Content-Range creates merge semantics.

Common errors and fixes

Symptom Likely cause Fix
405 Method Not Allowed The route does not expose PUT or PATCH, or a proxy blocks it. Inspect the endpoint’s Allow header and routing/proxy policy; use the method the API documents.
415 Unsupported Media Type The patch format or Content-Type is not accepted. Send the documented media type, such as application/merge-patch+json or application/json-patch+json.
400 or 422 validation error A PUT representation is incomplete, or a patch operation/path/value violates the schema. Read the error details, send all required replacement fields, and validate patch paths and values before retrying.
409 Conflict or 412 Precondition Failed The resource changed or an ETag precondition failed. GET the current representation, reconcile changes, then retry with its latest strong ETag if the user approves.
Fields unexpectedly disappear after PUT The server treats omission as replacement rather than merge. Send the complete representation, or switch to the server’s documented PATCH format.
A PATCH retry duplicates an action The patch is non-idempotent, such as append or increment. Use an idempotency key if the API supports one, add an ETag precondition, or redesign the operation so repetition is safe.
Some PATCH operations appear applied after another fails The implementation is not honoring atomic patch processing. Report the contract violation or use an endpoint that guarantees atomic application; do not assume partial success is portable.

Performance, reliability and cost considerations

PUT often sends more bytes because it carries a complete representation. That can simplify server logic and make retries predictable, but it may overwrite fields the client did not intend to touch if the client’s copy is stale. PATCH can reduce payload size and narrow the change, but it adds a patch format, path validation and more complicated retry decisions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Neither method guarantees a database transaction across multiple resources, and neither guarantees that downstream side effects will run only once. Define timeouts, retry limits, idempotency keys where appropriate, audit behavior and response status codes in the API contract. Measure payload size and latency in your own environment rather than assuming one method is always faster.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If you are documenting or reviewing an API and need clean visual captures of its web pages, ScreenshotNeo provides a website screenshot API and MCP server. A single request can return PNG, JPEG, WebP or PDF. Before capture it accepts consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result.

Example using cURL (see the ScreenshotNeo documentation for all options):

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo also has an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

FAQ

Can I use PATCH to create a resource?

Only if the patch format and server explicitly define creation behavior. Do not infer it from the method; confirm the endpoint contract.

Should a PUT response return the whole resource?

HTTP does not require one response shape. Follow the API’s documented status code and representation, and use any returned ETag for subsequent conditional requests.

Is a PATCH body always smaller than a PUT body?

No. A patch containing many operations, tests and nested values can be as large as—or larger than—a replacement representation.

Does idempotent mean a request can be retried without authentication or authorization checks?

No. Every retry still needs normal authentication, authorization, validation and rate-limit handling.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I use PATCH to create a resource?

Only if the patch format and server explicitly define creation behavior. Confirm the endpoint contract.

Should a PUT response return the whole resource?

HTTP does not require one response shape; follow the API documentation and retain any returned ETag.

Is a PATCH body always smaller than a PUT body?

No. A complex patch can be as large as or larger than a complete representation.

Does idempotent mean a retry skips authentication checks?

No. Retries still undergo authentication, authorization, validation and rate-limit handling.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Bottom Line

Use PUT for complete replacement at a known URI and PATCH for documented partial changes. Protect either method with ETags and If-Match when stale clients could overwrite newer data; never assume a partial JSON body or a retry is safe without reading the API contract.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.