Replaces an existing resource with a new version. The entire resource must be provided (not partial updates - use PATCH for that).
Endpoint
PUT /fhir/{resourceType}/{id}
The FHIR resource type (e.g., Patient, Observation, Encounter)
The logical ID of the resource to update
Must be application/fhir+json or application/fhir+xml
Response format: application/fhir+json (default) or application/fhir+xml
Conditional update. Only update if current version matches this ETag. Example:
W/"5" - Prevents lost updates via optimistic locking
Response style: - return=representation (default) - Return full updated
resource - return=minimal - Return headers only - return=OperationOutcome
Query Parameters
For conditional update. Update the resource matching these search parameters.
Example: ?identifier=http://hospital.example/mrn|12345
Request Body
The complete resource including the ID. Missing fields are removed (not preserved).
Patient Update
Observation Update
{
"resourceType" : "Patient" ,
"id" : "123" ,
"name" : [
{
"family" : "Doe" ,
"given" : [ "Jane" , "Marie" ]
}
],
"gender" : "female" ,
"birthDate" : "1990-01-01" ,
"identifier" : [
{
"system" : "http://hospital.example/mrn" ,
"value" : "12345"
}
],
"telecom" : [
{
"system" : "email" ,
"value" : "[email protected] " ,
"use" : "home"
}
],
"active" : true
}
Total Replacement : PUT replaces the entire resource. Any fields not
included in the request body are removed. Use PATCH for partial updates.
Response
200 OK
Resource updated successfully.
New version number (incremented from previous)
ISO 8601 timestamp of this update
Updated Resource
Response 3
{
"resourceType" : "Patient" ,
"id" : "123" ,
"meta" : {
"versionId" : "6" ,
"lastUpdated" : "2026-01-12T14:30:00.000Z"
},
"name" : [
{
"family" : "Doe" ,
"given" : [ "Jane" , "Marie" ]
}
],
"gender" : "female" ,
"birthDate" : "1990-01-01" ,
"identifier" : [
{
"system" : "http://hospital.example/mrn" ,
"value" : "12345"
}
],
"telecom" : [
{
"system" : "email" ,
"value" : "[email protected] " ,
"use" : "home"
}
],
"active" : true
}
201 Created
Resource created (update-as-create). Occurs when the resource doesn’t exist and server allows creation via PUT.
Created Resource
Response 3
{
"resourceType" : "Patient" ,
"id" : "new-patient-123" ,
"meta" : {
"versionId" : "1" ,
"lastUpdated" : "2026-01-12T14:30:00.000Z"
},
"name" : [
{
"family" : "Doe" ,
"given" : [ "John" ]
}
]
}
Update-as-Create : Whether PUT can create resources (when they don’t exist)
depends on server configuration. Check the CapabilityStatement for
updateCreate support.
400 Bad Request
Validation failed or malformed request.
{
"resourceType" : "OperationOutcome" ,
"issue" : [
{
"severity" : "error" ,
"code" : "invalid" ,
"expression" : [ "Patient.id" ],
"diagnostics" : "Resource ID in body (999) does not match URL (123)"
}
]
}
404 Not Found
Resource doesn’t exist and server doesn’t support update-as-create.
{
"resourceType" : "OperationOutcome" ,
"issue" : [
{
"severity" : "error" ,
"code" : "not-found" ,
"diagnostics" : "Resource Patient/123 not found"
}
]
}
409 Conflict
Version conflict or referential integrity violation.
{
"resourceType" : "OperationOutcome" ,
"issue" : [
{
"severity" : "error" ,
"code" : "conflict" ,
"diagnostics" : "Version conflict: current version is 7, provided If-Match is W/ \" 5 \" "
}
]
}
412 Precondition Failed
Conditional update matched multiple resources (ambiguous) or If-Match failed.
{
"resourceType" : "OperationOutcome" ,
"issue" : [
{
"severity" : "error" ,
"code" : "multiple-matches" ,
"diagnostics" : "Multiple resources match the search criteria. Conditional update requires exactly one match."
}
]
}
Examples
cURL - Basic Update
cURL - Safe Update (with If-Match)
cURL - Conditional Update
cURL - Update-as-Create
Python Example
JavaScript Example
curl -X PUT "https://your-server.com/fhir/Patient/123" \
-H "Content-Type: application/fhir+json" \
-H "Accept: application/fhir+json" \
-d '{
"resourceType": "Patient",
"id": "123",
"name": [{"family": "Doe", "given": ["Jane"]}],
"gender": "female",
"birthDate": "1990-01-01"
}'
Best Practices
Always Use If-Match : Include the If-Match header with the current ETag
to prevent lost updates in concurrent scenarios. Without it, last write wins.
Complete Resource Required : You must send the entire resource. Missing fields are removed. Common mistake:Bad - Missing fields will be deleted
{
"resourceType" : "Patient" ,
"id" : "123" ,
"name" : [{ "family" : "NewName" }]
// Oops! gender, birthDate, identifier all deleted
}
For partial updates, use PATCH instead.
ID Consistency : The id in the request body must match the id in the
URL. The resourceType must also match.
See Also
Bearer token authentication
For version-aware updates
The FHIR resource type (e.g., Patient, Observation, Encounter)
The logical ID of the resource
Body application/fhir+json application/fhir+xml application/fhir+json application/fhir+xml
A FHIR resource. All resources have resourceType, id, and meta fields.
Logical id of this artifact
Metadata about a resource
A FHIR resource. All resources have resourceType, id, and meta fields.
Logical id of this artifact
Metadata about a resource