REST API
PUT /v1/patients/{patient_id}
Update a patient
/v1/patients/{patient_id} Seals a complete new version of record, reusing the patient's DEK.
Path parameters #
-
patient_idstring requiredThe patient's document id.
Request body #
-
recordobject requiredThe `data` stream of a patient (`PatientData` in the web app) — everything here is sealed before upload. `birth_date` accepts a `date` or an aware `datetime` and is stored the way the web app stores it, as a UTC ISO 8601 instant. Set `Settings.time_precision` to truncate it to the workspace's anonymization precision before sealing, like the web app does.
-
tagsobject`null` keeps the tags.
-
specialist_idsobject -
expected_latest_version_idobjectThe `latest_version_id` you read; the write is refused with 409 if another version was saved since.
Responses #
-
200 Successful Response
-
indexobject requiredWhat the vault knows about a patient/exam/template (`docs/PROTOCOL.md §8`): keys, streams, clear metadata. Every field here is something the vault itself reads to route and authorize. The clinical content never appears on this model: it lives in the sealed object of each version, and a short sealed summary (name, title) lives in `encrypted_index`, which only a DEK holder opens. Exactly one `security_group_id` per document: sharing a patient with another team means copying it, never sharing its key.
-
version_idobject -
draft_revobject -
recordobject requiredThe `data` stream of a patient (`PatientData` in the web app) — everything here is sealed before upload. `birth_date` accepts a `date` or an aware `datetime` and is stored the way the web app stores it, as a UTC ISO 8601 instant. Set `Settings.time_precision` to truncate it to the workspace's anonymization precision before sealing, like the web app does.
-
summaryobject
-
-
400 The vault refused the request as invalid.
-
errorobject requiredThe body of every non-2xx response: what went wrong, for a program and for a person.
-
-
401 No client certificate, or the SDK session was rejected or expired (`session_expired`).
-
errorobject requiredThe body of every non-2xx response: what went wrong, for a program and for a person.
-
-
402 The workspace has no credit for this.
-
errorobject requiredThe body of every non-2xx response: what went wrong, for a program and for a person.
-
-
403 CN not allowed, permission denied, or no key for the data's security group (`group_key_unavailable`).
-
errorobject requiredThe body of every non-2xx response: what went wrong, for a program and for a person.
-
-
404 Not found — also a node read under a group it does not belong to.
-
errorobject requiredThe body of every non-2xx response: what went wrong, for a program and for a person.
-
-
409 A pending or newer version, a replay, or an upload that never reached storage.
-
errorobject requiredThe body of every non-2xx response: what went wrong, for a program and for a person.
-
-
422 The body or query failed validation (`invalid_request`).
-
errorobject requiredThe body of every non-2xx response: what went wrong, for a program and for a person.
-
-
429 Rate limited, after the SDK's own backoff gave up.
-
errorobject requiredThe body of every non-2xx response: what went wrong, for a program and for a person.
-
-
500 An envelope did not open (`crypto_error`, no detail on purpose).
-
errorobject requiredThe body of every non-2xx response: what went wrong, for a program and for a person.
-
-
502 The vault failed, or answered outside the protocol (`protocol_error`).
-
errorobject requiredThe body of every non-2xx response: what went wrong, for a program and for a person.
-
curl --cert client.crt --key client.key \
-X PUT "https://api.imgexam.com/v1/patients/<patient_id>" \
-H "Content-Type: application/json" \
-d @body.jsonimport httpx
response = httpx.put(
"https://api.imgexam.com/v1/patients/<patient_id>",
cert=("client.crt", "client.key"),
json=body,
)
response.raise_for_status()
print(response.json()){
"record": {
"legal_name": "string",
"display_name": "string",
"identifiers": {},
"external_id": {},
"birth_date": {},
"biological_sex": {},
"gender_identity": {},
"race_identity": {},
"email": {},
"phone": {},
"address": {},
"internal_notes": {},
"custom_attributes": {}
},
"tags": {},
"specialist_ids": {},
"expected_latest_version_id": {}
}{
"index": {
"document_id": "string",
"workspace_id": "string",
"resource": "patients",
"security_group_id": "string",
"encrypted_keys": {},
"encrypted_index": {},
"streams": {},
"meta": {},
"created_at": "string",
"created_by": "string",
"updated_at": "string",
"updated_by": {},
"is_archived": false,
"is_deleted": false
},
"version_id": {},
"draft_rev": {},
"record": {
"legal_name": "string",
"display_name": "string",
"identifiers": {},
"external_id": {},
"birth_date": {},
"biological_sex": {},
"gender_identity": {},
"race_identity": {},
"email": {},
"phone": {},
"address": {},
"internal_notes": {},
"custom_attributes": {}
},
"summary": {}
}{
"error": {
"code": "string",
"message": "string",
"trace_id": {}
}
}{
"error": {
"code": "string",
"message": "string",
"trace_id": {}
}
}{
"error": {
"code": "string",
"message": "string",
"trace_id": {}
}
}{
"error": {
"code": "string",
"message": "string",
"trace_id": {}
}
}{
"error": {
"code": "string",
"message": "string",
"trace_id": {}
}
}{
"error": {
"code": "string",
"message": "string",
"trace_id": {}
}
}{
"error": {
"code": "string",
"message": "string",
"trace_id": {}
}
}{
"error": {
"code": "string",
"message": "string",
"trace_id": {}
}
}{
"error": {
"code": "string",
"message": "string",
"trace_id": {}
}
}{
"error": {
"code": "string",
"message": "string",
"trace_id": {}
}
}