National Health Authority

Command Palette

Search for a command to run...

Facility Registry (HFR)

Search and de-duplicate facilities, run the four-stage HFR onboarding wizard, link HIP/HIU bridges, and verify facility contacts.

The Health Facility Registry (HFR) is where you onboard the clinic, hospital, lab or pharmacy. Onboarding is a four-stage wizard driven by a trackingId that carries state between calls, performed by a facility manager who holds an HPR ID. The final facilityId it returns is also your HIP ID for consent and data-flow.

Search before you onboard

Many Indian facilities are already seeded in HFR. Always search and de-duplicate first — creating a duplicate is the most common onboarding mistake.

flowchart TD
  S["Search / de-duplicate"] --> B["1. basic-information<br/>(x-hprid-auth) → trackingId"]
  B --> Q{"operational<br/>status = Functional?"}
  Q -- "yes" --> AD["2. additional-information"]
  AD --> DT["3. detailed-information"]
  DT --> SUB["4. submit-facility<br/>(x-hprid-auth) → facilityId"]
  Q -- "no" --> SUB
  SUB --> BR["link bridges (HIP/HIU)"]
  SUB --> OTP["verify facility contact (OTP)"]

Headers

All calls send Authorization: Bearer $SYSTEM_TOKEN. Only basic-information and submit-facility additionally require the facility manager's x-hprid-auth token.

Search & de-duplicate

Search by facilityId or by the trio ownershipCode + stateLGDCode + facilityName. When a facilityId is supplied, the other criteria are ignored. Fuzzy match on name, exact match on everything else; paginated (default 10 per page).

POST/FacilityManagement/v1.5/facility/search

Returns basic facility details.

cURL
curl -X POST "https://apihspsbx.abdm.gov.in/v4/int/FacilityManagement/v1.5/facility/search" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "facilityId": "IN33XXXXXX45",
  "ownershipCode": "",
  "stateLGDCode": "",
  "districtLGDCode": "",
  "subDistrictLGDCode": "",
  "pincode": "",
  "facilityName": "",
  "page": 1,
  "resultsPerPage": 10
}'
Response
{
"facilities": [
  {
    "facilityId": "IN33XXXXXX45",
    "facilityName": "ABC Hospital",
    "facilityStatus": "Submitted",
    "ownership": "PRIVATE",
    "ownershipCode": "P",
    "systemOfMedicine": "Modern Medicine(Allopathy),Dentistry",
    "facilityType": "Dental College",
    "stateName": "Tamil Nadu", "stateLGDCode": "33",
    "districtName": "Chennai", "districtLGDCode": "568",
    "subDistrictName": "Ambattur", "subDistrictLGDCode": "5700",
    "address": "No 510 south street koyambedu, ",
    "pincode": "600107",
    "latitude": "27.90728", "longitude": "78.32990"
  }
]
}

Search field rules

From the HFR workbook: facilityId is a 12-character alphanumeric value starting with IN (when supplied, other filters are ignored). ownershipCode is a value from get-master-data?type=OWNER; stateLGDCode / districtLGDCode / subDistrictLGDCode come from the lgd/* APIs; pincode is max 6 digits. page defaults to 1 and resultsPerPage to 10 — both are system-set, not end-user input.

De-duplicate

A stricter address-based duplicate check that also returns distance to each match — the best pre-flight before creating a facility.

POST/search/address/filter/deduplicate

name, district and subDistrict are required; address, village, geolocation and facilityId are optional. district/subDistrict are LGD codes; results are sorted nearest-first by distances (km).

cURL
curl -X POST "https://apihspsbx.abdm.gov.in/v4/int/search/address/filter/deduplicate" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "name": "Sunrise Clinic",
  "address": "alampur",
  "district": "499",
  "subDistrict": "3997",
  "village": "530905",
  "geolocation": "20.615650,77.502489",
  "facilityId": ""
}'
Response
[
{
  "facility_name": "tsst1",
  "alternate_id": "INXXXXXXXX93",
  "sub_district": "Karanja",
  "district": "Washim",
  "state": "Maharashtra",
  "distances": "0"
}
]

Fetch facilities within a radius of a point, with optional filters for ownership, speciality, system of medicine, ABDM-software status and even doctor attributes. Path and field names are taken from the HFR Swagger (ground truth).

POST/FacilityManagement/v1.5/facility/bygeoLocation/searchFacilityAndInfrastructureWithinRadiusWithFilter

centerLat, centerLon, radiusInKm, from (≥ 0) and size (≥ 1) drive the search; the rest are optional filters. Latitude −90…+90, longitude −180…+180, 1–6 decimals. abdmSoftware: "0" or "1"; facilityOwnership: "G", "P" or "PP". som is a system-of-medicine code; speciality and hospitalSpecialityType take comma-separated lists.

cURL
curl -X POST "https://apihspsbx.abdm.gov.in/v4/int/FacilityManagement/v1.5/facility/bygeoLocation/searchFacilityAndInfrastructureWithinRadiusWithFilter" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "centerLat": "12.911411",
  "centerLon": "77.676313",
  "radiusInKm": "50",
  "from": "0",
  "size": "2000",
  "abdmSoftware": "1",
  "facilityOwnership": "G",
  "facilityStatus": "Functional",
  "facilityName": "",
  "hospitalSpecialityType": "22,57",
  "speciality": "Leeching,Dalak,Exercise",
  "som": "UN",
  "gender": "",
  "doctorName": "",
  "doctorSystemOfMedicine": "",
  "languages": ""
}'
Response
{
"searchCountTotal": 1,
"recordList": [
  {
    "fac_unique_id": "71600",
    "alternate_id": "<Facility ID>",
    "facility_name": "<Facility Name>",
    "facility_ownership": "G",
    "facility_type": "22",
    "system_of_medicine": "UN",
    "geolocation": "12.911411,77.676313",
    "district": "525", "state": "29", "pincode": "560035",
    "abdm_software": "1",
    "distances": "0",
    "speciality": ["dalak", "exercise", "leeching"]
  }
]
}

Master & LGD lookups

Never hardcode codes — every wizard dropdown has a masters API. Codes may carry trailing padding spaces (e.g. "G "); trim before comparing.

APIMethodReturns
/v1.5/facility/get-master-typesGETList of master types
/v1.5/facility/get-master-data?type=OWNERGETValues for a type (OWNER, MEDICINE, FAC-STATUS, IMAGING, DIAGNOSTIC…)
/v1.5/facility/lgd/statesGETStates + their districts
/v1.5/facility/lgd/districts?stateCode=34GETDistricts for a state
/v1.5/facility/lgd/subdistricts?districtCode=4GETSub-districts for a district
/v1.5/facility/fetch-facility-typeGETFacility types for an ownership + medicine system
/v1.5/facility/get-owner-subtypeGETOwnership sub-types (incl. Central-Govt ministries)
/v1.5/facility/get-specialitiesGETSpecialities per system of medicine
/getPsuDetailsByMinistry?ministry=MODGETPSUs for a ministry
GET/v1.5/facility/get-master-data?type=OWNER

The pattern for every master list — a type and a code/value array.

cURL
curl "https://apihspsbx.abdm.gov.in/v4/int/v1.5/facility/get-master-data?type=OWNER" \
-H "Authorization: Bearer $SYSTEM_TOKEN"
Response
{
"type": "OWNER",
"data": [
  { "code": "G", "value": "Government" },
  { "code": "P", "value": "Private" },
  { "code": "PP", "value": "Public-Private-Partnership" }
]
}

PSU details (Central Government facilities)

When a facility is a Central-Government PSU (ownershipCode: "G", ownershipSubTypeCode: "C", workingInPsu: true), the facPsuName in basic-information must be a PSU id from this list.

GET/getPsuDetailsByMinistry?ministry=MOD

ministry codes (MOD, MOR, MOSteel, MOHF…) come from get-owner-subtype for Central-Government entities.

cURL
curl "https://apihspsbx.abdm.gov.in/v4/int/getPsuDetailsByMinistry?ministry=MOD" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "Accept: application/json"
Response
{
"data": [
  { "id": "HAL", "value": "HAL(Hindustan Aeronautics Limited)" },
  { "id": "BEL", "value": "BEL(Bharat Electronics Limited)" }
]
}

Onboarding — the four stages

Stage 1 — Basic information

Creates the draft facility and returns the trackingId. The whole facility payload is nested under facilityInformation, with trackingId as a sibling (empty on first create). Requires x-hprid-auth.

POST/v1.5/facility/basic-information

Save the returned trackingId — every later stage needs it.

cURL
curl -X POST "https://apihspsbx.abdm.gov.in/v4/int/v1.5/facility/basic-information" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "x-hprid-auth: $HPR_USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "trackingId": "",
  "facilityInformation": {
    "facilityName": "Test Hospital 102",
    "ownershipCode": "G",
    "ownershipSubTypeCode": "C",
    "ownershipSubTypeCode2": "MOSteel",
    "workingInPsu": true,
    "facPsuName": "SAIL(Steel Authority of India Limited)",
    "facilityAddressDetails": {
      "country": "India",
      "stateLGDCode": "18",
      "districtLGDCode": "288",
      "subDistrictLGDCode": "2087",
      "villageCityTownLGDCode": "",
      "addressLine1": "testaddadd,3testing",
      "addressLine2": "",
      "pincode": "781005",
      "latitude": "70.15394",
      "longitude": "72.87281"
    },
    "facilityContactInformation": {
      "facilityContactNumber": "8989042241",
      "facilityEmailId": "clinic@example.com",
      "facilityLandlineNumber": "",
      "facilityStdCode": "",
      "websiteLink": ""
    },
    "systemOfMedicineCode": "M,D",
    "facilityTypeCode": "9",
    "facilitySubType": "30",
    "specialityTypeCode": "",
    "typeOfServiceCode": "",
    "facilityOperationalStatus": "F",
    "facilityUploads": {
      "facilityBuildingPhoto": { "name": "building.pdf", "value": "<base64>" },
      "facilityBoardPhoto": { "name": "board.png", "value": "<base64>" }
    },
    "facilityAddressProof": [
      { "addressProofType": null, "addressProofAttachment": { "name": "", "value": "" } }
    ],
    "timingsOfFacility": [
      { "workingDays": "Mon", "openingHours": "9:00 AM - 5:00 PM" },
      { "workingDays": "Tue", "openingHours": "9:00 AM - 5:00 PM" }
    ],
    "abdmCompliantSoftware": [
      { "existingSoftwares": [], "anyOther": "abdm.gov.in" }
    ]
  }
}'
Response
{
"trackingId": "7993",
"status": "Created",
"message": "Facility created successfully. Please save the Facility Id returned",
"errorStatus": null
}

Nested payload & coded status

Two things older integrations get wrong: (1) the facility payload is nested under facilityInformation, not flat; and (2) facilityOperationalStatus is a master code (e.g. "F" for Functional from FAC-STATUS), not the word "Functional". Uploads, address proof, timings and abdmCompliantSoftware all belong inside basic information. Building/board photos: max 5 MB each; jpg/jpeg/png/pdf, with the filename extension matching the bytes.

Basic-information field rules

Validations the HFR portal enforces on stage 1 (from the HFR test-case workbook). Backend uses codes from the masters API, not display labels.

FieldRule
facilityNameAlphanumeric, must start with a letter, > 4 characters, no special characters
latitudeReal number −90.000000…+90.000000, 1–6 decimals
longitudeReal number −180.000000…+180.000000, 1–6 decimals
countryDefaults to India, non-editable
stateLGDCode / districtLGDCode / subDistrictLGDCodeLGD codes from the lgd/* APIs
addressLine1 (mandatory) / addressLine2Alphanumeric; only these specials allowed: . - , / ( ) _
pincodeMax 6 digits
workingDaysCodes from get-master-data?type=WORKING-DAYS; multiple; required if operational status is Functional
timingsOfFacility10:00 AM - 2:00 PM or 24*7; only for selected working days
facilityOperationalStatusCode from FAC-STATUS (e.g. F = Functional)
facilityLandlineNumber10 digits, no alphabets/specials
facilityContactNumber (mobile, public)6–8 digits
facilityEmailId / websiteLinkValid email / valid URL
Building & Board photos≤ 5 MB each; PNG/JPEG/JPG; single file
facilityAddressProofType codes from ADDRESS-PROOF (multiple); each attachment ≤ 5 MB
ownershipCodeOne value from OWNER master
ownershipSubTypeCodeRequired only when ownership is Government; from get-owner-subtype
ownershipSubTypeCode2Required only when subtype is Central; from CENTRAL-GOVERNMENT
systemOfMedicineCodeCodes from MEDICINE (multiple)
facilityTypeCode / facilitySubTypeCodes from fetch-facility-type / fetch-facility-Sub-type
typeOfServiceCodeFrom SPECIALITY-TYPE; not required for Pharmacy, Blood bank, Diagnostic Lab, Imaging Center, Cath lab, Dialysis Center
specialityTypeCodeFrom get-specialities per system of medicine; required for all types except Pharmacy, Blood bank, Cath lab, Dialysis Center

Stage 2 — Additional information

Only when facilityOperationalStatus is Functional. Captures which sub-services exist and any linked programme IDs.

POST/v1.5/facility/additional-information

The has* flags accept Y/N. Fields that don't apply to the facility type must be null or N, or the API returns per-field errorStatus entries.

cURL
curl -X POST "https://apihspsbx.abdm.gov.in/v4/int/v1.5/facility/additional-information" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "trackingId": "820",
  "generalInformation": {
    "hasDialysisCenter": "N",
    "hasPharmacy": "N",
    "hasBloodBank": "N",
    "hasCathLab": "N",
    "hasDiagnosticLab": "N",
    "hasImagingCenter": "N",
    "servicesByImagingCenter": [ { "service": "", "count": 0 } ]
  },
  "linkedProgramIds": {
    "nhrrId": "",
    "nin": "",
    "abpmjayId": "",
    "rohiniId": "",
    "echsId": "",
    "cghsId": "",
    "ceaRegistration": "",
    "stateInsuranceSchemeId": ""
  }
}'

Stage 3 — Detailed information

Only when Functional. Send only the sections that apply to the facility type — sending an inapplicable section is rejected with HIS-1070 ("not required for this facility type").

POST/v1.5/facility/detailed-information

Section applicability by type: specialities & medicalInfrastructure for hospital/clinic/IPD/day-care/dentistry; pharmacyDetails for pharmacies; bloodBankDetails for blood banks; imagingServices for imaging centres; diagnosticServices for diagnostic labs.

cURL
curl -X POST "https://apihspsbx.abdm.gov.in/v4/int/v1.5/facility/detailed-information" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "trackingId": "80454",
  "specialities": [
    { "systemOfMedicineCode": "M", "isSpecializationAvalaible": "Yes", "specialities": ["s6", "s13"] }
  ],
  "medicalInfrastructure": {
    "countIPDBedsWithoutOxygen": 0,
    "countIPDBedsWithOxygen": 0,
    "countICUBedsWithVentilators": 0,
    "countICUBedsWithoutVentilators": 0,
    "countHDUBedsWithVentilators": 0,
    "countHDUBedsWithoutVentilators": 0,
    "totalNumberOfVentilators": 0,
    "countDayCareBedsWithoutOxygen": 0,
    "countDayCareBedsWithOxygen": 0,
    "countDentalChairs": 0,
    "totalNumberOfBeds": 0
  },
  "pharmacyDetails": {
    "isJanAushadhiKendra": "N",
    "janAushadhiKendraId": "",
    "drugLicenseNumber": "",
    "pharmacyGstinNumber": "",
    "pharmacistRegistrationNumber": ""
  },
  "bloodBankDetails": {
    "isFacilityRegisteredInERaktkosh": "N",
    "eRaktoshId": "",
    "bloodBankLicenseNumber": "",
    "bloodStorageCenters": "",
    "storageCentersCount": 0,
    "bloodCollectedPerAnnum": "",
    "bloodRequiredPerAnnum": ""
  },
  "imagingServices": [ { "service": "", "count": 0 } ],
  "diagnosticServices": []
}'
Response
{
"trackingId": "80454",
"status": "Saved",
"message": "Facility details have been saved successfully. Please login at https://hspsbx.abdm.gov.in/ and submit your facility details for approval.",
"errorStatus": null
}

Stage 4 — Submit facility

Final submission. Without it the facility stays in Draft. Requires x-hprid-auth. Returns the permanent facilityId.

POST/v1.5/facility/submit-facility

Leave sourceOfInformation empty to submit as your own entity, or set it to a valid HFR data source with the matching sourceUniqueID. The facilityId starts with IN and is 12 characters.

cURL
curl -X POST "https://apihspsbx.abdm.gov.in/v4/int/v1.5/facility/submit-facility" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "x-hprid-auth: $HPR_USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "trackingId": "820",
  "sourceOfInformation": "",
  "sourceUniqueID": "",
  "facilitySuperUser": ""
}'
Response
{
"facilityId": "INAN000167",
"status": "Created",
"message": "Facility created successfully. Please save the Facility Id returned.",
"errorStatus": null
}

Submit body per Swagger

Per the HFR Swagger, the submit body is

{ trackingId*, sourceOfInformation, sourceUniqueID, facilitySuperUser }

— only trackingId is required and facilitySuperUser is an optional string. Leave sourceOfInformation / sourceUniqueID empty to submit as your own entity. The older x-hprid-auth-verifier header is not used.

Your facilityId is your HIP ID

The returned facilityId is the facility's HFR ID, which doubles as your HIP ID for consent and data-flow APIs. Link your bridges to it next.

Update a facility

There is no separate update endpoint. To edit an existing facility you re-run the same onboarding stages carrying the facility's existing trackingId, then submit again (a "resubmit"). Field rules are identical to onboarding.

Edit the stage(s) you need

Call basic-information, additional-information and/or detailed-information again with the facility's existing trackingId and the changed values — send only the stages that change. basic-information still requires x-hprid-auth.

Resubmit

Call submit-facility again with the same trackingId to push the edits for approval.

Edits are keyed by trackingId

The Swagger models every onboarding/edit stage by trackingId — the handle returned by the first basic-information call — so keep it from the original onboarding. If you only hold the facilityId, search for the facility first, and confirm the edit-keying against the sandbox before relying on it in production.

Associate your HIP/HIU bridges with the facility so data-flow requests resolve to it. Each bridge needs a unique hipName.

POST/v1/bridges/MutipleHRPAddUpdateServices

Links one or more bridges (each HRP[] entry) to the facility. All HRP[] fields are required.

cURL
curl -X POST "https://apihspsbx.abdm.gov.in/v4/int/v1/bridges/MutipleHRPAddUpdateServices" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "facilityId": "IN28XXXXXX08",
  "facilityName": "Test Hospital 104",
  "HRP": [
    {
      "bridgeId": "SBX_000135",
      "hipName": "Test Hospital 104",
      "type": "HIP",
      "active": true
    }
  ]
}'
Response
[
{
  "servicesLinked": {
    "id": "SBX_000135",
    "name": "Testing",
    "types": ["HIP"],
    "active": true
  }
}
]

Bridge field rules

From the HFR workbook: facilityId must already exist in HFR (starts IN, 12 characters) and facilityName is auto-fetched from it. bridgeId is alphanumeric and its validity is checked by HIECM; it must not repeat an already-linked bridge on the facility. type is HIP/HIU (validated by HIECM) and active is a boolean.

hipName & duplicate rules

hipName is what patients see when searching for the hospital in the ABHA/PHR app. Rules: max 15 characters, no special characters (%$*#@(~&!), and unique per bridge per facility. A common convention is hospital name + bridge suffix (e.g. XYZ + BRIDGE TESTXYZ BRIDGE). Re-linking a bridgeId already associated with the facility fails with error code 2500 (or 2506).

Verify facility contact (OTP)

Send OTP to contact

POST/v1.5/facility/sendOtpToContact

Sends a 6-digit OTP to the facility's registered mobile and returns a transactionId.

cURL
curl -X POST "https://apihspsbx.abdm.gov.in/v4/int/v1.5/facility/sendOtpToContact" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "facilityId": "IN28XXXXXX14" }'
Response
[
{
  "facilityId": "IN28XXXXXX14",
  "status": "Success",
  "message": "Otp sent successfully! Please keep transaction id for future reference",
  "transactionId": "efcd063c-7c4a-421f-8c2d-62de95ca82d6",
  "errorStatus": null
}
]

Validate OTP

POST/v1.5/facility/validateOtp

Validates the OTP against the transactionId from the send step and links the source hospital ID to HFR. source must be one of: UWIN, PMNDP, AB-PMJAY, NHRR, HMIS-CDAC, NIN, eHospital, STHMISID, STINSID, COWIN.

cURL
curl -X POST "https://apihspsbx.abdm.gov.in/v4/int/v1.5/facility/validateOtp" \
-H "Authorization: Bearer $SYSTEM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "otp": "091729",
  "source": "COWIN",
  "transactionId": "c22f9549-6d0f-436a-bc62-de05d57e7083"
}'

Validation gotchas

Save yourself a support ticket

The rules the HFR sandbox enforces most often.

RuleDetail
Facility uniquenessname + address + state + district + sub-district + pincode must be unique
Status branchingA non-Functional facilityOperationalStatus skips stages 2 & 3 and goes straight to submit
Ownership constraintsGownerSubTypeCode must be C; P/PPP or NP
PSU fieldsfacPsuName only when ownershipCode:"G" + ownershipSubTypeCode:"C" + workingInPsu:true
Medical infrastructureRequired for IPD/day-care/dentistry; not for imaging/diagnostic/blood-bank/pharmacy/cath-lab
SpecialitiesRequired for hospital/clinic types; not for diagnostic/imaging/blood-bank/pharmacy/dialysis/cath-lab
facilityId formatStarts with IN, exactly 12 characters
facilityNameStarts with a letter, > 4 chars, alphanumeric, no specials
Address line specialsOnly . - , / ( ) _ allowed beyond alphanumerics
Public phone numbersLandline 10 digits; mobile 6–8 digits
Working days & timingsworkingDays required when Functional; timings HH:MM AM - HH:MM PM or 24*7
Bed/chair countsNumeric; per-field ≤ 2 digits; totalNumberOfBeds / totalNumberOfVentilators ≤ 4 digits
Update flowRe-run stages with the existing trackingId, then resubmit — no dedicated update endpoint
Geolocation"lat,long", 1–6 decimals; lat −90…+90, long −180…+180
Master codesMay carry trailing padding spaces — trim before comparing

Sources

  • HSP Swagger — HFR OpenAPI spec (ground truth)
  • ABDM HFR — Facility Onboarding Documentation (updated 08-04-2026)
  • ABDM HFR M4 Test Cases workbook (16-03-2024) — field validations