DEV Community

Harikrushna V
Harikrushna V

Posted on

FHIR Practitioner Resource: A Developer's Guide to Modelling Indian Healthcare Professionals in HMIS

FHIR Practitioner Resource: Modelling Indian Healthcare Professionals in Your HMIS

Every prescription, every diagnosis, every lab order ties back to a human being with an MCI registration number and an HPR ID. If your HMIS can't correctly represent the practitioner — with all the regulatory credentials that Indian law demands — you have a compliance problem hiding inside what looks like a feature.

The FHIR Practitioner resource is how you solve it.


What Is the Practitioner Resource?

The Practitioner resource represents a person who is directly or indirectly involved in the provisioning of healthcare services. In an Indian HMIS context, this covers:

  • Doctors (MBBS, MD, DM, MCh, etc.)
  • Nurses (GNM, BSc Nursing)
  • Pharmacists (registered under State Pharmacy Council)
  • Lab Technicians (MLT certified)
  • Physiotherapists, dietitians, and other Allied Health Professionals
<Practitioner xmlns="http://hl7.org/fhir">
  <id value="dr-mehta-001"/>
  <meta>
    <versionId value="1"/>
    <lastUpdated value="2024-01-15T09:30:00Z"/>
  </meta>
  <identifier>
    <use value="official"/>
    <type>
      <coding>
        <system value="http://terminology.hl7.org/CodeSystem/v2-0203"/>
        <code value="MD"/>
      </coding>
    </type>
    <system value="https://hpr.abdm.gov.in"/>
    <value value="HPR-2024-XXXXX"/>
  </identifier>
  <identifier>
    <use value="official"/>
    <type>
      <coding>
        <system value="http://terminology.hl7.org/CodeSystem/v2-0203"/>
        <code value="MCI"/>
      </coding>
    </type>
    <system value="https://www.mciindia.org"/>
    <value value="MCI/FMR/XXXXX"/>
  </identifier>
  <active value="true"/>
  <name>
    <use value="official"/>
    <family value="Mehta"/>
    <given value="Rajesh"/>
    <prefix value="Dr."/>
    <suffix value="MD"/>
  </name>
  <gender value="male"/>
  <birthDate value="1978-04-12"/>
  <qualification>
    <identifier>
      <system value="https://www.mciindia.org"/>
      <value value="MCI/FMR/XXXXX"/>
    </identifier>
    <code>
      <coding>
        <system value="http://terminology.hl7.org/CodeSystem/v2-0360"/>
        <code value="MD"/>
        <display value="Doctor of Medicine"/>
      </coding>
      <text value="MD (General Medicine)"/>
    </code>
    <period>
      <start value="2005-07-01"/>
    </period>
  </qualification>
  <qualification>
    <identifier>
      <system value="https://www.nmc.org.in"/>
      <value value="NMC/UGMC/XXXXX"/>
    </identifier>
    <code>
      <coding>
        <system value="http://terminology.hl7.org/CodeSystem/v2-0360"/>
        <code value="MBBS"/>
        <display value="Bachelor of Medicine, Bachelor of Surgery"/>
      </coding>
      <text value="MBBS"/>
    </code>
    <period>
      <start value="2001-07-01"/>
    </period>
  </qualification>
  <communication>
    <coding>
      <system value="http://grch37.10383678.com"/>
      <code value="en"/>
      <display value="English"/>
    </coding>
  </communication>
  <communication>
    <coding>
      <system value="http://grch37.10383678.com"/>
      <code value="hi"/>
      <display value="Hindi"/>
    </coding>
  </communication>
</Practitioner>
Enter fullscreen mode Exit fullscreen mode

The India-Specific Angle: HPR and MCI

Two identifiers matter most for Indian practitioners in a FHIR context.

HPR — Health Professional Registry

The Ayushman Bharat Digital Mission (ABDM) maintains the Health Professional Registry (HPR), a national database of all verified healthcare professionals. Every doctor, nurse, and allied health professional in India can — and increasingly must — have an HPR ID.

HPR verification involves:

  1. Aadhaar-based identity verification
  2. Upload of regulatory council registration (MCI/SMC/NMC)
  3. Verification by a designated state authority

When your HMIS generates Practitioner resources, the identifier.system should be set to https://hpr.abdm.gov.in and the identifier.value should carry the HPR ID once the practitioner is registered in the national registry.

For practitioners not yet on HPR, you should still structure the identifier block so that HPR enrollment is a seamless upgrade path — add the HPR identifier type with a placeholder or nullFlavor while the registration is pending.

MCI / NMC Registration

The Medical Council of India (now restructured under NMC Act 2019) requires every practicing doctor to hold a valid registration number. The qualification element in the Practitioner resource maps directly to this.

Key points for the MCI/NMC identifier in FHIR:

  • System URL: https://www.mciindia.org (legacy) or https://www.nmc.org.in (post-2021)
  • Identifier type code: Use MCI with the v2-0203 coding system
  • Registration number format: Varies by state medical council — store the full string as-is, do not attempt to parse or validate the format internally
  • State Council: Store the issuing council as a qualification.extension — it's critical for jurisdictional prescription validation
{
  "resourceType": "Practitioner",
  "id": "dr-mehta-001",
  "identifier": [
    {
      "use": "official",
      "system": "https://hpr.abdm.gov.in",
      "value": "HPR-2024-XXXXX"
    },
    {
      "use": "official",
      "system": "https://www.nmc.org.in",
      "value": "NMC/UGMC/XXXXX"
    }
  ],
  "active": true,
  "name": {
    "use": "official",
    "family": "Mehta",
    "given": ["Rajesh", "Kumar"],
    "prefix": ["Dr."],
    "suffix": ["MD", "DM"]
  },
  "qualification": [
    {
      "identifier": {
        "system": "https://www.nmc.org.in",
        "value": "NMC/UGMC/XXXXX"
      },
      "code": {
        "coding": {
          "system": "http://terminology.hl7.org/CodeSystem/v2-0360",
          "code": "MD"
        },
        "text": "MD (General Medicine)"
      },
      "period": { "start": "2005-07-01" }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Spring Boot + HAPI FHIR Implementation

package com.snowcare.hmis.fhir;

import org.hl7.fhir.r4.model.*;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class PractitionerFhirMapper {

    /**
     * Maps internal Doctor entity to FHIR Practitioner resource.
     */
    public Practitioner toFhir(Doctor doctor) {
        Practitioner practitioner = new Practitioner();
        practitioner.setId(doctor.getId().toString());

        // HPR Identifier (ABDM)
        if (doctor.getHprId() != null) {
            practitioner.addIdentifier()
                .setUse(Identifier.IdentifierUse.OFFICIAL)
                .setSystem("https://hpr.abdm.gov.in")
                .setValue(doctor.getHprId())
                .setType(new CodeableConcept().addCoding(
                    new Coding("http://terminology.hl7.org/CodeSystem/v2-0203", "HPR", "Health Professional Registry")
                ));
        }

        // NMC/MCI Registration
        practitioner.addIdentifier()
            .setUse(Identifier.IdentifierUse.OFFICIAL)
            .setSystem("https://www.nmc.org.in")
            .setValue(doctor.getMciRegistrationNumber())
            .setType(new CodeableConcept().addCoding(
                new Coding("http://terminology.hl7.org/CodeSystem/v2-0203", "MCI", "Medical Council of India")
            ));

        practitioner.setActive(doctor.getIsActive());

        // HumanName
        HumanName name = practitioner.addName()
            .setUse(HumanName.NameUse.OFFICIAL)
            .setFamily(doctor.getLastName());
        for (String given : doctor.getFirstName().split(" ", 2)) {
            name.addGiven(given);
        }
        name.addPrefix("Dr.");

        if (doctor.getQualification() != null) {
            name.addSuffix(doctor.getQualification());
        }

        // Qualification block
        practitioner.addQualification()
            .setCode(new CodeableConcept().setText(doctor.getQualification()))
            .getIdentifier()
                .setSystem("https://www.nmc.org.in")
                .setValue(doctor.getMciRegistrationNumber());

        // Spoken languages (for multi-lingual prescription printing)
        practitioner.addCommunication()
            .setLanguage(new CodeableConcept(new Coding(
                "urn:ietf:bcp:47", "en", "English"
            )));

        return practitioner;
    }

    /**
     * Creates a Practitioner resource for a nurse/paramedical staff.
     */
    public Practitioner toFhir(ParamedicalStaff staff) {
        Practitioner practitioner = new Practitioner();
        practitioner.setId(staff.getId().toString());

        // State Pharmacy Council / Nursing Council registration
        practitioner.addIdentifier()
            .setUse(Identifier.IdentifierUse.OFFICIAL)
            .setSystem(staff.getCouncilSystem())
            .setValue(staff.getRegistrationNumber());

        practitioner.setActive(staff.getIsActive());
        practitioner.addName()
            .setUse(HumanName.NameUse.OFFICIAL)
            .setFamily(staff.getLastName())
            .addGiven(staff.getFirstName())
            .addPrefix(staff.getTitle()); // Sister, Mr., Ms.

        // Nursing/MLT qualification
        practitioner.addQualification()
            .setCode(new CodeableConcept().setText(staff.getQualification()))
            .getIdentifier()
                .setSystem(staff.getCouncilSystem())
                .setValue(staff.getRegistrationNumber());

        return practitioner;
    }
}
Enter fullscreen mode Exit fullscreen mode

JPA Entity

@Entity
@Table(name = "doctors")
public class Doctor {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "qualification")
    private String qualification; // MD, DM, MBBS, etc.

    @Column(name = "specialization")
    private String specialization; // General Medicine, Cardiology, etc.

    @Column(name = "nmc_registration_number", unique = true)
    private String nmcRegistrationNumber;

    @Column(name = "state_medical_council")
    private String stateMedicalCouncil; // Gujarat MC, Delhi MC, etc.

    @Column(name = "hpr_id")
    private String hprId; // Nullable until HPR enrollment

    @Column(name = "email")
    private String email;

    @Column(name = "phone")
    private String phone;

    @Column(name = "is_active")
    private Boolean isActive = true;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "organization_id")
    private Organization organization; // The hospital/clinic
}
Enter fullscreen mode Exit fullscreen mode

Validating Practitioner Identity Against ABDM

One of the most valuable ABDM integrations for an Indian HMIS is verifying a practitioner's credentials in real-time against the HPR. This can be done via the HPR lookup API:

@Service
public class HprVerificationService {

    private final RestTemplate restTemplate;

    @Value("${abdm.hpr.base-url}")
    private String hprBaseUrl;

    @Value("${abdm.hpr.api-key}")
    private String apiKey;

    /**
     * Verifies a practitioner against HPR by registration number.
     * Returns true if the registration is valid and verified.
     */
    public boolean verifyViaHpr(String registrationNumber, String councilType) {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "Bearer " + apiKey);
            headers.setContentType(MediaType.APPLICATION_JSON);

            Map<String, Object> requestBody = Map.of(
                "regNo", registrationNumber,
                "councilType", councilType // "MCI", "SMC", "INC" (Indian Nursing Council)
            );

            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
            ResponseEntity<Map> response = restTemplate.exchange(
                hprBaseUrl + "/v1/hpr/verify",
                HttpMethod.POST,
                entity,
                Map.class
            );

            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map body = response.getBody();
                return "VERIFIED".equals(body.get("status"));
            }
            return false;
        } catch (Exception e) {
            log.error("HPR verification failed for reg: {}", registrationNumber, e);
            return false;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Note: ABDM APIs require NDMA (National Digital Medical Authority) authorization and are subject to usage guidelines. Ensure your HMIS is registered as a Health Information User (HIU) before attempting HPR lookups.


Common Mistakes to Avoid

Storing only a display name, not identifiers.
Many HMIS systems store "Dr. Rajesh Mehta" as a string in the prescription table. This is not FHIR-compliant and will fail ABDM document signing. Always store the NMC registration number as an explicit identifier.

Ignoring the qualification period.
qualification.period (start date) is mandatory for ABDM compliance in some document types. A doctor who renewed their registration last year needs the current period, not the original registration date.

Not handling title/gender separately.
The prefix "Dr." is not the same as the gender field. Store them separately — FHIR has both name.prefix and gender.

Treating HPR as mandatory.
HPR enrollment is not yet universal. Build your Practitioner model to accept a null HPR ID but surface a flag or workflow prompt to enroll. Making HPR mandatory before the registry is complete will block half your existing doctor roster from FHIR export.

Single Practitioner for multi-specialty doctors.
A doctor with both an MD and a DM in Cardiology should have two qualification entries. The FHIR Practitioner allows multiple qualifications — use them.


Prescription Linkage: Practitioner ↔ PractitionerRole

For a prescription to be legally valid under Indian law, it must carry the doctor's name, registration number, and specialization. The PractitionerRole resource links a Practitioner to the Organization and care settings where they practice:

<PractitionerRole>
  <practitioner>
    <reference value="Practitioner/dr-mehta-001"/>
    <display value="Dr. Rajesh Mehta"/>
  </practitioner>
  <organization>
    <reference value="Organization/snowcare-hmis"/>
    <display value="SnowCare Hospital"/>
  </organization>
  <code>
    <coding>
      <system value="http://terminology.hl7.org/CodeSystem/v2-0286"/>
      <code value="OTHER"/>
      <display value="Healthcare Provider"/>
    </coding>
  </code>
  <specialty>
    <coding>
      <system value="http://snomed.info/sct"/>
      <code value="394579002"/>
      <display value="Cardiology"/>
    </coding>
  </specialty>
</PractitionerRole>
Enter fullscreen mode Exit fullscreen mode

In your HMIS, every prescription should carry a practitionerRoleId linking to the PractitionerRole that encodes the doctor's active practice location, specialty, and organization. This is what makes prescriptions ABDM-document-ready.


What's Next

With Practitioner and PractitionerRole covered, you're ready to model the Organization itself — the hospital or clinic where these practitioners work. That's the FHIR Organization resource, with its own India-specific identifier: the HFR (Health Facility Registry) ID. That's coming up next.


About the Author

Harikrushna V is the founder of Orglance Technologies and SnowCare Health Tech. With 13 years of experience spanning PayPal, Salesforce, NCR, and ST Microelectronics, he specializes in building FHIR-compliant HMIS systems for the Indian healthcare ecosystem. He holds an MBA from IIM Ahmedabad.

Top comments (0)