Definition
PUT is an HTTP method that replaces an entire resource at a specific URI with the data provided in the request body. Unlike PATCH (which performs partial updates), PUT requires the client to send the complete representation of the resource. PUT is idempotent - sending the same PUT request multiple times will produce the same result as sending it once.
The key characteristic of PUT is full replacement: if the resource exists, it’s completely replaced; if it doesn’t exist, some servers may create it (though this behavior is implementation-dependent). PUT requests must include the complete resource representation, not just the fields being changed.
PUT is fundamental to RESTful API design, following the principle that the client knows the exact URI of the resource being modified. This contrasts with POST, where the server typically determines the URI of newly created resources.
Example
User Profile - Full Update:
PUT /api/users/123 HTTP/1.1
Content-Type: application/json
{
"id": 123,
"name": "Alice Johnson",
"email": "[email protected]",
"role": "admin",
"department": "Engineering",
"active": true
}
Product Catalog - Replace Product:
PUT /api/products/SKU-456 HTTP/1.1
Content-Type: application/json
{
"sku": "SKU-456",
"name": "Premium Headphones",
"price": 199.99,
"currency": "USD",
"stock": 50,
"category": "electronics"
}
Configuration File - Update Settings:
PUT /api/settings/notifications HTTP/1.1
Content-Type: application/json
{
"email": true,
"sms": false,
"push": true,
"frequency": "daily"
}
Analogy
House Renovation: PUT is like completely gutting and rebuilding a room - you remove everything and replace it with entirely new contents. You don’t just paint a wall (that would be PATCH), you strip it down to the studs and rebuild.
Document Editing: Think of replacing a document in a file cabinet. With PUT, you remove the entire old document and insert a completely new one. You don’t just cross out a line and write a correction (that’s PATCH) - you replace the whole document.
Car Replacement: PUT is like replacing your entire car. You don’t just upgrade the stereo system (PATCH), you trade in the whole vehicle for a completely new one with all new specifications.
Code Example
// PUT - Full replacement of user resource
PUT /api/users/789 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{
"id": 789,
"firstName": "Bob",
"lastName": "Smith",
"email": "[email protected]",
"role": "developer",
"department": "Engineering",
"manager": 456,
"hireDate": "2024-01-15",
"active": true
}
// Response - 200 OK (resource updated)
HTTP/1.1 200 OK
Content-Type: application/json
Last-Modified: Thu, 09 Jan 2026 10:30:00 GMT
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
{
"id": 789,
"firstName": "Bob",
"lastName": "Smith",
"email": "[email protected]",
"role": "developer",
"department": "Engineering",
"manager": 456,
"hireDate": "2024-01-15",
"active": true,
"updatedAt": "2026-01-09T10:30:00Z"
}
// PUT - Idempotent behavior (same request again)
PUT /api/users/789 HTTP/1.1
(same payload as above)
// Response - Same result (idempotent)
HTTP/1.1 200 OK
(same response - resource unchanged)
// PUT - Create if not exists (some servers)
PUT /api/users/999 HTTP/1.1
Content-Type: application/json
{
"id": 999,
"firstName": "Charlie",
"email": "[email protected]"
}
// Response - 201 Created (new resource)
HTTP/1.1 201 Created
Location: /api/users/999
Diagram
sequenceDiagram
participant Client
participant Server
participant Database
Client->>Server: PUT /api/users/123
Note over Client,Server: Complete resource representation
Server->>Database: Check if resource exists
Database-->>Server: Resource found
Server->>Database: Replace entire resource
Database-->>Server: Updated successfully
Server-->>Client: 200 OK
Note over Server,Client: Return updated resource
Client->>Server: PUT /api/users/123 (same payload)
Note over Client,Server: Idempotent - same request again
Server->>Database: Replace entire resource
Database-->>Server: Same result
Server-->>Client: 200 OK
Note over Server,Client: Identical response (idempotent)
Best Practices
- Send complete resource: PUT requires the full representation, including all fields
- Use for known URIs: Client must know the exact resource URI
- Implement idempotency: Same PUT request should always produce same result
- Return appropriate status: 200 OK (updated) or 201 Created (new resource)
- Support ETags: Use If-Match header to prevent lost updates
- Document side effects: If PUT triggers cascading updates, document them
- Validate complete payload: Ensure all required fields are present
- Consider PATCH alternative: If partial updates are common, offer PATCH
- Use PUT for replacements: Not for partial modifications
- Handle concurrency: Implement optimistic locking with ETags
Common Mistakes
Using PUT for partial updates instead of sending the complete resource. Not implementing idempotency correctly, causing duplicate operations on retry. Returning 201 Created when the resource already existed (should return 200 OK). Accepting partial payloads without validation, creating incomplete resources. Not supporting ETags or If-Match headers, leading to lost update problems. Using PUT when POST would be more appropriate for creating resources with server-generated URIs. Forgetting that PUT should replace the entire resource, not merge fields. Not handling concurrent updates properly. Confusing PUT with PATCH semantics.