M4 Healthcare Professional Registry
The Healthcare Professional Registry, from your software
An HPR ID tells ABDM who a practitioner is. It does not say they are a doctor. That takes a second record — council, qualifications, place of work — which HPR verifies over days, outside any API.
01 Two halves
An identity, and the record behind it
Most confusion about HPR — “we registered the doctor, so why is nothing verified?” — is these two being read as one.
A number, an address such as name@hpr.abdm, and a login,
verified against Aadhaar when it is created. It carries no council
registration, no qualification and no place of work.
Created in one sitting · Aadhaar-verified · says nothing about practice
Which council registered them and under what number, what they qualified in and where, where they work now, and a certificate evidencing each. HPR queues it for verification.
Sent in one call · verified over days · by people, not the API
02 The HPR ID
Creating an HPR ID with Aadhaar
For a practitioner with no HPR ID yet. The session carries every step, and neither the Aadhaar number nor the password is ever stored.
-
Start with Aadhaar
By default the number is sealed and UIDAI texts its holder an OTP. With
method=link, UIDAI sends an authentication link instead and no Aadhaar number is sent at all. -
Confirm the authentication
The answer is
mobile_pendingwhen the practitioner can go on, orexisting_accountwith their HPR ID number when this Aadhaar already has one. On the link method, a409means they have not used the link yet. -
Verify a mobile
The Aadhaar-registered number is verified at once. Any other number gets its own OTP first.
-
Choose a username, create the ID
Suggestions come from HPR. With a facility on the session the practitioner joins its roster, verified. HPR’s token for the new ID is kept, so the professional record can start straight away rather than after a second login.
POST /v1/hpr/enrolments
{
"aadhaar_number": "XXXXXXXX9012",
"method": "otp"
}
↑ sealed with PKCS#1 v1.5, never stored
← 201 Created
{
"id": "5c1d9a70-…",
"flow": "enrol_aadhaar",
"status": "aadhaar_pending"
}
POST /v1/hpr/enrolments/{session_id}/aadhaar/verify
{
"otp": "******"
}
← 200 OK
{
"status": "mobile_pending"
}
POST /v1/hpr/enrolments/{session_id}/mobile
{
"mobile": "98XXXXXX10"
}
GET /v1/hpr/enrolments/{session_id}/suggestions
POST /v1/hpr/enrolments/{session_id}/hpr-id
{
"hpr_id": "ravi.kumar",
"password": "********"
}
03 The professional record
Collected in four steps, sent in one call
HPR has no per-section API: council registration, qualifications and current work travel in a single body. No form collects all of that on one screen, so the connector keeps a draft and assembles it at submit.
- Draft
-
Start the record
Name the practitioner’s own completed HPR session and their professional type — doctor or nurse decides which council and course lists apply. Every step acts as the practitioner; no token is accepted from you or returned to you.
- Council
-
Registration details
The council from HPR’s council masters, the registration number, the date on the certificate, whether it has to be renewed, and the certificate itself.
- Degrees
-
Qualifications
Up to ten, each with degree, college, university, year and a certificate. Re-sending this step replaces the list rather than adding to it.
- Work
-
Work details
Where they practise now. A facility in HFR is named by its HFR id alone; one that is not is given by address. Sending both is how a work declaration attaches to the wrong hospital.
The personal half is not retyped. Name, gender and date
of birth come from the practitioner’s HPR account, which HPR
verified against Aadhaar — retyping them is how a record ends up
disagreeing with the identity it hangs off. For a record HPR already
holds, submit with mode=update: HPR takes the identical body
and re-queues the whole record.
04 Verification
Submitted is not verified
Submitting returns a reference number and nothing else of consequence. What happens next happens at the council and the facility, over days.
- Submitted
-
HPR has the record
It accepted the body and returned a reference number. Nobody has looked at it yet.
- Council
-
The registration is checked
council_verifiedstaysnulluntil the council has looked — and null is not the same as rejected. - Facility
-
The work is confirmed
The facility the practitioner declared confirms it, tracked as
work_verified.
POST /v1/hpr/registrations/{registration_id}/submit
{
"hpr_login_id": "{fresh_session_id}",
"mode": "register"
}
↑ HPR tokens are short-lived: sign in again
← 200 OK
{
"status": "submitted",
"reference_number": "…"
}
# days later — read it, don't infer it
GET /v1/hpr/registrations/{registration_id}/status
← 200 OK
{
"reference_number": "…",
"council_verified": null,
"work_verified": null
}
05 Failure modes
Where HPR integrations go wrong
The expensive ones fail days later, at a council, where nobody can see the request that caused them.
- Certificates
-
A certificate that is not a PDF
HPR does not open the file when it accepts the record. A JPEG labelled as a certificate surfaces days later as a verification rejection, by which time nobody still has the original.
- Sealing
-
Reusing the ABHA encryption
ABHA seals with RSA-OAEP over SHA-1. HPR seals with PKCS#1 v1.5, with a key from its own certificate endpoint. Ciphertext built the ABHA way cannot be opened by HPR, and HPR reports that as a wrong OTP rather than an encryption error.
- Updates
-
Updating one section
HPR re-queues whatever it receives as the whole record, so sending only the changed section blanks the rest.
- Identity
-
Trusting an HPR ID nobody confirmed
HPR refuses id lookups from some integrations. An operator can still keep a typed-in id, but the roster marks it unverified and records why, so check
verifiedbefore relying on it.
06Looking practitioners up
Not every doctor is enrolled through your software. For those who already
have an HPR ID: GET /v1/hpr/professionals/{hpr_id} for the
record, …/{hpr_id}/exists as the cheap check before
storing an id against anything, GET /v1/hpr/professionals
by name or state, and …/by-mobile/{mobile}, which can
return several registrations because one mobile may carry more than
one.
The forms themselves are built from HPR’s masters under
/v1/hpr/: systems of medicine, medical and nurse councils,
colleges and universities, categories, states and districts.
HPR’s state ids are not LGD codes, so do not reuse the lists built
for HFR integration.
07Keeping a facility’s roster in step
POST /v1/practitioners looks a
practitioner up in HPR by HPR ID or mobile and adds them with HPR’s
details. Several matches on a mobile are refused rather than guessed,
and a departed practitioner is deactivated rather than deleted.
Putting someone on a roster is a deliberate act, so a professional
filling in their own HPR record does not do it for you.
What the roster holds is refreshed from HPR’s answers instead of
drifting: the registration number and name at submit, and council,
speciality and verification on each status read — with
verified_at set only when HPR reports the council has
verified. For an EMR this is the list a clinician signs records from;
ABDM for EMR software covers the rest of that
workflow.
08HPR comes before HFR
The facility manager who registers a hospital in HFR signs in with HPR credentials, so a new facility’s first registry call is usually an HPR one. The portal walks through it: create the manager’s HPR ID through ABDM’s Aadhaar page, or sign an existing manager in, then fill in the facility. Registering hospitals is the portal’s job, so these sign-ins are not part of the API.
This connector groups HPR and HFR as M4, after ABHA, record sharing and consent in the milestone guide. Some ABDM material uses “M4” for NHCX claims instead, which is a separate programme. Every endpoint on this page is listed in the API overview, and what ABDM is explains where the registries sit in the network.
Enrol a practitioner in the sandbox
Sandbox keys are issued on signup. Create an HPR ID, file a professional record with a test certificate, and read its status back.
FAQ Common questions