Patient Share (Scan-and-Share) & HPR (Healthcare Professional Registry)

1. Patient Share / Scan-and-Share

What this is for: This is the "walk up to the reception desk and scan a QR code" flow. A patient opens their ABHA (PHR) app, scans the facility's counter QR code, and their basic profile (name, ABHA address, DOB, etc.) is sent straight to the facility's reception system — no manual data entry, no paperwork. In return, the facility hands the patient a queue token number, and the patient can watch their token number update live in their PHR app while they wait.

Under the hood this is a round trip through the ABDM gateway: the patient's PHR app tells ABDM "I'm sharing my profile with this HIP", ABDM calls our system (acting as the HIP — Health Information Provider — for the facility), we generate a token number and hand it back to ABDM, and ABDM relays that acknowledgement back to the patient's app (where we also act as the HIU — Health Information User — receiving that acknowledgement). The same request/response pattern is reused for a secondary "what's the current queue number at this counter" query used to show live queue progress.

Code lives in src/modules/abdm/hip/patient-share/:

Outbound / internal endpoints (/v1/patient-share)

GET /v1/patient-share/stats/:facilityId

Plain English: returns the "how are we doing today" numbers for the reception-desk dashboard — how many patients have scanned in, how many were successfully checked in, how many failed.

{
  "success": true,
  "message": "Success",
  "data": {
    "allTime": { "total": 482, "acknowledged": 460, "failed": 14, "received": 8 },
    "today": { "total": 37, "acknowledged": 35, "failed": 2 }
  },
  "requestId": null
}

GET /v1/patient-share/events

Plain English: the paginated list of "who scanned in today" — every patient-share event recorded for the facility, newest first.

{
  "limit": 20,
  "offset": 0,
  "status": "ACKNOWLEDGED"
}

status is optional (RECEIVED | ACKNOWLEDGED | FAILED | EXPIRED); omit to return all.

{
  "success": true,
  "message": "Success",
  "data": {
    "events": [
      {
        "id": "clv9x...",
        "facilityId": "fac_9182",
        "requestId": "9b9f6b1e-2b40-4f2e-8a4c-3f2b6e2a11aa",
        "abhaAddress": "rajesh.kumar@abdm",
        "abhaNumber": "91-1234-5678-9012",
        "hipCode": "IN0310000702_1",
        "counterId": "counter-1",
        "tokenNumber": "482913",
        "linkingToken": null,
        "latitude": 28.6139,
        "longitude": 77.209,
        "status": "ACKNOWLEDGED",
        "createdAt": "2026-07-18T04:12:03.000Z"
      }
    ],
    "total": 1,
    "limit": 20,
    "offset": 0
  }
}

Note rawPayload (the full ABDM payload) is deliberately omitted here for size — fetch the single-event endpoint for that.

GET /v1/patient-share/events/:requestId

Plain English: the full detail of one specific scan-in event, including the raw payload ABDM sent us — mainly used to debug an event that looks wrong or didn't behave as expected.

POST /v1/patient-share/events/:requestId/retry

Plain English: if our earlier acknowledgement to ABDM failed (e.g. a network blip), this button re-sends it, so the patient's queue token still gets confirmed without asking them to scan again.

{ "success": true, "message": "Acknowledged successfully", "data": null }
{ "success": true, "message": "Already acknowledged", "data": null }

POST /v1/patient-share/running-token/status

Plain English: asks ABDM "what queue number is currently being served at counter X of this facility?" — used so a waiting patient's PHR app can show live queue progress. The actual answer doesn't come back in this HTTP response; it arrives later via a separate callback (below).

{
  "hipId": "IN0310000702_1",
  "context": "counter-1"
}
{
  "success": true,
  "message": "Accepted",
  "data": { "requestId": "5c8a1f2e-77b3-4e5a-9b1c-2d3e4f5a6b7c" },
  "requestId": null
}

Returned with HTTP 202 — ABDM only acknowledges receipt of the query here.

PATCH /v1/orvo/patient-share/{tokenNumber} — ORVO appointment correlation callback

Plain English: one-way inbound callback from api.orvo.app into abha.orvo.app when the appointment attached to a Scan & Share token changes status. This endpoint links the Orvo appointment data back onto every matching PatientShareEvent row for that facility, so the reception dashboard and the underlying event record stay in sync.

{
  "appointmentId": "appt-1",
  "clinicId": "550e8400-e29b-41d4-a716-446655440000",
  "patientId": "550e8400-e29b-41d4-a716-446655440001",
  "doctorId": "550e8400-e29b-41d4-a716-446655440002",
  "doctorName": "Dr. John Doe",
  "appointmentStatus": "Booked",
  "appointmentDate": "2026-08-21",
  "meta": {
    "departmentId": "550e8400-e29b-41d4-a716-446655440003",
    "departmentName": "Cardiology"
  }
}

appointmentDate accepts Orvo's date-only YYYY-MM-DD value as well as a full ISO 8601 timestamp. meta and its department fields may be omitted or null when the appointment is not assigned to a department. appointmentStatus accepts the canonical values used by this API, and legacy No-Show / No Show spellings are normalized to noShown.

Inbound ABDM callbacks

These four routes are POSTed to directly by the ABDM gateway. There is no bearer-token or session auth on any of them — ABDM does not reliably send X-HIP-ID either, so the non-blocking attachXHipId-style handling is used elsewhere in the codebase for header-optional cases; these specific callback routes rely purely on the body's own hipId/abhaAddress fields to resolve context. Every inbound callback here is logged via createInboundCallbackLogger('patient-share') for auditability, and every controller method replies immediately with 202 before doing any processing — ABDM only allows the HIP a short window to acknowledge, so processing happens asynchronously after the response is already sent.

POST /api/v3/hip/patient/share — Inbound ABDM callback

Plain English: this is the actual "the patient just scanned the QR" event. ABDM sends us the patient's profile the instant they scan, and we must hand back a queue token number within seconds.

{
  "intent": "PROFILE_SHARE",
  "metaData": {
    "hipId": "IN0310000702_1",
    "context": "counter-1",
    "hprId": null,
    "hfrId": null,
    "latitude": "28.6139",
    "longitude": "77.2090"
  },
  "profile": {
    "patient": {
      "abhaAddress": "rajesh.kumar@abdm",
      "abhaNumber": "91-1234-5678-9012",
      "name": "Rajesh Kumar",
      "gender": "M",
      "yearOfBirth": "1991",
      "monthOfBirth": "04",
      "dayOfBirth": "24",
      "phoneNumber": "9876543210",
      "address": {
        "line": "12 MG Road",
        "district": "Bengaluru Urban",
        "state": "Karnataka",
        "pincode": "560001"
      }
    }
  },
  "token": "a1b2c3d4-link-token-example"
}

Note: ABDM sends latitude/longitude as strings here (a known ABDM quirk) even though the DB column and the PHR-app's own outbound request use numbers; the schema coerces this automatically. token is a V3 addition — a link token issued at QR-scan time (valid 24h) that lets the facility later perform HIP-initiated care-context linking for this patient without a separate demographic-auth step.

POST /api/v3/hiu/patient/on-share — Inbound ABDM callback

Plain English: this is ABDM relaying back, to us acting as the patient's HIU, the token number that the HIP (possibly a different facility's system, or our own HIP side) just assigned — so the patient's own PHR session can be told "here's your number."

{
  "acknowledgement": {
    "status": "SUCCESS",
    "abhaAddress": "rajesh.kumar@abdm",
    "profile": {
      "context": "counter-1",
      "tokenNumber": "482913",
      "expiry": 180
    }
  },
  "error": null,
  "response": { "requestId": "9b9f6b1e-2b40-4f2e-8a4c-3f2b6e2a11aa" }
}

expiry is sent by ABDM as a numeric string in practice (e.g. "180"); the schema coerces it so the callback isn't rejected and silently dropped.

POST /api/v3/hip/patient/running-token/status — Inbound ABDM callback

Plain English: ABDM, on behalf of a waiting PHR user, is asking our HIP side "what number are you currently serving at this counter?"

{
  "hipId": "IN0310000702_1",
  "context": "counter-1"
}

POST /api/v3/hiu/running-token/on-status — Inbound ABDM callback

Plain English: ABDM delivering the answer to the running-token query above back to whichever app originally asked (our HIU side), so a live queue-progress display can be updated.

{
  "token": {
    "hipId": "IN0310000702_1",
    "context": "counter-1",
    "runningTokenNumber": "482913",
    "averageTokenServiceTimeInMinutes": 5
  },
  "error": null,
  "response": { "requestId": "5c8a1f2e-77b3-4e5a-9b1c-2d3e4f5a6b7c" }
}

2. HPR — Healthcare Professional Registry

What this is for: HPR is India's national registry of doctors and other healthcare professionals — completely separate from ABHA (which is the patient health ID). This module lets a doctor or nurse create an HPR ID (their professional identity number), verify their identity via Aadhaar or mobile OTP, fill in their full professional profile (qualifications, registration numbers, work details), upload supporting documents, and — separately — register/link the facility (hospital/clinic) they work at into the Health Facility Registry (HFR). Once done, the professional can log in and manage their HPR account going forward.

Everything under this module proxies through to ABDM's NHPR (National Health Professional Registry) sandbox APIs. This backend does two things NHPR requires beyond plain proxying:

  1. Server-side RSA encryption of sensitive fields (Aadhaar numbers, OTPs, passwords, mobile numbers) via hprCryptoService, using ABDM's public certificate (fetchable directly at GET /auth/cert, though clients normally never need to call it themselves).
  2. Session-token forwarding — after login, the caller's HPR session token (hprToken) is captured from the Authorization header (via hprRequestContext, an AsyncLocalStorage-based per-request context wired in as router-level middleware) and auto-injected into outbound request bodies as hprToken/hpr_token wherever ABDM expects it there in addition to (or instead of) an auth header.

Code lives in src/modules/abdm/hpr/, mounted at /v1/hpr (see src/app.ts):

Because this module is a broad proxy, nearly every response is a passthrough of whatever ABDM returns, wrapped in this backend's standard envelope: { "success": true, "message": "Success", "data": <ABDM's response>, "requestId": null }. Examples below show a realistic data payload per ABDM's documented contract; treat exact field sets as illustrative since ABDM's sandbox responses for deeply-nested objects are not fully pinned down in the schema (marked loose()/passthrough where that applies).

Registration: Aadhaar identity verification

Two parallel paths exist to Aadhaar-verify a new registrant, both converging on a txnId-carrying demographic payload that feeds HPR ID creation: (a) the gateway/DigiLocker hosted-portal flow, and (b) the direct-OTP flow this backend drives itself with server-side RSA encryption.

POST /v1/hpr/registration/aadhaar/generate-link

Plain English: starts the "verify via ABDM's own hosted Aadhaar consent page" path — we never see the doctor's raw Aadhaar number for this option.

{ "scopes": ["nhpr-register"], "source": "NHPR" }
{ "txnId": "txn-abc-123", "link": "https://healthid.ndhm.gov.in/verify?token=..." }

POST /v1/hpr/registration/aadhaar/generate-otp

Plain English: the alternative to the hosted-portal flow — enter your Aadhaar number directly in our form, and ABDM texts an OTP to your Aadhaar-linked mobile.

POST /v1/hpr/registration/aadhaar/verify-otp

Plain English: submits the OTP the doctor received, completing direct-OTP Aadhaar verification, and gets back their Aadhaar KYC details to pre-fill the registration form.

{ "otp": "123456", "txnId": "txn-abc-124", "domainName": "@hpr.abdm", "idType": "hpr_id" }

domainName/idType default when omitted, but leaving them out has been observed to surface a misleading "Failed to retrieve aadhaar transaction details" error even though txnId is valid — always send them.

{
  "txnId": "txn-abc-124",
  "name": "Rajesh Kumar",
  "gender": "M",
  "yearOfBirth": "1991",
  "monthOfBirth": "04",
  "dayOfBirth": "24",
  "photo": "base64....",
  "address": { "state": "Karnataka", "district": "Bengaluru Urban", "pincode": "560001" }
}

POST /v1/hpr/registration/aadhaar/verify

Plain English: the gateway/DigiLocker-flow counterpart to verify-otp — fetches the verified Aadhaar demographics (and any existing linked HPR record) once the user has completed consent in ABDM's hosted portal.

POST /v1/hpr/registration/aadhaar/verify-gateway

Plain English: an alternate entry point for the same gateway/DigiLocker flow, for callers that only have a txnId from the consent redirect (no OTP to submit — that step already happened in ABDM's portal). Internally calls the same upstream ABDM endpoint as verify-otp.

POST /v1/hpr/registration/aadhaar/check-account

Plain English: "does this person already have an HPR account?" — used to redirect an already-registered doctor to login instead of letting them re-register.

Demographic auth & mobile OTP registration

POST /v1/hpr/registration/aadhaar/demographic-auth-mobile

Plain English: an alternative to OTP — confirms a mobile number matches UIDAI's records for this Aadhaar transaction without sending an OTP at all (useful when OTP delivery is unavailable).

POST /v1/hpr/registration/aadhaar/generate-mobile-otp

Plain English: sends an OTP to a contact mobile number supplied during registration (used when it differs from the Aadhaar-linked mobile).

POST /v1/hpr/registration/aadhaar/verify-mobile-otp

HPR ID creation

POST /v1/hpr/registration/aadhaar/hpid-suggestions

Plain English: suggests available username-style HPR IDs based on the doctor's name (e.g. rajesh.kumar, rajesh.kumar1).

POST /v1/hpr/registration/aadhaar/create-hprid

Plain English: the final registration step — creates the actual HPR ID account with a username and password, so the doctor can subsequently log in.

{
  "txnId": "txn-abc-123",
  "email": "rajesh.kumar@example.com",
  "domainName": "@hpr.abdm",
  "firstName": "Rajesh",
  "lastName": "Kumar",
  "password": "SecurePass123!",
  "hprId": "rajesh.kumar",
  "sourceType": "AADHAAR",
  "hpCategoryCode": 1,
  "hpSubCategoryCode": 1,
  "role": 1
}

email and password are sent as plaintext by the caller and RSA-encrypted server-side before forwarding. hpCategoryCode/role: 1 = Doctor.

{ "hprId": "rajesh.kumar@hpr.abdm", "hprIdNumber": "91-1234-5678-9012" }

Login (authentication)

None of these carry a forwarded HPR token — they're what establishes one (the outbound client falls back to ABDM's gateway token for these calls).

GET /v1/hpr/auth/cert

Plain English: fetches ABDM's public encryption certificate. Exposed mainly for parity/debugging — this backend already does all RSA encryption server-side, so most clients never need to call this.

POST /v1/hpr/auth/password

Plain English: standard username+password login for an existing HPR account.

POST /v1/hpr/auth/mobile-otp/send

POST /v1/hpr/auth/aadhaar-otp/init

POST /v1/hpr/auth/aadhaar-otp/confirm

Plain English: completes Aadhaar-OTP login and issues the session token.

POST /v1/hpr/auth/mobile-otp/verify

{
  "txnId": "txn-login-555",
  "hprIds": [
    { "hpId": "91-1234-5678-9012", "hprId": "rajesh.kumar" },
    { "hpId": "91-2222-3333-4444", "hprId": "rajesh.k.nurse" }
  ]
}

POST /v1/hpr/auth/authorized-token

Plain English: "I have multiple HPR accounts on this mobile — give me the token for this specific one."

Account management

GET /v1/hpr/account/information

Plain English: the doctor's full HPR profile, for display in an account/profile screen.

GET /v1/hpr/account/id-card

Plain English: fetches the doctor's official HPR ID card (image/PDF) for viewing or download.

GET /v1/hpr/auth/logout

Plain English: ends the HPR session on ABDM's side.

Professional registration & update

POST /v1/hpr/doctors/register

Plain English: fills in the doctor's actual professional profile — personal details, qualifications, current workplace — after the bare HPR ID account already exists. This is the step that makes the registry entry meaningful, not just a login.

{
  "practitioner": {
    "healthProfessionalType": "doctor",
    "officialMobile": "9876543210",
    "officialEmail": "rajesh.kumar@example.com",
    "personalInformation": {
      "firstName": "Rajesh",
      "lastName": "Kumar",
      "gender": "M",
      "dateOfBirth": "1991-04-24",
      "nationality": "356",
      "languagesSpoken": "1,2",
      "category": "C"
    },
    "registrationAcademic": {
      "category": "MBBS",
      "registrationData": [
        {
          "qualifications": [
            { "qualificationName": "MBBS", "collegeId": "1022", "yearOfPassing": "2015" }
          ]
        }
      ]
    },
    "currentWorkDetails": { "facilityId": "IN2810000123" }
  }
}

Deeper nested fields (registrationAcademic, currentWorkDetails, communicationAddress, contactInformation) are intentionally left loosely typed since they vary widely by profession/category — validate the exact shape against a live NHPR sandbox response before hardening.

POST /v1/hpr/doctors/fetch-professional-info

Plain English: looks up a registered professional's profile by HPR ID.

POST /v1/hpr/doctors/update-professional

Plain English: edits an existing professional profile — same payload shape as registration, applied to an account that's already registered.

Document management

POST /v1/hpr/doctors/fetch-documents

Plain English: lists which documents (degree certificate, ID photo, etc.) are already on file for a professional, and which slots are still empty.

[
  { "document_id": 1, "document_type": "profilePhoto", "uploaded": true },
  { "document_id": 2, "document_type": "degreeCertificate", "uploaded": false }
]

POST /v1/hpr/uploads/upload-document

Plain English: uploads the actual scanned certificate/photo files.

{
  "document": [
    {
      "document_id": 2,
      "document_type": "degreeCertificate",
      "fileType": "application/pdf",
      "data": "JVBERi0xLjQK..."
    }
  ]
}

Email verification

POST /v1/hpr/doctors/generate-email-otp

POST /v1/hpr/doctors/resend-email-otp

POST /v1/hpr/doctors/verify-email-otp

Plain English: confirms the emailed OTP and sets that address as the doctor's official verified email on the profile.

Mobile verification (profile update)

Distinct from the registration-time mobile OTP endpoints above — these operate on an already-registered professional's official mobile number and always need an active session.

POST /v1/hpr/doctors/generate-mobile-otp

POST /v1/hpr/doctors/regenerate-mobile-otp

POST /v1/hpr/doctors/verify-mobile-otp

Password management

POST /v1/hpr/password/recover-mobile-send

Plain English: forgot-password flow, step 1 — send a recovery OTP to the account's registered mobile.

POST /v1/hpr/password/recover-mobile-verify

POST /v1/hpr/password/reset

POST /v1/hpr/password/recover-aadhaar

Plain English: alternate recovery path when the registered mobile is unreachable — recover via Aadhaar OTP instead.

POST /v1/hpr/password/recover-aadhaar-confirm

POST /v1/hpr/password/change

Plain English: for a logged-in user who already knows their password and just wants to change it (no OTP needed).

Forgot HPID (recovering a forgotten username)

POST /v1/hpr/forgot-hpid/aadhaar-generate-otp

POST /v1/hpr/forgot-hpid/aadhaar-verify

POST /v1/hpr/forgot-hpid/mobile-generate-otp

POST /v1/hpr/forgot-hpid/mobile-verify

Plain English: since one mobile can map to more than one account, recovering by mobile also needs matching demographic details to pick the right one.

{
  "txnId": "txn-hpid-991",
  "otp": "123456",
  "firstName": "Rajesh",
  "lastName": "Kumar",
  "yearOfBirth": "1991",
  "monthOfBirth": "04",
  "dayOfBirth": "24",
  "gender": "M"
}

These GET endpoints use the forwarded HPR token if a session is present, otherwise fall back to the ABDM gateway token — a session is preferred but not strictly required.

GET /v1/hpr/search/hprid-exists/:hprId

Plain English: username-availability check while choosing an HPR ID, independent of hpid-suggestions (a user may type a custom name that needs its own check).

GET /v1/hpr/search/mobile/:mobile

Plain English: look up a professional record by registered mobile number.

GET /v1/hpr/search/hprid/:hprId

Plain English: look up a professional record by HPR ID.

Master data (reference/lookup lists)

All GET unless noted, all read-only reference data proxied straight from NHPR's public master-data APIs — called with a bare, header-free request since these public endpoints reject Authorization/X-CM-ID headers. Used purely to populate dropdowns in the registration/onboarding UI:

Endpoint Purpose
GET /v1/hpr/master/hpr-categories/:role Professional categories for a role (1=Doctor, 2=Nurse, 3=Other)
GET /v1/hpr/master/hpr-subcategories/:role/:categoryCode Sub-categories under a category
GET /v1/hpr/master/system-of-medicines Allopathy, Ayurveda, Homeopathy, Dentistry, Unani, etc.
GET /v1/hpr/master/medical-councils State/national medical councils
GET /v1/hpr/master/nurse-councils State/national nursing councils
GET /v1/hpr/master/languages/:languageId Resolve one language record by id
GET /v1/hpr/master/universities/:collegeId University affiliated with a college
GET /v1/hpr/master/colleges/:stateId/:systemOfMedicine Colleges in a state teaching a given system of medicine
POST /v1/hpr/master/courses Degree courses by college (loose passthrough body — the one master-data call that is a POST and goes through the standard authenticated client)
GET /v1/hpr/master/countries Country list
GET /v1/hpr/master/states Indian states/UTs
GET /v1/hpr/master/districts/:stateId HPR's own district list (distinct code system from LGD, see below)
GET /v1/hpr/master/sub-districts/:districtId HPR's own sub-district list
GET /v1/hpr/master/affiliated-boards All academic boards
GET /v1/hpr/master/affiliated-boards/:boardId One board's details
GET /v1/hpr/master/affiliated-boards-state/:stateId Boards scoped to a state
GET /v1/hpr/master/all-ministries Government ministries (used in facility ownership fields)

Example response shape for any of the above (data): [{ "code": "1", "name": "Allopathy" }, { "code": "2", "name": "Ayurveda" }] — actual field names vary by list; all are passthrough of ABDM's own shape.

Facility (HFR) onboarding — the "HPR → HFR → Done" journey

What this is for: this is the "HPR → HFR → Done" journey — a doctor may need to register (or find and link to) the facility they work at in the national Health Facility Registry, as a 4-step wizard. A trackingId returned by step 1 must be threaded through every subsequent step of the same in-progress registration.

POST /v1/hpr/facility/search

Plain English: search for an existing facility (to link to, or to confirm one doesn't already exist before creating a new one).

POST /v1/hpr/facility/basic-info (step 1)

{
  "trackingId": "",
  "facilityInformation": {
    "facilityName": "Sahyadri Hospital",
    "facilityAddressDetails": {
      "stateLGDCode": "27",
      "districtLGDCode": "522",
      "pincode": "560001",
      "addressLine1": "12 MG Road"
    },
    "facilityContactInformation": {
      "facilityEmailId": "contact@sahyadri.example",
      "facilityContactNumber": "9876543210"
    },
    "ownershipCode": "G",
    "systemOfMedicineCode": "M",
    "typeOfServiceCode": "IPD,OPD",
    "facilityOperationalStatus": "F"
  }
}

trackingId is empty on the first call; ABDM issues one in the response.

POST /v1/hpr/facility/additional-info (step 2)

POST /v1/hpr/facility/detailed-info (step 3)

POST /v1/hpr/facility/submit (step 4)

GET /v1/hpr/facility/master-types and GET /v1/hpr/facility/master-data/:type

Plain English: reference data for the onboarding form's dropdowns (e.g. type=OWNER returns ownership codes).

POST /v1/hpr/facility/contact-details, POST /v1/hpr/facility/send-otp, POST /v1/hpr/facility/validate-otp

Plain English: a contact-verification sub-flow proving the caller has authority over the facility record before it's finalized.

Cascading dropdown endpoints for onboarding

Endpoint Purpose
POST /v1/hpr/facility/fetch-type Facility types for an ownership+system-of-medicine combo
POST /v1/hpr/facility/fetch-subtype Sub-types for a facility type
POST /v1/hpr/facility/owner-subtype Ownership sub-types (e.g. private-for-profit vs not-for-profit)
POST /v1/hpr/facility/specialities Specialities for a system of medicine

Example request/response for fetch-type (FacilityFetchTypeSchema): { "ownershipCode": "G", "systemOfMedicineCode": "M" } → [{ "code": "2", "label": "Hospital" }]

POST /v1/hpr/facility/deduplicate

Plain English: checks whether a near-duplicate facility already exists before finalizing a new registration.

POST /v1/hpr/facility/multiple-hrp-services

Plain English: links one or more Health-Related Practitioner services to a facility record. The request/response shape here is intentionally left untyped (z.looseObject({})) since ABDM's contract for this endpoint isn't yet pinned down against a live sandbox — validate before hardening.

LGD (Local Government Directory) geography

Separate code system from HPR's own master/districts/master/sub-districts — LGD codes are specifically what the facility address fields (stateLGDCode/districtLGDCode/subDistrictLGDCode) expect.

Endpoint Purpose
GET /v1/hpr/lgd/states All LGD states
GET /v1/hpr/lgd/districts/:stateCode LGD districts for a state
GET /v1/hpr/lgd/subdistricts/:districtCode LGD sub-districts for a district

Example response (data) for any: [{ "code": "522", "name": "Bengaluru Urban" }]