Last updated: 4 October 2026
Document endpoints are POST and authenticated (Authorization: Bearer <idToken>).
Each creates a FHIR Composition and pushes it to ABDM. Each returns a CompositionRes
object (a composition FHIR resource). All use "patientNeeds" — at least one of
abhaAddress (string) or patientId (number); omitting both yields
400 VALIDATION_ERROR.
The five document endpoints share these error codes (plus each endpoint's own extras):
INVALID_DOCTOR_GCP_FHIR_ID(400) ·PATIENT_NOT_FOUND(404) ·ENCOUNTER_NOT_FOUND(404) ·NO_ACTIVE_ENCOUNTER(409) ·ABDM_GATEWAY_ERROR(502) ·LINK_TOKEN_MISSING(502) ·LINK_TOKEN_RATE_LIMITED(429)
Every document is filed against an encounter (the ABDM care-context reference). Each of
the five endpoints accepts an optional encounterId; resolution works the same way for
all of them:
encounterId supplied — that encounter is used. It must belong to the patient
and to your organization, otherwise 404 ENCOUNTER_NOT_FOUND.encounterId omitted — the patient's open encounter is used (status
in-progress, arrived, planned, triaged).finished) — so a discharged patient's documents still upload.409 NO_ACTIVE_ENCOUNTER. Create a visit with
/opd_patient or /admit_patient before pushing a document.The four JSON document endpoints — /discharge_summary, /diagnostic_report,
/op_consultation, /procedure_ot_notes — accept text/HTML only via their text /
content fields. They cannot accept file attachments (no multipart upload).
Only /health_document accepts file uploads. It accepts PDF, JPEG or PNG files up to
5 MB each, across page1–page4, with a PDF uploaded on its own — a PDF cannot
be combined with images. A file's type is determined from the file's own bytes, not from
the Content-Type you send for that part, so a renamed or mislabelled file is rejected
rather than silently stored as something else. Scanned PDFs can be sent directly —
converting to images is no longer required.
/discharge_summary — POST (auth)Creates a DischargeSummary composition and pushes it to ABDM.
| Name | Type | Required | Description |
|---|---|---|---|
doctorDetails | array | Yes | Array of { doctorName, doctorGcpId }, min 1. |
text | string | Yes | Summary content (HTML allowed). |
status | string | Yes | Use "final" — only final is pushed to ABDM. |
date | string | Yes | ISO date. |
compositionId | string | No | Optional composition id. |
encounterId | string | No | Attach to a specific encounter (must belong to the patient and your org). When omitted, see Encounter resolution. |
abhaAddress | string | —* | Patient's ABHA address. |
patientId | number | —* | Nice HMS patient id. |
* At least one of abhaAddress / patientId is required.
{
"abhaAddress": "savitribilagi@sbx",
"text": "<div>Cough with APD</div><div>cough</div><div>BP 140/80 PR 87/min RR 20/min</div>",
"doctorDetails": [
{ "doctorName": "Dr Umesh Bilagi", "doctorGcpId": "cf4a6ab1-3f32-4b92-adc5-89489da6ca14" }
],
"status": "final",
"date": "2023-05-08T19:21:23.918Z"
}
{
"composition": {
"id": "e721069a-cc8c-4e5e-a437-b4cfcaee11a4",
"resourceType": "Composition",
"status": "final",
"title": "DischargeSummary",
"date": "2023-05-08T19:21:23.918Z",
"subject": { "reference": "Patient/9b4ec056-991d-4237-b1fd-a65770349610" }
}
}
ENCOUNTER_NOT_FOUND (404) — a supplied encounterId does not belong to this patient and org.NO_ACTIVE_ENCOUNTER (409) — the patient has no encounter at all; create a visit first./diagnostic_report — POST (auth)Creates a DiagnosticReport composition and pushes it to ABDM.
| Name | Type | Required | Description |
|---|---|---|---|
performer | array | Yes | Array of { doctorName, doctorGcpId }, min 1. The performer is who signs the report. |
testName | string | Yes | Non-empty, e.g. "CT Abdomen". |
category | string | Yes | "Hematology" | "Biochemistry" | "Microbiology" | "Radiology" | "Others". |
text | string | Yes | Non-empty report content (HTML allowed). |
status | string | Yes | Use "final" — only final is pushed to ABDM. |
requester | object | No | { doctorName, doctorGcpId }. If omitted, the requester is assumed to be the patient. |
conclusion | string | No | e.g. "Normal Study". |
compositionId | string | No | Optional. |
encounterId | string | No | Attach to a specific encounter (must belong to the patient and your org). When omitted, see Encounter resolution. |
date | string | No | ISO date; defaults to the request timestamp when omitted. |
abhaAddress | string | —* | Patient's ABHA address. |
patientId | number | —* | Nice HMS patient id. |
* At least one of abhaAddress / patientId is required.
{
"abhaAddress": "savitribilagi@sbx",
"performer": [
{ "doctorName": "Dr Umesh Bilagi", "doctorGcpId": "cf4a6ab1-3f32-4b92-adc5-89489da6ca14" }
],
"testName": "CT Abdomen",
"category": "Radiology",
"text": "<div>Ultrasound Report ...</div>",
"status": "final",
"conclusion": "Normal Study"
}
Returns a CompositionRes object.
INVALID_DOCTOR_GCP_FHIR_ID (400) — validates performer and requester.PATIENT_NOT_FOUND (404) · ENCOUNTER_NOT_FOUND (404) · NO_ACTIVE_ENCOUNTER (409)ABDM_GATEWAY_ERROR (502) · LINK_TOKEN_MISSING (502) · LINK_TOKEN_RATE_LIMITED (429)/op_consultation — POST (auth)Creates an OP Consultation composition and pushes it to ABDM.
| Name | Type | Required | Description |
|---|---|---|---|
doctorDetails | array | Yes | Array of { doctorName, doctorGcpId }, min 1. |
date | string | Yes | ISO date of the consultation. |
status | string | Yes | Current status of the consultation. |
chiefComplaints | string | No | Primary complaints reported by the patient. |
medicalHistory | string | No | Patient's past medical history. |
physicalExamination | string | No | Findings from the physical examination. |
medicines | array | No | Array of { drug, frequency, instruction, duration, route }. |
opdProcedure | object | No | { procedureName, procedureDescription, date? }. |
followUp | object | No | { startDate, endDate?, comment }. |
compositionId | string | No | Optional. |
encounterId | string | No | Attach to a specific encounter (must belong to the patient and your org). When omitted, see Encounter resolution. |
abhaAddress | string | —* | Patient's ABHA address. |
patientId | number | —* | Nice HMS patient id. |
* At least one of abhaAddress / patientId is required.
{
"abhaAddress": "savitribilagi@sbx",
"doctorDetails": [
{ "doctorName": "Dr Umesh Bilagi", "doctorGcpId": "cf4a6ab1-3f32-4b92-adc5-89489da6ca14" }
],
"date": "2023-05-08T19:21:23.918Z",
"status": "final",
"chiefComplaints": "Cough and fever",
"medicines": [
{ "drug": "Paracetamol", "frequency": "BD", "instruction": "After food", "duration": "5 days", "route": "Oral" }
]
}
Returns a CompositionRes object.
INVALID_DOCTOR_GCP_FHIR_ID (400)PATIENT_NOT_FOUND (404) · ENCOUNTER_NOT_FOUND (404) · NO_ACTIVE_ENCOUNTER (409)ABDM_GATEWAY_ERROR (502) · LINK_TOKEN_MISSING (502) · LINK_TOKEN_RATE_LIMITED (429)/procedure_ot_notes — POST (auth)Creates a procedure / OT-notes composition and pushes it to ABDM.
| Name | Type | Required | Description |
|---|---|---|---|
doctorDetails | array | Yes | Array of { doctorName, doctorGcpId }, min 1. |
date | string | Yes | ISO date of the procedure. |
status | string | Yes | Current status of the procedure. |
opdProcedure | object | No | { procedureName, procedureDescription, date? }. |
followUp | object | No | { startDate, endDate?, comment }. |
compositionId | string | No | Optional. |
encounterId | string | No | Attach to a specific encounter (must belong to the patient and your org). When omitted, see Encounter resolution. |
abhaAddress | string | —* | Patient's ABHA address. |
patientId | number | —* | Nice HMS patient id. |
* At least one of abhaAddress / patientId is required.
{
"abhaAddress": "savitribilagi@sbx",
"doctorDetails": [
{ "doctorName": "Dr Umesh Bilagi", "doctorGcpId": "cf4a6ab1-3f32-4b92-adc5-89489da6ca14" }
],
"date": "2023-05-08T19:21:23.918Z",
"status": "final",
"opdProcedure": {
"procedureName": "Appendectomy",
"procedureDescription": "Laparoscopic appendectomy"
}
}
Returns a CompositionRes object.
INVALID_DOCTOR_GCP_FHIR_ID (400)PATIENT_NOT_FOUND (404) · ENCOUNTER_NOT_FOUND (404) · NO_ACTIVE_ENCOUNTER (409)ABDM_GATEWAY_ERROR (502) · LINK_TOKEN_MISSING (502) · LINK_TOKEN_RATE_LIMITED (429)/health_document — POST (multipart/form-data, auth)Uploads a scanned health document (PDF, JPEG or PNG) and creates a HealthDocumentRecord composition. Each file must be under 5 MB.
| Name | Type | Required | Description |
|---|---|---|---|
doctorDetails | string | Yes | JSON string, e.g. "[{\"doctorName\":\"Dr Umesh\",\"doctorGcpId\":\"...\"}]". |
text | string | Yes | Title, e.g. "Prescription" or "Lab report". |
status | string | Yes | One of preliminary, final, amended, entered-in-error. Only final is pushed to ABDM. |
date | string | No | ISO date. |
compositionId | string | No | Optional. |
encounterId | string | No | Attach to a specific encounter (must belong to the patient and your org). When omitted, see Encounter resolution. |
abhaAddress | string | —* | Patient's ABHA address. |
patientId | number | —* | Nice HMS patient id. |
* At least one of abhaAddress / patientId is required.
| Name | Required | Description |
|---|---|---|
page1 | Yes | PDF, JPEG or PNG, ≤ 5 MB. |
page2 | No | PDF, JPEG or PNG, ≤ 5 MB. |
page3 | No | PDF, JPEG or PNG, ≤ 5 MB. |
page4 | No | PDF, JPEG or PNG, ≤ 5 MB. |
If one of page1–page4 is a PDF, it must be the only file in the request. Send the
request as multipart/form-data using your client's multipart mode — do not set a
Content-Type header by hand, or the multipart boundary is lost and the request is
rejected.
Returns a CompositionRes object, plus:
| Name | Description |
|---|---|
abdmNotified | true if the document was pushed to ABDM. false when status is not final. |
abdmNotifiedReason | Present only when abdmNotified is false — why it was not pushed. |
INVALID_REQUEST_METHOD (400) — non-POST method.DOCTOR_DETAILS_REQUIRED (400) — doctorDetails form field missing.VALIDATION_ERROR (400) — invalid form fields; unsupported file type; no file sent; a PDF combined with images.VALIDATION_ERROR (413) — a file exceeds the 5 MB limit.INVALID_DOCTOR_GCP_FHIR_ID (400)PATIENT_NOT_FOUND (404) · ENCOUNTER_NOT_FOUND (404) · NO_ACTIVE_ENCOUNTER (409)ABDM_GATEWAY_ERROR (502) · LINK_TOKEN_MISSING (502) · LINK_TOKEN_RATE_LIMITED (429)