REST API
POST /v1/exams
Create an exam
/v1/exams Seals record, links it to patient_id in clear meta, and creates the exam.
Request body #
-
recordobject requiredThe content of an exam version (`ExamContent` in the web app) — the report and its clinical context. `report_lexical` is the web editor's state (Lexical JSON, as a string) and is the source of truth; `report_html` is derived from it for readers that never open the editor. Write both when you produce a report, or the web editor opens an empty document.
-
patient_idstring required -
security_groupstring required
Responses #
-
201 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 content of an exam version (`ExamContent` in the web app) — the report and its clinical context. `report_lexical` is the web editor's state (Lexical JSON, as a string) and is the source of truth; `report_html` is derived from it for readers that never open the editor. Write both when you produce a report, or the web editor opens an empty document.
-
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 POST "https://api.imgexam.com/v1/exams" \
-H "Content-Type: application/json" \
-d @body.jsonimport httpx
response = httpx.post(
"https://api.imgexam.com/v1/exams",
cert=("client.crt", "client.key"),
json=body,
)
response.raise_for_status()
print(response.json()){
"record": {
"title": {},
"modality": {},
"exam_date": {},
"report_lexical": {},
"report_html": {},
"custom_attributes": {}
},
"patient_id": "string",
"security_group": "string"
}{
"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": {
"title": {},
"modality": {},
"exam_date": {},
"report_lexical": {},
"report_html": {},
"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": {}
}
}