ABDM v3 · M1–M4 implemented

FHIR R4 NRCeS profiles

FHIR R4 bundles to the NRCeS profiles ABDM validates

Every record that moves through ABDM is a FHIR R4 document bundle built to the profiles NRCeS publishes for India. Most hospital software stores medicines as “1-0-1” and test results as a name and a number. Send those as they are, and the connector builds, codes and validates the bundle.

01 Three ways in

Start from whatever your system already holds

Every route ends in the same place: a validated bundle attached to a care context, ready to be released when a patient consents.

Plain fields

What a data-entry operator types

PUT /v1/care-contexts/{id}/record takes medicines with dose and frequency, test names with values and units, complaints, diagnoses and vitals, for an OP consultation, a prescription or a lab report. The connector assembles the NRCeS-profiled bundle from them.

OPConsultation · Prescription · DiagnosticReport · coded where names match

A PDF

A scanned discharge paper or an outside report

Attach a PDF to a lab report or a consultation, or send it alone as a HealthDocumentRecord. It is placed where the profile expects it — embedded in the report, or filed as a document reference — and carried once, never twice.

Up to 10 MiB decoded · base64 or multipart

Your bundle

If you already build FHIR

PUT /v1/care-contexts/{id}/bundle accepts a bundle of your own for any of the eight HI types, and runs it through the same validation. Discharge summaries, immunisation, wellness and invoice records go in this way.

All eight HI types · rejected here, where you can fix it

02 From fields to FHIR

A lab report, as the LIS already has it

The request is the report as a technician would read it off the screen. The response says what was coded, and how.

  1. Create the care context

    POST /v1/care-contexts with hi_type DiagnosticReport. The record’s type must match it, or the call is refused with hi_type_mismatch.

  2. Send the fields

    Values like 11.2 or <0.5 become quantities; “Positive” stays text. Recognised units are UCUM-coded; anything else is kept as typed.

  3. Read the coding report

    coding lists every item: caller if you sent the code, master if the connector matched it, none if it went as text. Enough for “4 of 5 tests coded” on your screen.

  4. Resend to correct it

    A second PUT replaces the attached record, so a retry or a corrected report is safe.

record from plain fields Sandbox
PUT /v1/care-contexts/9b0e…/record
{
  "hi_type": "DiagnosticReport",
  "practitioner": {
    "hpr_id": "meera.nair@hpr.abdm",
    "name": "Dr Meera Nair"
  },
  "report_name": "Complete blood count",
  "tests": [
    {
      "name": "Hb",
      "value": 11.2,
      "unit": "g/dL",
      "reference_range": "13-17",
      "interpretation": "low"
    },
    {
      "name": "Peripheral smear",
      "value": "Normocytic normochromic"
    }
  ],
  "conclusion": "Mild anaemia.",
  "pdf": {
    "data": "JVBERi0xLjcK…"
  }
}

← 200 OK
{
  "care_context": {
    "hi_type": "DiagnosticReport",
    …
  },
  "coding": [
    {
      "field": "tests[0]",
      "source": "master",
      "system": "http://loinc.org",
      "code": "718-7"
    },
    {
      "field": "tests[1]",
      "source": "none",
      "code": null
    }
  ]
}

03 Health information types

Eight record types, and the code that says which

The Composition at the head of the bundle declares what the record is with a SNOMED CT code. It has to agree with the HI type the care context was created with; a mismatch is one of the things ABDM rejects on.

HI type Composition code SNOMED CT display From plain fields
OPConsultation371530004Clinical consultation reportYes
Prescription440545006Prescription recordYes
DiagnosticReport721981007Diagnostic studies reportYes, lab
HealthDocumentRecord419891008Record artifactYes, a PDF
DischargeSummary373942005Discharge summaryFull bundle
ImmunizationRecord41000179103Immunization recordFull bundle
WellnessRecord419891008Record artifactFull bundle
Invoice—None: text “Invoice Record”Full bundle

Invoice is the trap. The NRCeS InvoiceRecord profile has no SNOMED CT type code, and code tables that give it 721981007 are borrowing the diagnostic studies report code. The connector sends the type as text.

04 Validation

Rejected here, not by ABDM weeks later

A bundle that fails at the gateway fails when a clinician somewhere is waiting for it. Every bundle — built by the connector or uploaded by you — is checked for what ABDM actually rejects before it is stored.

Structure

A document, in the right order

A Composition must exist and be the first entry, the bundle must declare its profile in meta.profile, and the Composition’s code must agree with the declared HI type.

References

Nothing points at nothing

Every reference inside the bundle has to resolve to an entry in it, and the subject has to resolve to a patient. A dangling reference is the most common way a hand-built bundle fails.

Fields

Refused, never silently dropped

A field that belongs to another record type is an error, not ignored. A prescriber is required whenever medications or investigations are sent, because NRCeS makes it mandatory. Implausible vitals are refused — which catches a weight in grams or a temperature typed into the pulse box.

PDF

Actually a PDF, and all of it

The bytes must start with %PDF- and end with a %%EOF trailer. That catches a renamed JPEG and an upload truncated in transit, and returns invalid_pdf with the reason.

Errors name the field. Every refusal uses one shape, {"error": {"code", "message", "details"}}, and details says which field is wrong — including the ones that belong to a different record type.

05How codes are assigned

Coded data is better for the patient’s next clinician, but a wrong code is worse than none. So coding runs in a fixed order. A code you send always wins, provided it is from a system that item’s NRCeS profile allows. Otherwise the typed name is matched against the connector’s verified master, ignoring case, dots and spacing — so S. Creatinine, SGPT and F.B.S. all match. There is no fuzzy matching. Anything left over travels as text, which is valid FHIR.

Some names are left uncoded on purpose. “Sugar”, “albumin” and “protein” also name urine tests, so the operator has to pick the specific entry. For an operator dropdown, GET /v1/terminology/lab-tests?q=hb and GET /v1/terminology/diagnoses?q=fever search the same master the matcher uses. Each code in it was checked against the HL7 terminology server and a second source.

06Prescriptions and consultations

A prescription’s dose, frequency and duration are kept word for word, and the common forms are also structured so a PHR app can render them: OD, BD, TDS, 1-0-1, HS, SOS; “5 days” or a bare 5; “500 mg” or “1 tablet”. Nobody has to retype a prescription into a structured form for it to be shared.

An OP consultation is laid out in the sections the NRCeS OPConsultRecord profile defines — complaints, vitals, diagnoses, medications, investigations advised, notes, follow-up and an attached document — each as the resource type the profile expects. A follow-up can be a date or “in 7 days”, since the profile requires a date.

07After the bundle is built

The validated bundle is encrypted at rest and attached to its care context. It goes nowhere until the patient links that care context and consents to share it; then only the bundles the consent covers are selected, encrypted with Fidelius for the one requester and pushed. That half is the HIP integration. For a laboratory the whole of it is usually one call per report — see ABDM for labs — and the complete surface is on the ABDM API page.

Build your first bundle from a lab report

Sandbox credentials are issued on signup. Send one report as plain fields and see which tests come back coded.

FAQ Common questions

Frequently asked questions

Which FHIR version does ABDM use?
FHIR R4. Records are exchanged as FHIR document bundles conforming to the profiles NRCeS publishes for India, with a Composition as the first entry that says what kind of record the bundle is.
What are the ABDM health information types?
OPConsultation, Prescription, DiagnosticReport, DischargeSummary, ImmunizationRecord, HealthDocumentRecord, WellnessRecord and Invoice. Each maps to its own NRCeS profile and, apart from Invoice, to a SNOMED CT code on the Composition.
Do we need SNOMED CT and LOINC codes for ABDM?
Coded data is better, but not a precondition. Test and condition names that match the connector's verified master are coded automatically; others travel as text, which is valid FHIR. A code you send yourself always wins.
Can we share a PDF report through ABDM?
Yes. A PDF can be attached to a diagnostic report or a consultation, or sent on its own as a HealthDocumentRecord. It is checked to be a real PDF before it is bundled.