Delete Resource
curl --request DELETE \
--url http://localhost:8080/fhir/{resourceType}/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "http://localhost:8080/fhir/{resourceType}/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {Authorization: 'Bearer <token>'}};
fetch('http://localhost:8080/fhir/{resourceType}/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));HTTP/1.1 204 No Content
ETag: W/"6"
CRUD Operations
Delete Resource
Remove a FHIR resource
DELETE
/
{resourceType}
/
{id}
Delete Resource
curl --request DELETE \
--url http://localhost:8080/fhir/{resourceType}/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "http://localhost:8080/fhir/{resourceType}/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {Authorization: 'Bearer <token>'}};
fetch('http://localhost:8080/fhir/{resourceType}/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));HTTP/1.1 204 No Content
ETag: W/"6"
Marks a resource as deleted. Most servers use soft delete, preserving the resource in history.
Behavior:
Endpoint
DELETE /fhir/{resourceType}/{id}
string
required
The FHIR resource type (e.g.,
Patient, Observation, Encounter)string
required
The logical ID of the resource to delete
Headers
string
Response style:
return=representation- Return OperationOutcomereturn=minimal(default) - No response bodyreturn=OperationOutcome- Return OperationOutcome
Query Parameters
string
For conditional delete. Delete the resource matching these search parameters.Example:
?identifier=http://hospital.example/mrn|12345Response
204 No Content
Resource deleted successfully. No response body.Headers:HTTP/1.1 204 No Content
ETag: W/"6"
200 OK
Resource deleted successfully with OperationOutcome (when usingPrefer: return=OperationOutcome).
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "information",
"code": "informational",
"diagnostics": "Resource Patient/123 deleted successfully"
}
]
}
Headers:
HTTP/1.1 200 OK
Content-Type: application/fhir+json
ETag: W/"6"
404 Not Found
Resource doesn’t exist (some servers return 204 for idempotency).{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "not-found",
"diagnostics": "Resource Patient/123 not found"
}
]
}
409 Conflict
Resource cannot be deleted due to referential integrity or business rules.{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "conflict",
"diagnostics": "Cannot delete Patient/123: referenced by Observation/456, Encounter/789"
}
]
}
412 Precondition Failed
Conditional delete matched multiple resources (ambiguous).{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "multiple-matches",
"diagnostics": "Multiple resources match search criteria. Conditional delete requires exactly one match."
}
]
}
Examples
curl -X DELETE "https://your-server.com/fhir/Patient/123"
curl -X DELETE "https://your-server.com/fhir/Patient/123" \
-H "Prefer: return=OperationOutcome"
curl -X DELETE "https://your-server.com/fhir/Patient?identifier=http://hospital.example/mrn|12345"
# Delete the resource
curl -X DELETE "https://your-server.com/fhir/Patient/123"
# Try to read it (should return 410 Gone)
curl -i "https://your-server.com/fhir/Patient/123"
import requests
url = "https://your-server.com/fhir/Patient/123"
response = requests.delete(url)
if response.status_code == 204:
print("Patient deleted successfully")
elif response.status_code == 404:
print("Patient not found")
elif response.status_code == 409:
outcome = response.json()
print(f"Cannot delete: {outcome['issue'][0]['diagnostics']}")
import requests
patient_id = "123"
url = f"https://your-server.com/fhir/Patient/{patient_id}"
# First check if resource exists
response = requests.get(url)
if response.status_code == 200:
patient = response.json()
print(f"Deleting patient: {patient['name'][0]['family']}")
# Delete the resource
response = requests.delete(url)
if response.status_code == 204:
print("Deleted successfully")
else:
print("Patient not found")
const url = 'https://your-server.com/fhir/Patient/123';
const response = await fetch(url, {
method: 'DELETE'
});
if (response.status === 204) {
console.log('Patient deleted successfully');
} else if (response.status === 404) {
console.log('Patient not found');
} else if (response.status === 409) {
const outcome = await response.json();
console.log(`Cannot delete: ${outcome.issue[0].diagnostics}`);
}
const response = await fetch(
'https://your-server.com/fhir/Patient?identifier=http://hospital.example/mrn|12345',
{
method: 'DELETE'
}
);
if (response.status === 204) {
console.log('Patient deleted');
} else if (response.status === 412) {
console.log('Multiple matches found - cannot delete');
}
Delete Behavior
Soft Delete (Typical)
Most FHIR servers use soft delete:- Resource marked as deleted in database
- History preserved and accessible
GET /Patient/123returns410 GoneGET /Patient/123/_history/5still works (returns version 5)
Hard Delete (Rare)
Complete removal from database:- Resource and all history permanently deleted
- Cannot be recovered
- Usually restricted by policy or disabled entirely
Check Server Behavior: Review the server’s CapabilityStatement or documentation to understand its delete behavior.
Idempotent Delete
DELETE is idempotent - deleting an already-deleted resource succeeds:# First delete
DELETE /fhir/Patient/123 # 204 No Content
# Second delete (same resource)
DELETE /fhir/Patient/123 # 204 No Content (idempotent)
# Reading the deleted resource
GET /fhir/Patient/123 # 410 Gone
Conditional Delete
Delete by search criteria instead of ID:DELETE /fhir/{resourceType}?{search_parameters}
- 0 matches: No-op, returns
204 No Content - 1 match: Deletes that resource →
204 No Content - 2+ matches: Rejects as ambiguous →
412 Precondition Failed
DELETE /fhir/Patient?identifier=http://hospital.example/mrn|12345
Accessing Deleted Resources
After soft delete, use history endpoints to access deleted resources:# List all versions (including deleted)
GET /fhir/Patient/123/_history
# Read specific version (even if resource is deleted)
GET /fhir/Patient/123/_history/5
Referential Integrity
Some servers check if other resources reference the resource being deleted: Protected Resources (common scenarios):- Patient referenced by Observations, Encounters
- Practitioner referenced by many resources
- Organization referenced by locations, departments
- Allow deletion regardless (most permissive)
- Return
409 Conflictif references exist (most cautious) - Cascade delete (rare - delete referencing resources too)
Common Use Cases
Delete Test Data
DELETE /fhir/Patient/test-patient-123
Soft Delete with Verification
import requests
# Delete
requests.delete('https://server.com/fhir/Patient/123')
# Verify it's gone (should get 410)
response = requests.get('https://server.com/fhir/Patient/123')
assert response.status_code == 410, "Resource should be deleted"
Conditional Delete by Identifier
DELETE /fhir/Patient?identifier=http://hospital.example/temp|temp-12345
Delete with Audit Trail
import requests
patient_id = "123"
url = f"https://server.com/fhir/Patient/{patient_id}"
# Get current state before deleting (for audit)
patient = requests.get(url).json()
audit_log = {
"action": "delete",
"resource": patient,
"timestamp": "2026-01-12T15:00:00Z"
}
# Perform delete
response = requests.delete(url)
if response.status_code == 204:
print("Deleted and logged")
Best Practices
Cannot Undo: Even with soft delete, most UIs don’t provide “undelete” functionality. Ensure deletion is intended before proceeding.
Check References First: Before deleting, search for resources that reference it to avoid breaking referential integrity:If any exist, consider whether deletion is appropriate.
GET /fhir/Observation?subject=Patient/123
GET /fhir/Encounter?subject=Patient/123
Empty Body: DELETE requests should have an empty body per FHIR specification. Don’t send a resource in the body.
See Also
Resource History
View deleted resource versions
Search
Find resources before deleting
Update Resource
Modify instead of deleting
Learn FHIR CRUD
Understand FHIR delete semantics
Authorizations
Bearer token authentication
Path Parameters
The FHIR resource type (e.g., Patient, Observation, Encounter)
The logical ID of the resource