National Health AuthorityNHA Docs

Command Palette

Search for a command to run...

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

AreaHIU responsibility
Consent requestSend the purpose, HI types, date range, and data erase date to HIE-CM.
Patient decisionWait while the patient approves or denies the request in a PHR app.
Consent artefactFetch and store the signed consent artefact after a grant.
Health data requestSend the consent ID, a data range, a data push URL, and ECDH key material.
Data receiptReceive encrypted FHIR data, decrypt it, and show it to the doctor.
Patient rightsStop 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.

ViewShow these fields
Consent RequestsPatient name, ABHA address, date range, data erase date, HI types, and status.
Granted RequestsConsent request ID, consent artefact ID, purpose, date range, and grant time.
Documents ViewFHIR 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.

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.

CodeDisplayUse it when
CAREMGTCare ManagementA doctor needs records for care.
BTGBreak the GlassEmergency access requires urgent care.
PUBHLTHPublic HealthA public health program needs records.
HPAYMTHealthcare PaymentA payment or claim flow needs records.
DSRCHDisease Specific Healthcare ResearchApproved research needs disease data.
PATRQTSelf-RequestedThe patient asks for their own data.

HI types state what record classes the HIU requests.

CodeDisplay
PrescriptionPrescription
DiagnosticReportDiagnostic Report
OPConsultationOP Consultation
DischargeSummaryDischarge Summary
ImmunizationRecordImmunization Record
HealthDocumentRecordRecord artefact
WellnessRecordWellness 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.

FieldMeaningExample
purpose.codeWhy the HIU needs data.CAREMGT
patient.idPatient ABHA address.patient@sbx
hiu.idHIU service or facility ID.IN0810041289
requesterDoctor or user who asks for data.Doctor name and identifier.
hiTypesRecord types requested.Prescription, DiagnosticReport
permission.accessModeAccess mode for data.VIEW or STORE
permission.dateRangeClinical record date range.2026-05-24 to 2026-06-23
permission.dataEraseAtLatest time to erase data.2026-06-30T10:43:00Z
permission.frequencyAllowed repeat access.1 time per hour, 0 repeats.

Status values

StatusHIU action
REQUESTEDKeep the request pending.
GRANTEDFetch each consent artefact.
DENIEDStop the flow and show the denial.
EXPIREDStop the flow and ask for new consent.
REVOKEDStop access and erase stored data.

Send the consent request to the HIE-CM sandbox base URL. Use https://dev.abdm.gov.in/api/hiecm/ for sandbox HIE-CM calls.

POST/consent/v3/request/init

Initiate a consent request for the patient's ABHA address.

Request
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
        }
      }
    }
  }'
Response (202)
{
  "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.

POST{hiuBridgeUrl}/api/v3/hiu/consent/request/on-init

Receive the consent request ID from HIE-CM.

Callback example
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"
    }
  }'
Your response (202)
{
  "acknowledgement": {
    "status": "OK"
  }
}

Step 3 — Check request status when needed

Poll status only when your UI needs a refresh. Prefer callbacks for state changes.

POST/consent/v3/request/status

Check the status of one consent request.

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"
  }'
Response (200)
{
  "consentRequest": {
    "id": "req-uuid-001",
    "status": "REQUESTED"
  }
}

HIE-CM can also send an on-status callback after a status check.

POST{hiuBridgeUrl}/api/v3/hiu/consent/request/on-status

Receive the status check callback from HIE-CM.

Callback example
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.

Corrected bridge URL
POST {hiuBridgeUrl}/v0.5/consents/hiu/notify
POST{hiuBridgeUrl}/v0.5/consents/hiu/notify

Receive consent grant, denial, or revocation status.

CallbackReceiverPurpose
{hiuBridgeUrl}/v0.5/consents/hiu/notifyHIUGet grant, denial, or revocation status.
{hipBridgeUrl}/v0.5/consents/hip/notifyHIPGet the consent detail and approved care contexts.
Callback example: grant
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"
        }
      ]
    }
  }'
Callback example: denial
{
  "notification": {
    "consentRequestId": "req-uuid-001",
    "status": "DENIED"
  }
}
Callback example: revocation
{
  "notification": {
    "consentRequestId": "req-uuid-001",
    "status": "REVOKED",
    "consentArtefacts": [
      {
        "id": "consent-art-uuid-001"
      }
    ]
  }
}
HIP notification example
{
  "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.

POST/consent/v3/request/hiu/on-notify

Tell HIE-CM that your HIU received the consent notification.

Request
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"
    }
  }'
Response (202)
{
  "acknowledgement": {
    "status": "OK"
  }
}

Fetch each consent artefact after a GRANTED notification. Store the artefact securely. You need it for the health data request.

POST/consent/v3/fetch

Fetch a full consent artefact by consent ID.

Request
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"
  }'
Response (200)
{
  "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.

POST/data-flow/v3/health-information/request

Request encrypted FHIR data for one consent artefact.

Request
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"
      }
    }
  }'
Response (202)
{
  "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.

POST{hiuBridgeUrl}/api/v3/hiu/health-information/on-request

Receive the HIE-CM acknowledgement for the data request.

Callback example
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"
    }
  }'
Your response (202)
{
  "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.

POST{dataPushUrl}

Receive encrypted FHIR bundles from the HIP.

Callback example
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"
    }
  }'
Your response (202)
{
  "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.

POST/data-flow/v3/health-information/notify

Notify HIE-CM that your HIU received the data.

Request
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"
          }
        ]
      }
    }
  }'
Response (202)
{
  "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.

Corrected HIP bridge URL
POST {hipBridgeUrl}/v0.5/health-information/hip/request

Data decryption at the HIU

Decrypt data only on your backend. Never expose the HIU private key to a browser.

  1. Read the HIP keyMaterial from the data push call.
  2. Use the stored HIU private key for the same transactionId.
  3. Derive the shared secret with ECDH on Curve25519.
  4. Derive the AES key with the HIU nonce and HIP nonce.
  5. Decrypt each encrypted FHIR entry.
  6. Validate the checksum before you store data.
  7. Parse the FHIR bundle and render it for the doctor.
  8. Send the TRANSFERRED notification 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.

Patient control is part of Milestone 3. The patient can grant, deny, or revoke consent. The patient can also let consent expire.

EventSourceHIU action
DenialDENIED notificationMark the request denied and request no data.
ExpirydataEraseAt or EXPIRED statusStop access and erase data by the erase time.
RevocationREVOKED notificationStop access at once and erase stored data.
Grant with narrower scopeConsent artefactUse 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.

ScenarioExpected result
Consent grantThe patient approves in PHR, and the HIU fetches the consent artefact.
Consent denialThe HIU stops the flow and shows a denied status.
Consent revocationThe HIU stops access and erases stored data.
Data requestThe HIU sends ECDH key material and gets a transaction ID.
Data receiptThe HIU receives encrypted FHIR pages at the data push URL.
Data decryptionThe doctor console shows readable FHIR records.
Data eraseThe HIU deletes data at dataEraseAt.
Multi-page dataThe HIU handles all pages without duplicates.

Sources

  • ABDM Proposed Simplified Milestone 3 (DOCX→MD, 2026-08)