Milestone 3 — HIU
Request patient consent, fetch the consent artefact, and receive encrypted health data as an HIU.
Milestone 3 makes your system a Health Information User (HIU).
Your HIU asks for patient consent by ABHA address. It receives a consent artefact after the patient approves the request. It then requests health data from one or more HIP systems.
Overview
What you build
| Area | HIU responsibility |
|---|---|
| Consent request | Send the purpose, HI types, date range, and data erase date to HIE-CM. |
| Patient decision | Wait while the patient approves or denies the request in a PHR app. |
| Consent artefact | Fetch and store the signed consent artefact after a grant. |
| Health data request | Send the consent ID, a data range, a data push URL, and ECDH key material. |
| Data receipt | Receive encrypted FHIR data, decrypt it, and show it to the doctor. |
| Patient rights | Stop access after expiry, denial, or revocation. |
Prerequisites
- Create a gateway session token first. See Authentication.
- Understand the consent artefact model first. See Consent Framework.
- Prepare ECDH key material and data decryption logic. See Data Encryption.
- Register a public HTTPS bridge URL for callbacks.
- Store the ABHA address after patient registration or QR flow.
OCR source caveat
The archived source includes OCR text from screenshots.
Some JSON keys and paths contain OCR errors.
This guide fixes clear errors, such as txnld to txnId.
Verify every payload against the sandbox Swagger before certification.
Doctor console features
Show 3 console views for a reviewer.
| View | Show these fields |
|---|---|
| Consent Requests | Patient name, ABHA address, date range, data erase date, HI types, and status. |
| Granted Requests | Consent request ID, consent artefact ID, purpose, date range, and grant time. |
| Documents View | FHIR document title, patient data, practitioner, facility, encounter date, and HI type. |
Show live status events.
Use terms such as Consent request initiated, Acknowledgement received, and Data request accepted.
Consent request workflow
The HIU starts the consent flow. HIE-CM sends the request to the patient's PHR app. The patient grants, denies, or later revokes consent.
sequenceDiagram
autonumber
participant Doctor as Doctor console
participant HIU as HIU backend
participant HIECM as HIE-CM
participant PHR as Patient PHR app
participant HIP as HIP bridge
Doctor->>HIU: Select ABHA, purpose, HI types, and dates
HIU->>HIECM: POST /consent/v3/request/init
HIECM-->>HIU: 202 Accepted and on-init callback
HIECM->>PHR: Show consent request
PHR->>HIECM: Grant or deny consent
HIECM-->>HIU: POST {hiuBridgeUrl}/v0.5/consents/hiu/notify
HIECM-->>HIP: POST {hipBridgeUrl}/v0.5/consents/hip/notify
HIU->>HIECM: POST /consent/v3/request/hiu/on-notify
HIU->>HIECM: POST /consent/v3/fetch
HIECM-->>HIU: Full consent artefact
Meta codes
Purpose codes state why the HIU needs data. The source lists this subset from HL7 PurposeOfUse.
| Code | Display | Use it when |
|---|---|---|
CAREMGT | Care Management | A doctor needs records for care. |
BTG | Break the Glass | Emergency access requires urgent care. |
PUBHLTH | Public Health | A public health program needs records. |
HPAYMT | Healthcare Payment | A payment or claim flow needs records. |
DSRCH | Disease Specific Healthcare Research | Approved research needs disease data. |
PATRQT | Self-Requested | The patient asks for their own data. |
HI types state what record classes the HIU requests.
| Code | Display |
|---|---|
Prescription | Prescription |
DiagnosticReport | Diagnostic Report |
OPConsultation | OP Consultation |
DischargeSummary | Discharge Summary |
ImmunizationRecord | Immunization Record |
HealthDocumentRecord | Record artefact |
WellnessRecord | Wellness Record |
Invoice HI type
The source table omits Invoice.
Its screen examples show it in the HI type selector.
Confirm your enabled HI types in the sandbox before a demo.
Consent detail fields
| Field | Meaning | Example |
|---|---|---|
purpose.code | Why the HIU needs data. | CAREMGT |
patient.id | Patient ABHA address. | patient@sbx |
hiu.id | HIU service or facility ID. | IN0810041289 |
requester | Doctor or user who asks for data. | Doctor name and identifier. |
hiTypes | Record types requested. | Prescription, DiagnosticReport |
permission.accessMode | Access mode for data. | VIEW or STORE |
permission.dateRange | Clinical record date range. | 2026-05-24 to 2026-06-23 |
permission.dataEraseAt | Latest time to erase data. | 2026-06-30T10:43:00Z |
permission.frequency | Allowed repeat access. | 1 time per hour, 0 repeats. |
Status values
| Status | HIU action |
|---|---|
REQUESTED | Keep the request pending. |
GRANTED | Fetch each consent artefact. |
DENIED | Stop the flow and show the denial. |
EXPIRED | Stop the flow and ask for new consent. |
REVOKED | Stop access and erase stored data. |
Step 1 — Initiate the consent request
Send the consent request to the HIE-CM sandbox base URL.
Use https://dev.abdm.gov.in/api/hiecm/ for sandbox HIE-CM calls.
/consent/v3/request/initInitiate a consent request for the patient's ABHA address.
curl -X POST "https://dev.abdm.gov.in/api/hiecm/consent/v3/request/init" \
-H "Authorization: Bearer <your-access-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: $(uuidgen | tr 'A-Z' 'a-z')" \
-H "TIMESTAMP: $(date -u +%Y-%m-%dT%H:%M:%S.000Z)" \
-H "X-CM-ID: sbx" \
-d '{
"consent": {
"purpose": {
"text": "Care Management",
"code": "CAREMGT",
"refUri": "http://terminology.hl7.org/CodeSystem/v3-ActReason"
},
"patient": {
"id": "patient@sbx"
},
"hiu": {
"id": "IN0810041289",
"name": "Demo HIU Hospital"
},
"requester": {
"name": "Dr ANKIT GUPTA",
"identifier": {
"type": "REGNO",
"value": "doctor-registration-number",
"system": "https://www.nmc.org.in"
}
},
"hiTypes": [
"Prescription",
"DiagnosticReport",
"OPConsultation"
],
"permission": {
"accessMode": "VIEW",
"dateRange": {
"from": "2026-05-24T00:00:00.000Z",
"to": "2026-06-23T23:59:59.999Z"
},
"dataEraseAt": "2026-06-30T10:43:00.000Z",
"frequency": {
"unit": "HOUR",
"value": 1,
"repeats": 0
}
}
}
}'{
"consentRequestId": "req-uuid-001"
}Consent init response shape
The source screenshot shows a 202 Accepted response with consentRequestId.
Some ABDM flows return only 202 and send the ID in on-init.
Implement both paths.
Step 2 — Receive the on-init callback
Store the consent request ID.
Correlate it with your original REQUEST-ID.
{hiuBridgeUrl}/api/v3/hiu/consent/request/on-initReceive the consent request ID from HIE-CM.
curl -X POST "https://your-hiu.example.com/api/v3/hiu/consent/request/on-init" \
-H "Authorization: Bearer <gateway-callback-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: callback-request-id-001" \
-H "TIMESTAMP: 2026-06-23T10:43:28.000Z" \
-H "X-HIU-ID: IN0810041289" \
-d '{
"consentRequest": {
"id": "req-uuid-001"
},
"resp": {
"requestId": "original-request-id"
}
}'{
"acknowledgement": {
"status": "OK"
}
}Step 3 — Check request status when needed
Poll status only when your UI needs a refresh. Prefer callbacks for state changes.
/consent/v3/request/statusCheck the status of one consent request.
curl -X POST "https://dev.abdm.gov.in/api/hiecm/consent/v3/request/status" \
-H "Authorization: Bearer <your-access-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: $(uuidgen | tr 'A-Z' 'a-z')" \
-H "TIMESTAMP: $(date -u +%Y-%m-%dT%H:%M:%S.000Z)" \
-H "X-CM-ID: sbx" \
-d '{
"consentRequestId": "req-uuid-001"
}'{
"consentRequest": {
"id": "req-uuid-001",
"status": "REQUESTED"
}
}HIE-CM can also send an on-status callback after a status check.
{hiuBridgeUrl}/api/v3/hiu/consent/request/on-statusReceive the status check callback from HIE-CM.
curl -X POST "https://your-hiu.example.com/api/v3/hiu/consent/request/on-status" \
-H "Authorization: Bearer <gateway-callback-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: callback-request-id-status-001" \
-H "TIMESTAMP: 2026-06-23T10:44:00.000Z" \
-H "X-HIU-ID: IN0810041289" \
-d '{
"consentRequest": {
"id": "req-uuid-001",
"status": "REQUESTED"
},
"resp": {
"requestId": "status-request-id"
}
}'Step 4 — Receive the patient decision
The patient opens the request in a PHR app. The patient can grant, deny, or later revoke consent.
Use this bridge callback path for the HIU notification.
POST {hiuBridgeUrl}/v0.5/consents/hiu/notify{hiuBridgeUrl}/v0.5/consents/hiu/notifyReceive consent grant, denial, or revocation status.
| Callback | Receiver | Purpose |
|---|---|---|
{hiuBridgeUrl}/v0.5/consents/hiu/notify | HIU | Get grant, denial, or revocation status. |
{hipBridgeUrl}/v0.5/consents/hip/notify | HIP | Get the consent detail and approved care contexts. |
curl -X POST "https://your-hiu.example.com/v0.5/consents/hiu/notify" \
-H "Authorization: Bearer <gateway-callback-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: callback-request-id-002" \
-H "TIMESTAMP: 2026-06-23T10:44:41.000Z" \
-H "X-HIU-ID: IN0810041289" \
-d '{
"notification": {
"consentRequestId": "req-uuid-001",
"status": "GRANTED",
"consentArtefacts": [
{
"id": "consent-art-uuid-001"
}
]
}
}'{
"notification": {
"consentRequestId": "req-uuid-001",
"status": "DENIED"
}
}{
"notification": {
"consentRequestId": "req-uuid-001",
"status": "REVOKED",
"consentArtefacts": [
{
"id": "consent-art-uuid-001"
}
]
}
}{
"notification": {
"status": "GRANTED",
"consentId": "consent-art-uuid-001",
"consentDetail": {
"schemaVersion": "v3",
"consentId": "consent-art-uuid-001",
"createdAt": "2026-06-23T10:44:19.694Z",
"patient": {
"id": "patient@sbx"
},
"careContexts": [
{
"patientReference": "170039",
"careContextReference": "170039-420-10-Jun-2026"
}
],
"hiu": {
"id": "IN0810041289"
},
"hip": {
"id": "IN27100025844"
}
}
}
}Bridge path conflict in source
The source shows both /api/v3/hiu/consent/request/notify and the corrected /v0.5/consents/hiu/notify bridge URL.
Register the corrected bridge URL and test it in sandbox.
Step 5 — Acknowledge the notification
Acknowledge each consent artefact ID to HIE-CM. Send this call after your bridge handler stores the callback.
/consent/v3/request/hiu/on-notifyTell HIE-CM that your HIU received the consent notification.
curl -X POST "https://dev.abdm.gov.in/api/hiecm/consent/v3/request/hiu/on-notify" \
-H "Authorization: Bearer <your-access-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: $(uuidgen | tr 'A-Z' 'a-z')" \
-H "TIMESTAMP: $(date -u +%Y-%m-%dT%H:%M:%S.000Z)" \
-H "X-CM-ID: sbx" \
-d '{
"acknowledgement": [
{
"status": "OK",
"consentId": "consent-art-uuid-001"
}
],
"response": {
"requestId": "callback-request-id-002"
}
}'{
"acknowledgement": {
"status": "OK"
}
}Step 6 — Fetch the consent artefact
Fetch each consent artefact after a GRANTED notification.
Store the artefact securely.
You need it for the health data request.
/consent/v3/fetchFetch a full consent artefact by consent ID.
curl -X POST "https://dev.abdm.gov.in/api/hiecm/consent/v3/fetch" \
-H "Authorization: Bearer <your-access-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: $(uuidgen | tr 'A-Z' 'a-z')" \
-H "TIMESTAMP: $(date -u +%Y-%m-%dT%H:%M:%S.000Z)" \
-H "X-CM-ID: sbx" \
-d '{
"consentId": "consent-art-uuid-001"
}'{
"consent": {
"status": "GRANTED",
"consentDetail": {
"schemaVersion": "v3",
"consentId": "consent-art-uuid-001",
"createdAt": "2026-06-23T10:44:19.694Z",
"patient": {
"id": "patient@sbx"
},
"careContexts": [
{
"patientReference": "170039",
"careContextReference": "170039-420-10-Jun-2026"
}
],
"purpose": {
"text": "Care Management",
"code": "CAREMGT",
"refUri": "http://terminology.hl7.org/CodeSystem/v3-ActReason"
},
"hiTypes": [
"Prescription",
"DiagnosticReport"
],
"permission": {
"accessMode": "VIEW",
"dateRange": {
"from": "2026-05-24T00:00:00.000Z",
"to": "2026-06-23T23:59:59.999Z"
},
"dataEraseAt": "2026-06-30T10:43:00.000Z",
"frequency": {
"unit": "HOUR",
"value": 1,
"repeats": 0
}
},
"hiu": {
"id": "IN0810041289",
"name": "Demo HIU Hospital"
},
"hip": {
"id": "IN27100025844",
"name": "Demo HIP Hospital"
}
},
"signature": "BASE64_DIGITAL_SIGNATURE"
}
}Fetch response shape
The source says fetch returns the full consent artefact.
It also lists an on-fetch callback.
Support a direct 200 response and an async callback.
Health information request
Start this flow only after the HIU holds a granted consent artefact.
Generate a fresh ECDH key pair for each health data request.
Expose a public HTTPS dataPushUrl before you call HIE-CM.
sequenceDiagram
autonumber
participant HIU as HIU backend
participant HIECM as HIE-CM
participant HIP as HIP bridge
participant Data as HIU dataPushUrl
HIU->>HIU: Generate ECDH key pair and nonce
HIU->>HIECM: POST /data-flow/v3/health-information/request
HIECM-->>HIU: on-request callback with transactionId
HIECM->>HIP: POST {hipBridgeUrl}/v0.5/health-information/hip/request
HIP-->>HIECM: ACKNOWLEDGED
HIP->>HIP: Fetch matching FHIR records
HIP->>HIP: Encrypt FHIR bundles with HIU public key
loop each data page
HIP-->>Data: POST encrypted entries and HIP keyMaterial
Data-->>HIP: 202 Accepted
end
HIU->>HIU: Decrypt and validate data
HIU->>HIECM: POST /data-flow/v3/health-information/notify
Step 1 — Request health information
Send the consent ID, date range, data push URL, and HIU public key. Keep the private key only on your server.
/data-flow/v3/health-information/requestRequest encrypted FHIR data for one consent artefact.
curl -X POST "https://dev.abdm.gov.in/api/hiecm/data-flow/v3/health-information/request" \
-H "Authorization: Bearer <your-access-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: $(uuidgen | tr 'A-Z' 'a-z')" \
-H "TIMESTAMP: $(date -u +%Y-%m-%dT%H:%M:%S.000Z)" \
-H "X-CM-ID: sbx" \
-d '{
"hiRequest": {
"consent": {
"id": "consent-art-uuid-001"
},
"dateRange": {
"from": "2026-05-24T00:00:00.000Z",
"to": "2026-06-23T23:59:59.999Z"
},
"dataPushUrl": "https://your-hiu.example.com/abdm/data/push",
"keyMaterial": {
"cryptoAlg": "ECDH",
"curve": "Curve25519",
"dhPublicKey": {
"expiry": "2026-06-23T11:00:00.000Z",
"parameters": "Curve25519/32byte random key",
"keyValue": "BASE64_HIU_ECDH_PUBLIC_KEY"
},
"nonce": "BASE64_32_BYTE_HIU_NONCE"
}
}
}'{
"transactionId": "txn-uuid-data-001"
}Key material names
OCR changed several keys in this payload.
Use cryptoAlg, dhPublicKey, and keyValue.
Confirm casing against the sandbox Swagger.
Step 2 — Receive the on-request callback
Store the transaction ID. Use it to match later data push calls.
{hiuBridgeUrl}/api/v3/hiu/health-information/on-requestReceive the HIE-CM acknowledgement for the data request.
curl -X POST "https://your-hiu.example.com/api/v3/hiu/health-information/on-request" \
-H "Authorization: Bearer <gateway-callback-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: callback-request-id-003" \
-H "TIMESTAMP: 2026-06-23T10:45:39.000Z" \
-H "X-HIU-ID: IN0810041289" \
-d '{
"hiRequest": {
"transactionId": "txn-uuid-data-001",
"status": "REQUESTED"
},
"resp": {
"requestId": "original-data-request-id"
}
}'{
"acknowledgement": {
"status": "OK"
}
}Step 3 — Receive encrypted data at the data push URL
The HIP pushes encrypted FHIR entries to your dataPushUrl.
Accept pages idempotently by transactionId and page data.
{dataPushUrl}Receive encrypted FHIR bundles from the HIP.
curl -X POST "https://your-hiu.example.com/abdm/data/push" \
-H "Authorization: Bearer <hip-callback-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: hip-push-request-id-001" \
-H "TIMESTAMP: 2026-06-23T10:46:12.000Z" \
-d '{
"transactionId": "txn-uuid-data-001",
"pageNumber": 0,
"pageCount": 1,
"entries": [
{
"content": "BASE64_ENCRYPTED_FHIR_JSON",
"media": "application/fhir+json",
"checksum": "sha256-BASE64_CHECKSUM",
"careContextReference": "170039-420-10-Jun-2026"
}
],
"keyMaterial": {
"cryptoAlg": "ECDH",
"curve": "Curve25519",
"dhPublicKey": {
"expiry": "2026-06-23T11:00:00.000Z",
"parameters": "Curve25519/32byte random key",
"keyValue": "BASE64_HIP_ECDH_PUBLIC_KEY"
},
"nonce": "BASE64_32_BYTE_HIP_NONCE"
}
}'{
"acknowledgement": {
"status": "OK"
}
}Data push payload
The source screenshot confirms transactionId, entries, encrypted content, and key material.
It does not give a clean schema for every field.
Match your HIP partner and sandbox Swagger before production.
Step 4 — Notify HIE-CM after data receipt
Send a transfer status after you receive all pages.
Use TRANSFERRED only after decryption and integrity checks pass.
/data-flow/v3/health-information/notifyNotify HIE-CM that your HIU received the data.
curl -X POST "https://dev.abdm.gov.in/api/hiecm/data-flow/v3/health-information/notify" \
-H "Authorization: Bearer <your-access-token>" \
-H "Content-Type: application/json" \
-H "REQUEST-ID: $(uuidgen | tr 'A-Z' 'a-z')" \
-H "TIMESTAMP: $(date -u +%Y-%m-%dT%H:%M:%S.000Z)" \
-H "X-CM-ID: sbx" \
-d '{
"notification": {
"consentId": "consent-art-uuid-001",
"transactionId": "txn-uuid-data-001",
"doneAt": "2026-06-23T10:46:30.000Z",
"notifier": {
"type": "HIU",
"id": "IN0810041289"
},
"statusNotification": {
"sessionStatus": "TRANSFERRED",
"hipId": "IN27100025844",
"statusResponses": [
{
"careContextReference": "170039-420-10-Jun-2026",
"hiStatus": "OK",
"description": "FHIR bundle received and decrypted"
}
]
}
}
}'{
"acknowledgement": {
"status": "OK"
}
}Failure status term
The source uses FAILED for HIU data receipt failure.
Some older notes use ERRORED.
Verify the accepted enum before certification.
HIP bridge URL for data request
HIE-CM forwards the data request to the HIP bridge. The source corrects this path.
POST {hipBridgeUrl}/v0.5/health-information/hip/requestData decryption at the HIU
Decrypt data only on your backend. Never expose the HIU private key to a browser.
- Read the HIP
keyMaterialfrom the data push call. - Use the stored HIU private key for the same
transactionId. - Derive the shared secret with ECDH on Curve25519.
- Derive the AES key with the HIU nonce and HIP nonce.
- Decrypt each encrypted FHIR entry.
- Validate the checksum before you store data.
- Parse the FHIR bundle and render it for the doctor.
- Send the
TRANSFERREDnotification only after all pages pass.
Use a tested crypto library
Do not hand-code the ECDH and AES-GCM flow. Use a tested ABDM or FIDELIUS-compatible library. See Data Encryption for the crypto reference.
Consent expiry and revocation
Patient control is part of Milestone 3. The patient can grant, deny, or revoke consent. The patient can also let consent expire.
| Event | Source | HIU action |
|---|---|---|
| Denial | DENIED notification | Mark the request denied and request no data. |
| Expiry | dataEraseAt or EXPIRED status | Stop access and erase data by the erase time. |
| Revocation | REVOKED notification | Stop access at once and erase stored data. |
| Grant with narrower scope | Consent artefact | Use only approved care contexts and HI types. |
Create a scheduled job for dataEraseAt.
Run it even if no callback arrives.
Treat a revocation callback as urgent.
Record an audit log for every data access and erasure.
Certification scenarios
Test these scenarios before your Milestone 3 review.
| Scenario | Expected result |
|---|---|
| Consent grant | The patient approves in PHR, and the HIU fetches the consent artefact. |
| Consent denial | The HIU stops the flow and shows a denied status. |
| Consent revocation | The HIU stops access and erases stored data. |
| Data request | The HIU sends ECDH key material and gets a transaction ID. |
| Data receipt | The HIU receives encrypted FHIR pages at the data push URL. |
| Data decryption | The doctor console shows readable FHIR records. |
| Data erase | The HIU deletes data at dataEraseAt. |
| Multi-page data | The HIU handles all pages without duplicates. |
Sources
- ABDM Proposed Simplified Milestone 3 (DOCX→MD, 2026-08)
