Back to Blogs

Blog

PUT vs POST vs PATCH: Choosing the Right HTTP Method

written by
Dhayalan Subramanian
Associate Director - Product Growth at DigitalAPI

Updated on: 

TL;DR

1. POST creates new resources and is non-idempotent, meaning repeated requests can yield different results.

2. PUT completely replaces an existing resource or creates one if it doesn't exist, always being idempotent.

3. PATCH applies partial modifications to a resource, allowing granular updates without replacing the whole entity.

4. Understanding idempotence and safety is key to choosing the correct HTTP method for predictable API behavior.

5. Precise method selection improves API clarity, enables efficient caching, and ensures robust error handling and client interactions.

Get started with DigitalAPI today. Book a Demo!

Crafting a robust and intuitive API involves more than just exposing data; it demands a precise understanding of how clients and servers communicate. The seemingly simple choice between HTTP methods like POST, PUT, and PATCH can profoundly impact your API's predictability, efficiency, and overall developer experience. These verbs aren't interchangeable synonyms for "send data"—each carries a distinct semantic meaning that, when honored, transforms an ordinary endpoint into a highly functional and self-descriptive interaction. Misusing them, however, can lead to subtle bugs, unexpected behavior, and frustration down the line. This guide will demystify the nuances of PUT vs POST vs PATCH, helping you make informed decisions that elevate your API design.

The Foundational Concepts: Idempotence and Safety

Before diving into POST, PUT, and PATCH, it's essential to grasp two fundamental HTTP principles: **Idempotence** and **Safety**. These concepts are crucial for understanding why each method exists and how they should be used in a RESTful API.

What is Idempotence?

An operation is **idempotent** if executing it multiple times produces the same result as executing it once. This is critical for reliable API interactions, especially in distributed systems where network issues or client retries are common. If an idempotent request is sent, and the client doesn't receive a response (e.g., due to a timeout), it can safely retry the request without worrying about unintended side effects.

  • Idempotent Methods: GET, HEAD, PUT, DELETE, OPTIONS, TRACE.
  • Non-Idempotent Methods: POST.
  • Conditional Idempotence: PATCH (can be idempotent if the patch document specifies the same outcome upon repeated application, but it's not strictly guaranteed by the method itself).

For example:

  • `DELETE /resources/{id}`: If you delete a resource multiple times, it remains deleted. The first request removes it, subsequent requests (if the resource is already gone) will still result in the resource being absent, hence the same ultimate state.
  • `PUT /resources/{id}`: If you replace a resource with a specific data payload multiple times, the resource will always end up in the exact same state as defined by that payload.
  • `POST /resources`: If you send a request to create a resource multiple times, it might create multiple identical resources (e.g., two entries in a database for the same data), thus it is not idempotent.

What is Safety?

An operation is **safe** if it does not alter the state of the server. Safe methods are primarily used for retrieval and should not have any side effects on the server's data or resources. Clients can assume that calling a safe method will not change anything on the backend.

  • Safe Methods: GET, HEAD, OPTIONS.
  • Non-Safe Methods: POST, PUT, PATCH, DELETE.

For example:

  • `GET /resources`: Retrieves data without changing it.
  • `POST /resources`: Creates a resource, changing server state.

Understanding these distinctions is the first step in mastering the core HTTP methods for robust API development.

POST: Creating New Resources and Submitting Data

The POST method is arguably the most versatile of the HTTP verbs, primarily used for creating new resources on the server. However, its applications extend beyond simple creation to encompass submitting data for processing by the server. It's the go-to method when you need to send data that the server will use to initiate an action or generate a new entity with a server-assigned identifier.

Primary Use Cases for POST:

  1. Create a new resource: This is the most common use case. When a client sends a POST request to a collection URI (e.g., `/users`), it's asking the server to create a new resource within that collection. The server typically assigns a unique identifier to the new resource and returns it in the response.
  2. Submitting data for processing: POST can also be used for operations that don't neatly fit into other HTTP verbs but involve processing data. Examples include submitting a form, uploading a file, or triggering an operation that results in a new resource or state change but isn't a direct creation of a named resource.
  3. Appending to a resource: In some less common scenarios, POST can be used to append data to an existing resource if the operation itself results in a new state or sub-resource being created.

Key Characteristics of POST:

  • Non-idempotent: This is a crucial distinction. Sending the same POST request multiple times is likely to create multiple identical resources on the server. For instance, repeatedly `POST`ing to `/orders` might create several identical orders.
  • Server-generated identifiers: Typically, when a new resource is created via POST, the server is responsible for generating its unique identifier (e.g., an auto-incrementing ID or a UUID). The response usually includes the URI of the newly created resource (in the `Location` header) and its representation.
  • Response status: A successful creation typically returns a `201 Created` status code, along with the `Location` header pointing to the new resource. Other successful processing might return `200 OK` or `202 Accepted` (if the processing is asynchronous).

Example:

To create a new user:

POST /users
Content-Type: application/json

{
 "name": "Alice Smith",
 "email": "alice@example.com"
}

Successful response:

HTTP/1.1 201 Created
Location: /users/123
Content-Type: application/json

{
 "id": "123",
 "name": "Alice Smith",
 "email": "alice@example.com"
}

In scenarios where idempotency is required for creation, such as preventing duplicate transactions, an API security measure like an idempotency key can be implemented at the application level, even for POST requests.

PUT: Replacing or Upserting Entire Resources

The PUT method is designed for modifying existing resources by entirely replacing them with a new representation provided in the request body. If the resource identified by the URI does not exist, PUT can also be used to create it (often referred to as an "upsert" operation). The key here is the notion of *complete replacement* and the client's role in specifying the resource's exact location.

Primary Use Cases for PUT:

  1. Full update/replacement of an existing resource: When you want to modify a resource and you have the complete, updated representation of that resource, PUT is the appropriate method. The server replaces the entire state of the resource at the specified URI with the state contained in the request payload. Any fields not included in the payload will typically be reset or removed.
  2. Create a resource with a client-defined identifier (Upsert): If the client has the authority to specify the unique identifier for a new resource, PUT can be used to create it. For example, if `/products/new-sku-001` does not exist, a PUT request to that URI could create it. If it already exists, the PUT request would update it.

Key Characteristics of PUT:

  • Idempotent: This is PUT's most defining characteristic. Sending the same PUT request multiple times will have the exact same effect on the server's state. Each request will replace the resource at the target URI with the same data, ensuring consistency.
  • Client-defined identifiers (often): Unlike POST, where the server typically generates the ID, PUT often implies that the client knows (or specifies) the full URI of the resource it intends to replace or create.
  • Full resource representation: The request body for a PUT operation should contain the *complete* representation of the resource's desired state. Omitting fields might cause them to be nullified or revert to default values, depending on the server's implementation.
  • Response status: A successful update typically returns `200 OK` or `204 No Content`. If a resource was created (upsert), `201 Created` is appropriate.

Example:

To update a user's email, replacing the entire user object:

PUT /users/123
Content-Type: application/json

{
 "id": "123",
 "name": "Alice Smith",
 "email": "alice.updated@example.com"
}

Successful response (updated):

HTTP/1.1 200 OK
Content-Type: application/json

{
 "id": "123",
 "name": "Alice Smith",
 "email": "alice.updated@example.com"
}

If user `123` didn't exist, and the API supported upsert for PUT, it might create it and return `201 Created`.

When designing APIs, consider if your clients will always have the full resource representation for updates. If not, PATCH might be a more suitable choice.

PATCH: Applying Partial Modifications to Resources

The PATCH method is used to apply partial modifications to a resource. Unlike PUT, which demands a complete representation of the resource for replacement, PATCH allows clients to send only the specific changes they want to make. This can be significantly more efficient, especially for large resources or when network bandwidth is a concern.

Primary Use Cases for PATCH:

  1. Updating specific fields: This is the most common use. For example, changing only a user's email address without affecting their name, address, or other profile details. The client sends a document describing the changes, not the entire resource.
  2. Incrementing/decrementing values: A PATCH request could specify an operation to increment a counter or adjust a numerical value on the server.

Key Characteristics of PATCH:

  • Partial resource representation: The request body for a PATCH operation contains instructions on how to modify the resource, often in a specific "patch document" format like JSON Patch (RFC 6902) or JSON Merge Patch (RFC 7386). It specifies which fields to add, remove, replace, or test.
  • Conditional idempotence: While not strictly guaranteed to be idempotent by the RFC, PATCH operations can be implemented idempotently. For example, "set email to X" is idempotent. "Add 'tag A'" might not be if repeated. Careful design is needed to ensure predictable outcomes for retries, potentially by using a specific patch format that defines idempotent operations.
  • Non-atomic operations: By default, PATCH operations are not necessarily atomic, meaning that if one part of a patch fails, other parts might still succeed, leading to an inconsistent state. Robust API design should ensure atomicity where critical (e.g., using transactions on the backend).
  • Response status: A successful partial update typically returns `200 OK` (with the updated resource representation) or `204 No Content` (if no response body is needed).

Example (using JSON Patch):

To change only a user's email address:

PATCH /users/123
Content-Type: application/json-patch+json

[
 { "op": "replace", "path": "/email", "value": "new.email@example.com" }
]

Successful response:

HTTP/1.1 200 OK
Content-Type: application/json

{
 "id": "123",
 "name": "Alice Smith",
 "email": "new.email@example.com"
}

PATCH is particularly useful when clients only have partial data or when the resource being updated is large and sending the full representation with PUT would be inefficient. It offers fine-grained control over modifications, aligning with thoughtful API design principles.

PUT vs. PATCH: A Direct Comparison

The distinction between PUT and PATCH can be a common point of confusion for API developers. Both are used for updating resources, but their fundamental approach to modification is different. Understanding this difference is crucial for choosing the correct method and designing a truly RESTful API.

PUT: The "Replace" Operation

  • Nature: Replaces the entire resource. The client sends a complete new representation of the resource. Any fields not included in the request body are assumed to be removed or reset to default values.
  • Idempotency: Always idempotent. Sending the same PUT request multiple times will result in the resource having the exact same state as specified in the request body.
  • Payload: Requires the full resource representation in the request body.
  • Use Case: Ideal when the client has the complete, updated state of a resource and wants to overwrite the existing one. Also used for "upsert" operations where the client defines the resource ID.
  • Bandwidth Impact: Potentially higher, as the full resource representation is always sent.

PATCH: The "Modify" Operation

  • Nature: Applies partial modifications. The client sends a set of instructions (a "patch document") describing how to change specific parts of the resource.
  • Idempotency: Conditionally idempotent. Its idempotence depends on the nature of the patch instructions. "Set field X to value Y" is idempotent. "Add item to list" might not be. Developers must ensure idempotent implementation.
  • Payload: Contains only the changes to be applied, often in a structured format like JSON Patch or JSON Merge Patch.
  • Use Case: Best when clients only need to update a few fields of a resource, or when the resource is very large and sending the full representation is inefficient.
  • Bandwidth Impact: Potentially lower, as only the changes are transmitted.

Analogy:

  • PUT is like giving someone a completely new document to replace an old one. If you send it again, they'll just have the same new document.
  • PATCH is like giving someone a list of edits (e.g., "change line 3, delete paragraph 5, add new sentence at end"). If you send those same edits again, the outcome should ideally be the same, but you need to be careful if the edits depend on the current state.

The choice between PUT and PATCH boils down to the granularity of the update and whether the client typically operates with a full or partial view of the resource. For REST API best practices, use PUT for full replacements and PATCH for granular updates.

Choosing the Right Method: A Decision Framework

Selecting the appropriate HTTP method for your API endpoints is a critical aspect of thoughtful API design. It ensures your API is intuitive, predictable, and adheres to RESTful principles. Here’s a decision framework to guide your choices, focusing on POST, PUT, and PATCH, while briefly considering GET and DELETE:

1. What is the fundamental intent of the operation?

  • Retrieval (Read-only): If the goal is to fetch data without altering the server's state, use GET. (e.g., `GET /users`, `GET /users/{id}`).
  • Deletion (Remove): If the goal is to remove a specific resource, use DELETE. (e.g., `DELETE /users/{id}`).

2. Is the operation creating a new resource?

  • Yes, and the server generates the ID: Use POST. This is the most common scenario for creating new entities. (e.g., `POST /orders` to create a new order).
  • Yes, and the client specifies the ID (upsert capability): Use PUT. The client provides the full resource URI, and the server creates it if it doesn't exist, or replaces it if it does. (e.g., `PUT /products/{client-defined-sku}`).

3. Is the operation updating an existing resource?

  • Full replacement: If the client has the complete, updated state of the resource and intends to replace the entire existing resource, use PUT. Any fields not in the request body will be removed or reset. (e.g., `PUT /users/{id}` with the full user object).
  • Partial modification: If the client only wants to update specific fields of a resource without affecting others, use PATCH. The request body contains only the changes to be applied. (e.g., `PATCH /users/{id}` to change only the email address).

4. Does idempotence matter for this operation?

  • Yes, it must be idempotent: If repeated requests must always yield the same server state, PUT and DELETE are inherently idempotent. For PATCH, ensure your implementation is idempotent (e.g., using JSON Patch operations like "replace").
  • No, it's fine if repeated requests have different effects: POST is the method for non-idempotent actions, typically for creation. If you need idempotency for a POST-like action, consider adding an application-level idempotency key.

Summary Table:

MethodPrimary PurposeIdempotent?Safe?PayloadTypical Status CodeGETRetrieve a resourceYesYesN/A200 OKPOSTCreate a new resource, submit data for processingNoNoFull resource representation/data to process201 Created, 200 OK, 202 AcceptedPUTReplace a resource, create if not exists (upsert)YesNoFull resource representation200 OK, 204 No Content, 201 CreatedPATCHApply partial modifications to a resourceConditionalNoPartial resource representation (patch document)200 OK, 204 No ContentDELETERemove a resourceYesNoN/A200 OK, 204 No Content

By consistently applying this framework, you build an API that is not only functional but also communicates its intent clearly, simplifying client integration and reducing errors. This clarity also aids in effectively managing your API lifecycle management.

Beyond the Basics: Considerations for Robust APIs

Choosing the right HTTP method is foundational, but building truly robust and maintainable APIs requires attention to several other critical areas. These best practices enhance usability, security, and scalability, making your API a joy to work with.

HTTP Status Codes and Error Handling

HTTP status codes are your API's language for communicating the outcome of a request. Using them correctly is paramount for effective API monitoring tools and client error handling. For instance, a `400 Bad Request` indicates a client-side issue (e.g., invalid input), while a `500 Internal Server Error` points to a problem on the server. Always pair meaningful status codes with clear, machine-readable error messages in the response body, explaining what went wrong and how the client might rectify it (for 4xx errors).

API Versioning

As your API evolves, you'll inevitably introduce changes. A solid API versioning strategy allows you to introduce new features or breaking changes without disrupting existing clients. Common strategies include URI path versioning (e.g., `/v1/users`), query parameter versioning, or custom headers. Document your versioning strategies thoroughly and communicate deprecation plans clearly to your consumers.

API Security

Security should never be an afterthought. Implement robust API security measures, including proper authentication mechanisms (like OAuth 2.0 or API keys), authorization checks (Role-Based Access Control), input validation to prevent common attacks (e.g., SQL injection, XSS), and always use HTTPS/TLS for all communications. Regularly review your API against established security guidelines, such as the OWASP Top 10 API Security Risks.

Rate Limiting and Throttling

To protect your API from abuse, excessive load, and denial-of-service attacks, implement rate limiting and throttling. This controls the number of requests a client can make within a specified timeframe. Clearly communicate these limits to your API consumers via documentation and HTTP headers (e.g., `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `Retry-After`).

API Gateways and Developer Portals

Leveraging API gateways can centralize many of these concerns, handling authentication, authorization, rate limiting, and traffic management before requests reach your backend services. Coupled with a well-designed developer portal, these tools provide a comprehensive platform for managing, securing, and exposing your APIs, significantly enhancing the developer experience and ensuring broader adoption.

By integrating these considerations into your API design philosophy, you build not just endpoints, but a reliable, secure, and scalable ecosystem.

Common Misconceptions and Anti-Patterns

Even with a solid understanding of HTTP methods, developers can fall into common traps that undermine the elegance and effectiveness of their RESTful APIs. Recognizing these anti-patterns is as important as knowing the best practices.

1. Using POST for Everything

This is perhaps the most prevalent anti-pattern, often stemming from familiarity with traditional RPC (Remote Procedure Call) architectures. Treating POST as a generic "do something" verb for creation, updates, and even data retrieval bypasses the semantic richness of HTTP. Consequences include:

  • Loss of idempotence: Client retries can lead to unintended duplicate operations.
  • Inability to cache: POST responses are not cacheable by default, losing a significant performance optimization.
  • Confusing API design: Clients must infer the operation's intent from the URI or payload, rather than the clear HTTP verb.

2. Using GET to Change State

GET requests are explicitly defined as "safe" operations, meaning they should never alter the state of the server. Using GET to trigger updates, deletions, or any other state-changing action is a severe breach of HTTP principles and can lead to unexpected behavior, security vulnerabilities (e.g., cross-site request forgery attacks), and issues with caching mechanisms.

3. Confusing PUT and PATCH

As discussed, PUT is for *replacement*, and PATCH is for *partial modification*. Misusing PUT for partial updates means clients must send the entire resource, even if only a single field changes, leading to unnecessary bandwidth consumption and potential data integrity issues if clients don't send all fields correctly. Conversely, using PATCH for a full replacement complicates the server-side logic by requiring a patch document for an operation that could be a simple overwrite.

4. Ignoring HTTP Status Codes

Returning a generic `200 OK` for every successful operation, even when a `201 Created` or `204 No Content` would be more appropriate, or a `500 Internal Server Error` for all client-side issues, diminishes the API's clarity. Clients rely on these codes for proper error handling and flow control. Inconsistent or vague status codes make debugging a nightmare.

5. Lack of Consistent Naming and Structure

While not directly related to HTTP methods, inconsistent URI naming conventions (e.g., mixing plural and singular nouns, using verbs) or varying request/response payload structures across endpoints can make an API difficult to learn and use. Consistency in resource naming, data formats, and error structures is a hallmark of good API management platforms and developer experience.

By being vigilant against these common mistakes, developers can ensure their APIs are not only functional but also elegant, maintainable, and truly RESTful.

Conclusion

The decision of when to use PUT vs POST vs PATCH is far more than a stylistic preference—it's a foundational element of sound API design. Each HTTP method carries a distinct semantic intent, rooted in the core principles of idempotence and safety, that directly impacts how clients interact with your resources. POST serves as the primary verb for creating new, server-identified resources and submitting data for processing, carrying the implication of non-idempotent actions. PUT, in contrast, champions the concept of full resource replacement or client-defined upserts, guaranteeing idempotence and a predictable final state. PATCH steps in for granular, partial updates, offering efficiency for targeted modifications, albeit with careful consideration for its conditional idempotency.

By deliberately choosing the method that precisely matches the intended operation, you empower your API to be more intuitive, predictable, and robust. This precision translates into easier client integration, more effective caching, simplified error handling, and enhanced overall reliability. Mastering these distinctions elevates your API from a collection of endpoints to a well-structured, self-descriptive interface that adheres to the established conventions of the web, ultimately fostering greater developer satisfaction and wider adoption. Embrace the semantic power of HTTP methods, and your APIs will communicate with unmatched clarity and consistency.

FAQs

1. What is the main difference between PUT and POST?

The main difference lies in their purpose and idempotence. POST is typically used to *create* new resources when the server generates the resource's ID, and it is *not idempotent* (repeated requests can create multiple resources). PUT is used to *replace* an existing resource entirely or *create* a resource if the client specifies its ID (upsert), and it is *idempotent* (repeated requests result in the same state).

2. When should I use PATCH instead of PUT?

Use PATCH when you want to apply *partial modifications* to a resource. This is efficient when only a few fields need updating, or the resource is large, as you send only the changes. Use PUT when you want to *replace the entire resource* with a new representation, sending the complete updated object.

3. Is PATCH an idempotent method?

PATCH is *conditionally idempotent*. The HTTP specification does not guarantee idempotence for PATCH operations, as it depends on how the patch document is constructed and applied. For example, "set email to X" is idempotent, but "add item Y to a list" might not be if repeated. Careful API design is needed to ensure that repeated PATCH requests achieve the same final state.

4. Why is idempotence important in API design?

Idempotence is crucial for building reliable and fault-tolerant APIs. It allows clients to safely retry requests (e.g., after a network timeout) without worrying about unintended side effects like creating duplicate resources or performing the same action multiple times. This simplifies client logic and improves the overall robustness of distributed systems.

5. Can I use POST for updates?

While technically possible to use POST for updates, it is an anti-pattern in RESTful API design. POST is non-idempotent, making retries unsafe for updates, and it obscures the true intent of the operation. For full updates, use PUT; for partial updates, use PATCH. Adhering to these conventions improves API clarity, cacheability, and predictability.

Liked the post? Share on:

Don’t let your APIs rack up operational costs. Optimise your estate with DigitalAPI.

Book a Demo

You’ve spent years battling your API problem. Give us 60 minutes to show you the solution.

Get API lifecycle management, API monetisation, and API marketplace infrastructure on one powerful AI-driven platform.