> ## Documentation Index
> Fetch the complete documentation index at: https://developer.eka.care/llms.txt
> Use this file to discover all available pages before exploring further.

# Receive and decrypt records as a HIU

> Take the encrypted FHIR records a HIP pushes after consent, decrypt them, and report which ones you could read.

## In short

* Acknowledge `abha.hiu_data_push` within 5 seconds, then decrypt.
* Decrypt each entry with your stored `private_key` and `nonce`.
* Report each entry's result with Push FHIR parsing status.
* If Eka stores the data for you, read the records from the records product instead.

## When to use this

The patient has granted a consent you raised in [Request a patient's consent as a HIU](https://developer.eka.care/docs/hie-cm/workflows/hiu-request-consent.md), and you manage the data on your side. Each HIP encrypts the approved records with your public keyset and Eka delivers them to you on a webhook. This workflow decrypts them and tells Eka which care contexts you could parse.

If Eka stores the data for you, nothing arrives on a webhook. Read each approved care context with [Retrieve Health Records](https://developer.eka.care/api-sdk/health-records/retrieve-health-records.md) in the records product, passing the `care_context_id` from Consent Details as the identifier. That call belongs to the records product and is documented there.

## Before you start

* A bearer token for the API. See [Authorization](https://developer.eka.care/api-sdk/auth/getting-started.md).
* Your public keyset registered, and the matching `private_key` and `nonce` stored on your side. See the keyset steps in [Request a patient's consent as a HIU](https://developer.eka.care/docs/hie-cm/workflows/hiu-request-consent.md).
* A granted consent, with its `consent_id` and the approved `care_contexts[].id`.
* A webhook endpoint registered with Eka that verifies the `Eka-Webhook-Signature` header. See [Webhook signature](https://developer.eka.care/docs/webhooks/webhook-signature.md).
* A way to decrypt: either the [Ecdh decrypt](https://developer.eka.care/api-sdk/hie-cm/care-contexts/ecdh/decrypt.md) call, or the [abdm-ecdh library](https://developer.eka.care/docs/hie-cm/care-contexts/ecdh-encryption.md) in Go, Python or Java.

## Sequence

```mermaid theme={null}
sequenceDiagram
  participant HIP
  participant Eka
  participant App as Your app
  HIP->>Eka: encrypted records for the consent
  Eka-->>App: webhook abha.hiu_data_push
  App-->>Eka: 200 within 5 seconds
  App->>Eka: POST /abdm/v1/ecdh/decrypt
  App->>Eka: POST /abdm/v1/hiu/care-context/data/on-push
```

## Steps

**1. Receive the push and acknowledge it**

Eka sends [`abha.hiu_data_push`](https://developer.eka.care/docs/hie-cm/webhooks/hiu-data-push) when a HIP pushes records for your consent. Verify the signature and reply `200` within 5 seconds; Eka retries on any other status. Decrypt after you reply, so the 5 seconds are not spent on decryption.

From `data`, keep:

* `consent_id` and `transaction_id`: you send both back in the acknowledge step. The webhook carries a top-level `transaction_id` and a `data.transaction_id`; which of the two fields on-push expects is not yet confirmed.

- `entries`: one per care context, each with `care_context_id`, `content` (the encrypted FHIR bundle), `checksum` and `media` (`application/fhir+json`).
- `key_information`: the sender's key material, with `dh_public_key.key_value` and `nonce`.
- `hip_id`, `abha_address` and `oid`: which HIP and which patient the records belong to.

Match `consent_id` against the consents you raised.

**2. Decrypt each entry**

Call [Ecdh decrypt](https://developer.eka.care/api-sdk/hie-cm/care-contexts/ecdh/decrypt.md) once per entry, or decrypt locally with the [abdm-ecdh library](https://developer.eka.care/docs/hie-cm/care-contexts/ecdh-encryption.md). Map the fields like this:

| Decrypt field | Value |
| - | - |
| `encrypted_data` | `entries[].content` |
| `sender_public_key` | `key_information.dh_public_key.key_value` |
| `sender_nonce` | `key_information.nonce` |
| `receiver_private_key` | your stored `private_key` |
| `receiver_nonce` | your stored `nonce` |

`key_information.dh_public_key` is the HIP's (sender's) public key; your own key is the private key you registered with your keyset.

The response carries `decrypted_data`, the FHIR bundle as plain text. Hash the decrypted bundle and compare the result with `entries[].checksum`: the checksum is computed over the plain-text FHIR data, not the encrypted content. Parse the bundle as JSON.

**3. Report the parsing status**

Call [Push FHIR parsing status](https://developer.eka.care/api-sdk/hie-cm/care-contexts/data-on-push.md) with:

* `consent_id`.
* The `transaction_id` from the webhook. Which of the two fields is not yet confirmed.
* One `status_response` item per entry, with `care_context_id`, `success` (`true` if you decrypted and parsed it), and a `description` when it failed.

Eka returns `202 Accepted`.

## State you must persist

| Field | From | Keep | For |
| - | - | - | - |
| `consent_id` | `abha.hiu_data_push` | As long as you keep the records | The on-push call; tying records to the consent for audit |
| `transaction_id` (which of the two fields is not yet confirmed) | `abha.hiu_data_push` | Until on-push returns `202` | The on-push call |
| `care_context_id` | each entry | As long as you keep the record | On-push status; matching the record to the consent |
| Decrypted FHIR bundle | Ecdh decrypt | Until the consent expires or is revoked | Showing the record to your users |
| `hip_id` | `abha.hiu_data_push` | With the record | Knowing which facility a record came from |

## When it fails

> [!WARNING]
>
> Which of these codes each call returns is not yet confirmed. The codes come from the [errors page](https://developer.eka.care/docs/hie-cm/errors.md), matched by meaning. Log the code you actually receive.

Error responses carry `code`, `error` and `source_error` (`code`, `message`). Codes are listed on the [errors page](https://developer.eka.care/docs/hie-cm/errors.md).

| Situation | Code | Do |
| - | - | - |
| Your endpoint does not reply `200` within 5 seconds | none | Eka retries; reply first, decrypt after |
| Decryption fails | none from Eka if you use the library | Check you used the private key and nonce registered at the time of the consent; report the entry with `success` `false` |
| Ecdh decrypt rejects the body | `ABDM-1006`, `ABDM-1010` | Check every field is the Base64 value from the webhook or your store |
| Consent artefact expired | `ABDM-1061` | Do not use the records; raise a new consent |
| Transaction not recognised on on-push | `ABDM-1017`, `ABDM-1052` | Send the `transaction_id` from the same webhook; which of the two fields is not yet confirmed |
| HIP unavailable or no acknowledgement from the HIP | `ABDM-1401`, `ABDM-1402` | No records arrive from that HIP |
| No webhook arrives after the consent is granted | none | Check your keyset is registered and your webhook endpoint is reachable; check whether Eka stores the data for you |

## Test it

The [testing page](https://developer.eka.care/docs/hie-cm/testing.md) has the sandbox base URL, credentials and the happy path for every journey.

Sandbox base URL: `https://api.dev.eka.care`.&#x20;

* [ ] Run [Request a patient's consent as a HIU](https://developer.eka.care/docs/hie-cm/workflows/hiu-request-consent.md) to a granted consent
* [ ] `abha.hiu_data_push` arrives; your endpoint replies `200` within 5 seconds
* [ ] Each entry decrypts to a FHIR bundle with Ecdh decrypt and with the abdm-ecdh library, and both give the same result
* [ ] On-push with every entry `success` `true` returns `202`
* [ ] Decrypt with a wrong private key; report that entry with `success` `false`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.