Last updated: 26 August 2026
All endpoints are called with an Authorization: Bearer <idToken> header — except
/auth_token, which issues that token.
https://asia-south1-psychic-city-328609.cloudfunctions.net/<endpoint>
/discharge_patient is PUT./health_document is multipart/form-data (POST).Every error response uses the same JSON shape. There are no other error shapes.
{
"message": "Human-readable summary of the failure",
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request body",
"details": [
{ "field": "patient.abhaAddress", "message": "The direct input of Abha Address or Abha number is not possible." }
]
}
}
| Field | Always present? | Meaning |
|---|---|---|
message | Yes | Top-level summary (kept for backward compatibility — safe to keep parsing it). |
error.code | Yes | Stable, machine-readable code. Match on this. |
error.message | Yes | Curated, human-readable message. |
error.details | No — only on VALIDATION_ERROR | Array of { field, message }, one entry per failed field. |
Example — non-validation error
{
"message": "Patient not found",
"error": {
"code": "PATIENT_NOT_FOUND",
"message": "Patient not found"
}
}
x-request-id headerEvery response includes an x-request-id header:
x-request-id header, its value is echoed back unchanged.Send an x-request-id on every request and log the request/response pair against it. When
escalating an issue to Nice HMS support, include this value — it correlates to the
server-side log of the full (unredacted) error.
Match on error.code — these are stable strings.
error.code | HTTP | Meaning |
|---|---|---|
VALIDATION_ERROR | 400 | Request body failed schema validation. See error.details for field-level reasons. |
INVALID_EMAIL_FORMAT | 400 | An email string is malformed. |
INVALID_DOCTOR_GCP_FHIR_ID | 400 | A doctorGcpId does not exist in the FHIR store (Practitioner). |
DOCTOR_DETAILS_REQUIRED | 400 | doctorDetails is missing (health_document). |
INVALID_REQUEST_METHOD | 400 | Wrong HTTP method for the endpoint. |
UNAUTHORIZED | 401 | Missing/invalid/expired token, or the token is not mapped to an organization. |
SUBSCRIPTION_EXPIRED | 403 | The organization's subscription is invalid or expired. |
PATIENT_NOT_FOUND | 404 | No patient matches the supplied patientId / abhaAddress for this organization. |
ENCOUNTER_NOT_FOUND | 404 | No open encounter, or the supplied encounterId was not found. |
DOCTOR_NOT_FOUND | 404 | The Practitioner FHIR id does not exist (edit_doctor). |
EMAIL_ALREADY_EXISTS | 409 | Duplicate email when creating a doctor. |
ABDM_GATEWAY_ERROR | 502 | Upstream ABDM gateway returned an error (e.g. OTP verification failed, auth mode unavailable). |
LINK_TOKEN_MISSING | 502 | ABDM care-context link token was not found after the callback. |
DB_ERROR | 500 | A database operation failed. Curated generic message. |
INTERNAL_ERROR | 500 | Any unhandled / unknown error. Curated generic message. |
| Status | Category |
|---|---|
| 200 | Success |
| 400 | Bad request / validation |
| 401 | Unauthorized |
| 403 | Forbidden (subscription) |
| 404 | Not found |
| 409 | Conflict (duplicate) |
| 500 | Internal server error |
| 502 | Bad gateway (ABDM upstream) |
400 VALIDATION_ERROR first (auth is checked after body
validation).details[].field use dot notation, e.g. patient.firstName,
doctorDetails.0.doctorGcpId, patient.dob.x-request-id.The following codes are present on every authenticated route:
VALIDATION_ERROR(400) ·UNAUTHORIZED(401) ·SUBSCRIPTION_EXPIRED(403) ·DB_ERROR(500) ·INTERNAL_ERROR(500)
Each endpoint's documentation lists these shared codes + its own additional codes.
Where a route says "patientNeeds", the body must include at least one of abhaAddress
(string) or patientId (number). Omitting both yields 400 VALIDATION_ERROR with the
message "Either abhaAddress or patientId is required".
The table lists each route's additional codes — the ones on top of the shared codes.
(/auth_token is public and skips the subscription check.)
| Endpoint | Additional error codes |
|---|---|
/auth_token (public) | VALIDATION_ERROR (400) · UNAUTHORIZED (401) |
/create_patient | — |
/create_doctor | INVALID_EMAIL_FORMAT (400) · EMAIL_ALREADY_EXISTS (409) |
/edit_doctor | DOCTOR_NOT_FOUND (404) |
/get_doctor_opd_patients_by_date | — |
/get_doctor_ipd_patients_by_date | — |
/patient_by_id | PATIENT_NOT_FOUND (404) |
/patient_by_abhaAddress | PATIENT_NOT_FOUND (404) |
/patient_register_abha_otp_init | ABDM_GATEWAY_ERROR (502) |
/patient_register_abha_otp_confirm | ABDM_GATEWAY_ERROR (502) |
/opd_patient | INVALID_DOCTOR_GCP_FHIR_ID (400) · PATIENT_NOT_FOUND (404) |
/admit_patient | INVALID_DOCTOR_GCP_FHIR_ID (400) · PATIENT_NOT_FOUND (404) |
/discharge_patient | INVALID_DOCTOR_GCP_FHIR_ID (400) · PATIENT_NOT_FOUND (404) · ENCOUNTER_NOT_FOUND (404) |
/discharge_summary | INVALID_DOCTOR_GCP_FHIR_ID (400) · PATIENT_NOT_FOUND (404) · ENCOUNTER_NOT_FOUND (404) · ABDM_GATEWAY_ERROR (502) · LINK_TOKEN_MISSING (502) |
/diagnostic_report | INVALID_DOCTOR_GCP_FHIR_ID (400) · PATIENT_NOT_FOUND (404) · ENCOUNTER_NOT_FOUND (404) · ABDM_GATEWAY_ERROR (502) · LINK_TOKEN_MISSING (502) |
/op_consultation | INVALID_DOCTOR_GCP_FHIR_ID (400) · PATIENT_NOT_FOUND (404) · ENCOUNTER_NOT_FOUND (404) · ABDM_GATEWAY_ERROR (502) · LINK_TOKEN_MISSING (502) |
/procedure_ot_notes | INVALID_DOCTOR_GCP_FHIR_ID (400) · PATIENT_NOT_FOUND (404) · ENCOUNTER_NOT_FOUND (404) · ABDM_GATEWAY_ERROR (502) · LINK_TOKEN_MISSING (502) |
/health_document | INVALID_REQUEST_METHOD (400) · DOCTOR_DETAILS_REQUIRED (400) · INVALID_DOCTOR_GCP_FHIR_ID (400) · PATIENT_NOT_FOUND (404) · ENCOUNTER_NOT_FOUND (404) · ABDM_GATEWAY_ERROR (502) · LINK_TOKEN_MISSING (502) |
/uhi and /uhi/whatsapp follow the UHI protocol (search/init/confirm/cancel/status),
which has its own acknowledgement and error format — documented separately, not via this
envelope.| You did this | You'll see |
|---|---|
| Missing/invalid token | 401 UNAUTHORIZED |
| Expired subscription | 403 SUBSCRIPTION_EXPIRED |
| Bad field / wrong enum / missing required field | 400 VALIDATION_ERROR (+ details) |
Wrong doctorGcpId | 400 INVALID_DOCTOR_GCP_FHIR_ID |
Unknown patientId / abhaAddress | 404 PATIENT_NOT_FOUND |
Unknown encounterId | 404 ENCOUNTER_NOT_FOUND |
Duplicate email on create_doctor | 409 EMAIL_ALREADY_EXISTS |
| ABDM OTP/search/verify failure | 502 ABDM_GATEWAY_ERROR |
| ABDM link token missing after callback | 502 LINK_TOKEN_MISSING |
| Anything else unexpected | 500 INTERNAL_ERROR / 500 DB_ERROR |