ABDM v3 · M1–M4 implemented

M1 ABHA API

ABHA integration through one REST API

Every ABHA flow NHA certifies as Milestone 1, as ordinary REST calls: create an account, prove an existing one, print the card, and write the result onto your own patient record. This is the developer’s view — for what an ABHA is and why a citizen holds one, read the ABHA and Ayushman Bharat overview.

01 The surface

What an ABHA integration calls

Six groups of endpoints. All but Scan & Share authenticate with your credential alone, so one integration serves every facility on your account.

Create

Enrol a new ABHA

Aadhaar OTP is the common case. Mobile OTP creates an ABHA address, and the number follows only after KYC. Demo Auth and biometric creation exist for patients without a phone, each behind an NHA permission.

POST /v1/abha/enrolment/aadhaar · /mobile · /demo-auth · /biometric

Verify

Log in to an existing ABHA

By ABHA number, mobile or Aadhaar, with one OTP. When a mobile carries several ABHAs the session stops at account_pending and you name the one the patient means.

POST /v1/abha/login · /login/{session_id}/verify · /account

Find

Find ABHA, sending nothing

A lookup that spends no OTP and asks for no consent. It returns masked hits for the operator to confirm, each with an index that a biometric capture can then prove.

POST /v1/abha/search · /search/{session_id}/biometric

Read

Profile, card and QR

A normalised profile, and the ABHA card and QR as bytes the front desk can print without a second round trip. They use the citizen’s own token, so fetch them while the session is alive.

GET /v1/abha/sessions/{session_id}/profile · /card · /qr

Link

Write it onto your patient

Name your facility and MRN when a flow starts and the verified ABHA lands on that patient when it completes — or link the session afterwards.

POST /v1/abha/sessions/{session_id}/patient

Counter

Scan & Share

The patient scans a counter QR in their own ABHA app. Their profile arrives with a token number, and your desk looks the arrival up by the token the phone is showing.

GET /v1/facility/scan-share-qr · /v1/profile-shares

02 At the counter

Six patients, six routes

Design for the nine o’clock OPD line: one operator, and patients who did not all bring a charged phone. Only the routes that need the phone in hand spend an OTP.

The patientRouteCallsOTP
Has an ABHA app on their phone Scan & Share GET /v1/profile-shares No
Knows their ABHA or Aadhaar, phone at home Find ABHA, then fingerprint or iris POST /v1/abha/search, then …/biometric No
Has an ABHA and their phone Login by OTP POST /v1/abha/login, then …/verify Yes
No ABHA, has their phone Aadhaar or mobile enrolment POST /v1/abha/enrolment/aadhaar Yes, once
No ABHA, no phone Demo Auth enrolment POST /v1/abha/enrolment/demo-auth No — needs a BENEFIT-NAME
No ABHA, no phone, certified scanner Biometric enrolment POST /v1/abha/enrolment/biometric No — needs NHA to enable it

Missing from the table: checking an existing ABHA against the demographics you already hold. ABDM v3 has no such call. The write-ups that describe one are describing HealthID v1’s confirmWithDemographics, which was retired. Do not promise it to a hospital.

03 Enrolment

Creating an ABHA from Aadhaar

Two OTP-bearing calls and an address choice. The session carries the state between them, so the counter screen only ever holds a session id.

  1. Start with the Aadhaar number

    Send your facility and MRN with it if the desk already has them. The number is RSA-sealed with ABDM’s public key (OAEP with SHA-1, the padding ABDM mandates) before it leaves the connector, and never reaches a database or a log.

  2. Verify the OTP

    UIDAI texts the Aadhaar-registered mobile. A different mobile for the ABHA needs its own OTP before it counts as verified — and an unverified number cannot receive the linking SMS that M2 sends.

  3. Choose an address

    The session waits at address_pending. List the suggestions, let the citizen pick, post the choice. A new account can have no address yet, so never read the first element of the list blind.

  4. Receive the webhook

    abha.created arrives signed. If you named a patient at the start, the ABHA has been written onto that record.

enrol by aadhaar otp Sandbox
# start — sealed here, never stored
POST /v1/abha/enrolment/aadhaar

{
  "patient_reference": "MRN-1001",
  "aadhaar_number": "XXXXXXXX9012"
}

← 201 Created
{
  "id": "7b21e0c4-…",
  "flow": "enrol_aadhaar",
  "status": "otp_sent"
}

# verify
POST /v1/abha/enrolment/{session_id}/verify

{
  "otp": "******",
  "mobile": "98XXXXXX10"
}

← 200 OK
{
  "status": "address_pending"
}

# then pick the address
GET  /v1/abha/enrolment/{session_id}/addresses
POST /v1/abha/enrolment/{session_id}/address

04 No phone

Find ABHA, then prove it

For the patient who has an ABHA but not the phone it texts. The search proves nothing; the capture that follows proves everything.

  1. Search by mobile

    No OTP is sent and nothing reaches the citizen. An empty results list is an answer, not an error: they may not have an ABHA yet. An Aadhaar variant is accepted too, though NHA’s guide documents only the mobile body.

  2. Confirm the person, not the number

    The operator reads back the name, gender and masked number, and picks a hit by its index — which means something only inside this session. Check its auth_methods first: an account without AADHAAR_BIO will refuse a capture.

  3. Capture on a certified device

    Name the index, then submit the PID block from a UIDAI-certified fingerprint or iris device. It travels exactly as the device encrypted it for UIDAI, and is never logged or stored.

  4. Now the number is real

    The completed verification returns the profile with the full ABHA number, ready to write onto the patient. Verifying an existing ABHA this way needs no extra NHA entitlement.

find abha, verify by biometric Sandbox
POST /v1/abha/search

{
  "mobile": "98XXXXXX10"
}

← 201 Created
{
  "id": "3fa85f64-…",
  "status": "search_results",
  "results": [
    {
      "index": 0,
      "abha_number": "91-5259-8743-XXXX",
      "masked": true,
      "name": "Asha Devi",
      "gender": "F",
      "kyc_verified": true,
      "auth_methods": ["AADHAAR_OTP", "AADHAAR_BIO"]
    }
  ]
}
   ↑ masked: never write this onto a patient

# name the hit
POST /v1/abha/search/{session_id}/biometric

{
  "method": "bio",
  "index": 0
}

# send the capture from the RD device
POST /v1/abha/login/{session_id}/biometric/verify

05 Failure modes

Where M1 integrations break

Each of these looks like a bug in your code and is not. Two are handled below the API you call; the third is a set of permissions only NHA can grant.

Masks

Storing a masked ABHA number

Find ABHA returns numbers like 91-5259-8743-XXXX. Written onto a patient, that string looks exactly like a linked ABHA and matches the citizen nowhere. Its digits are a prefix of the real number, so even comparing against it reports “a different ABHA” for the citizen’s own record.

Handled · a masked number is never written onto a patient or compared

Tokens

Using a T-token as an X-token

A mobile login returns a short-lived transaction token while an ABHA still has to be chosen; an Aadhaar or ABHA-number login returns the citizen’s own X-token. Send the wrong one to a profile read and ABDM answers with a 401 that says nothing about why.

Handled · tokens classified by their claims, and never returned to you

Permissions

Assuming every route is switched on

Biometric ABHA creation is off by default and needs NHA to enable it for your client id. Demo Auth needs a BENEFIT-NAME that NHA issues per integrator for a named programme, and no default can be invented for it. Driving-licence enrolment is implemented, but NHA does not enable it in the sandbox.

Refused locally · abha_biometric_not_enabled, abha_benefit_name_not_configured

An ABHA on its own is not an integration; an ABHA on your MRN is. Pass patient_reference on any start request — the hospital is the one your key serves, so there is nothing else to name — and the ABHA number, address and ABDM’s demographics are written onto that patient when the flow completes. Demographics your system already holds are not overwritten.

A desk that registers first and verifies later calls POST /v1/abha/sessions/{session_id}/patient instead, any time before the session expires: 201 when it created the patient, 200 when it updated one.

Care contexts in M2 are linked to that ABHA, so this is the step HIP integration builds on.

07Scan & Share at the counter

Fetch one QR payload per counter from GET /v1/facility/scan-share-qr?counter_code=OPD-2 and render it yourself. The patient scans it in their ABHA app, which authenticates them; ABDM pushes their profile, the connector answers with a token number their phone displays, and a patient.profile_shared webhook fires. The operator enters the token in GET /v1/profile-shares?token_number=104 and registers from the demographics that come back. Drop token_number for the day’s queue in arrival order.

Two things to know. NHA specifies no token-board API — its playbook leaves token generation and queue display to the HMS — so the token counter, its daily reset and the queue are this connector’s own surface, not ABDM’s. And the facility must exist in HFR and be linked to the bridge before ABDM will deliver a share, which the HFR integration page covers.

08Getting M1 certified

ABHA is certified as Milestone 1, and the integration is typically a few weeks of it. After self-testing against the NHA sandbox, an NHA-empanelled agency runs functional testing against the M1 test cases, and a CERT-In empanelled auditor performs the WASA security audit — 5–8 weeks including remediation, ending in a Safe-to-Host certificate — before NHA’s own review of 2–4 weeks.

Test cases with a user-interface half — consent text, a resend timer, the card on screen — are demonstrated in your own software. What comes after M1 is in the milestone guide, rollout at a facility in ABDM for hospitals, and what ABDM is covers the network itself.

Run an enrolment against the sandbox today

Sandbox keys are issued on signup. Enrol a sandbox test Aadhaar, link it to a test MRN, and watch abha.created arrive.

FAQ Common questions

Frequently asked questions

What APIs are needed for ABHA integration?
Enrolment by Aadhaar OTP or mobile OTP, login to an existing ABHA, Find ABHA by mobile number, the profile, card and QR reads, and a call that links the verified ABHA to your own patient record. Together these are what ABDM certifies as Milestone 1.
Can we verify a patient's ABHA without an OTP?
Yes, two ways. With Scan & Share the patient scans the counter QR in their own ABHA app, which authenticates them. Without a phone, Find ABHA locates the account and a fingerprint or iris capture on a UIDAI-certified device proves it. ABDM v3 has no demographic verification of an existing ABHA.
How is an ABHA linked to our patient record?
Pass your facility and your own patient reference (the MRN) when you start the ABHA flow, or link the session afterwards. A patient already linked to a different ABHA is refused rather than silently re-pointed.
Does ABHA integration need ABDM certification?
Yes. ABHA is certified as Milestone 1, and production access also needs functional testing by an NHA-empanelled agency and a security audit. The sandbox is open while you build.