---
title: "ABDM API — Patient"
description: "Nice HMS ABDM patient endpoints: create_patient, patient_by_id, patient_by_abhaAddress, and the two-step ABHA registration (patient_register_abha_otp_init / confirm)."
date: 2026-08-26
lastModified: 2026-09-29
category: "developer"
author: "Dr. Umesh Bilagi"
beta: true
---

All patient endpoints are **POST** and authenticated (`Authorization: Bearer <idToken>`).

---

## `/create_patient` — POST (auth)

Creates a **non-ABHA** patient (written to both MySQL and the GCP FHIR store).

### Request fields — `patient` object

| Name | Type | Required | Description |
|---|---|---|---|
| `patient.firstName` | string | Yes | Non-empty. |
| `patient.gender` | string | Yes | `"Male"` \| `"Female"` \| `"Other"`. |
| `patient.dob` | string | Yes | `YYYY-MM-DD`, a valid **past** date. |
| `patient.mobile` | string | Yes | Exactly 10 digits. |
| `patient.state` | string | Yes | Non-empty. |
| `patient.district` | string | Yes | Non-empty. |
| `patient.abhaAddress` | string | **No** | Rejected — see note below. |
| `patient.abhaNumber` | string | **No** | Rejected — see note below. |
| `patient.prefix` | string | No | `Mr` \| `Mrs` \| `Ms` \| `Dr` \| `NA` \| `Master` \| `Er`. |
| `patient.middleName` | string | No | |
| `patient.lastName` | string | No | |
| `patient.address` | string | No | |
| `patient.panNumber` | string | No | |
| `patient.aadharNumber` | string | No | |
| `patient.email` | string | No | |
| `patient.alternatePhoneNumber` | string | No | |
| `patient.pincode` | number | No | |

### Example request

```json
{
  "patient": {
    "prefix": "Mr",
    "firstName": "Umesh",
    "middleName": "",
    "lastName": "Bilagi",
    "gender": "Male",
    "dob": "1989-04-26",
    "district": "Dharwad",
    "state": "KARNATAKA",
    "mobile": "9233235620",
    "address": "Hno11 , near pulley school",
    "panNumber": "APYVB3402Q",
    "aadharNumber": "514782451234",
    "email": "rameshH007@gmail.com",
    "alternatePhoneNumber": "0836223456"
  }
}
```

### Example response

```json
{
  "patient": {
    "id": 231,
    "prefix": "Mr",
    "firstName": "Umesh",
    "middleName": "",
    "lastName": "Bilagi",
    "gender": "Male",
    "dob": "1989-04-26T00:00:00.000Z",
    "orgId": 1,
    "gcpFhirId": "b6165fd2-b76a-48e3-81ad-202b3919d668",
    "abhaAddress": "",
    "abhaNumber": "",
    "district": "Dharwad",
    "state": "KARNATAKA",
    "mobile": "9233235620",
    "address": "Hno11 , near pulley school",
    "panNumber": "APYVB3402Q",
    "aadharNumber": "514782451234",
    "email": "rameshH007@gmail.com",
    "alternatePhoneNumber": "0836223456",
    "pincode": 580030
  }
}
```

### Error codes

Shared codes only (no route-specific extras).

**Note:** ABHA patients must be created via `/patient_register_abha_otp_init` +
`/patient_register_abha_otp_confirm`. Passing `abhaAddress` or `abhaNumber` here returns
`400 VALIDATION_ERROR` with message *"The direct input of Abha Address or Abha number is not possible."*

---

## `/patient_by_id` — POST (auth)

Fetches a single patient by Nice HMS (MySQL) id.

### Request fields

| Name | Type | Required | Description |
|---|---|---|---|
| `patientId` | number | Yes | The unique patient id generated within Nice HMS. |

### Example request

```json
{
  "patientId": 236
}
```

### Example response

Same `PatientRes` shape as `/create_patient` (a `patient` object).

### Error codes

- `PATIENT_NOT_FOUND` (404) — no patient matches this id for your organization.
- shared codes

---

## `/patient_by_abhaAddress` — POST (auth)

Fetches a single patient by ABHA address. The patient must already be registered in Nice
HMS under your organization using their ABHA address (via Aadhar/mobile OTP, ABHA card QR,
or the reception-generated HFR QR code).

### Request fields

| Name | Type | Required | Description |
|---|---|---|---|
| `abhaAddress` | string | Yes | The patient's ABHA address, e.g. `savitribilagi@sbx`. |

### Example request

```json
{
  "abhaAddress": "savitribilagi@sbx"
}
```

### Example response

Same `PatientRes` shape as `/create_patient`.

### Error codes

- `PATIENT_NOT_FOUND` (404)
- shared codes

---

## `/patient_register_abha_otp_init` — POST (auth)

Step 1 of ABHA registration: search the ABHA address and request an OTP. Returns a
`transactionId` used in step 2.

### Request fields

| Name | Type | Required | Description |
|---|---|---|---|
| `abhaAddress` | string | Yes | ABHA address to register, e.g. `abcd@abdm`. |
| `authMode` | string | Yes | `"MOBILE_OTP"` \| `"AADHAAR_OTP"` \| `"DONT_KNOW"`. See below. |

`authMode` selects which mobile number the OTP goes to:

- `"MOBILE_OTP"` — the mobile registered against the ABHA in ABDM.
- `"AADHAAR_OTP"` — the mobile linked to the patient's Aadhaar. Use this when the ABHA has
  no ABDM-verified mobile; it also works for patients who do.
- `"DONT_KNOW"` — no OTP is sent. The response lists the modes the ABHA supports so the
  caller can ask the patient to choose.

The mode you pass here must also be passed to `/patient_register_abha_otp_confirm`, otherwise
the verification is attempted on the wrong channel.

### Example request

```json
{
  "abhaAddress": "abcd@abdm",
  "authMode": "MOBILE_OTP"
}
```

### Example response

OTP sent:

```json
{
  "auth": {
    "transactionId": "f455d2f9-18f1-4c6e-bfd0-df5ff2449f97",
    "modes": ["MOBILE_OTP", "AADHAAR_OTP"]
  }
}
```

`authMode: "DONT_KNOW"` — no `transactionId`, because no OTP was sent:

```json
{
  "auth": {
    "modes": ["MOBILE_OTP", "AADHAAR_OTP"]
  }
}
```

Pass `auth.transactionId` to `/patient_register_abha_otp_confirm`.

### Error codes

- `VALIDATION_ERROR` (400)
- `ABDM_GATEWAY_ERROR` (502) — the auth mode is not available or is blocked for this ABHA
  address; or ABDM rejected the request. `error.message` carries ABDM's own reason.
- shared codes

---

## `/patient_register_abha_otp_confirm` — POST (auth)

Step 2 of ABHA registration: verify the OTP and create the patient. Call this after
`patient_register_abha_otp_init` (which returns the `transactionId`).

### Request fields

| Name | Type | Required | Description |
|---|---|---|---|
| `transactionId` | string | Yes | Returned by `patient_register_abha_otp_init`. |
| `otp` | string | Yes | The OTP the patient received. |
| `abhaAddress` | string | Yes | The ABHA address being registered. |
| `authMode` | string | No | `"MOBILE_OTP"` \| `"AADHAAR_OTP"`. Defaults to `"MOBILE_OTP"`. Must match the mode used in `/patient_register_abha_otp_init`. |

### Example request

```json
{
  "transactionId": "f455d2f9-18f1-4c6e-bfd0-df5ff2449f97",
  "otp": "886367",
  "abhaAddress": "abcd1234@abdm",
  "authMode": "MOBILE_OTP"
}
```

Omitting `authMode` behaves exactly as `"MOBILE_OTP"` — existing integrations are unaffected.

### Example response

Returns the created `PatientRes` (same shape as `/create_patient`).

### Error codes

- `VALIDATION_ERROR` (400)
- `ABDM_GATEWAY_ERROR` (502) — OTP verification failed / no user returned; or the OTP was
  requested on a different `authMode` than the one sent here. `error.message` carries ABDM's
  own reason.
- shared codes
