API documentation

Machine access for approved companies: validate FHIR resources from your software, scripts and CI pipelines.

Base URL: https://fhir-sandbox.sahasratech.com.np · FHIR base: https://fhir-sandbox.sahasratech.com.np/fhir · FHIR R4 (4.0.1), NP Core 1.0.0

Authentication

Create an API key on the API keys page (approved companies only). Keys start with npfs_ and are shown once. Send the key in every request:

Authorization: Bearer npfs_xxxxxxxxxxxxxxxxxxxxxxxx

GET /fhir/metadata and GET /api/profiles are public. Everything else requires a key (or a signed-in browser session).

POST /fhir/$validate

Validates a FHIR resource (JSON or XML) against NP Core and returns a FHIR OperationOutcome. Nothing is stored. Choose the profile with ?profile=, or omit it to use meta.profile or the NP Core default for the resource type.

curl -sS -X POST "https://fhir-sandbox.sahasratech.com.np/fhir/\$validate?profile=http://fhir.digitalhealth.gov.np/core/StructureDefinition/np-core-patient" \
  -H "Authorization: Bearer $NPFS_API_KEY" \
  -H "Content-Type: application/fhir+json" \
  --data-binary @patient.json

Each issue carries the raw validator text in details.text, a plain-language explanation and fix in diagnostics, the location in expression, and a structured explanation in the extension https://fhir-sandbox.mohp.gov.np/StructureDefinition/explanation. The resource conforms when there is no issue with severity error or fatal.

POST /api/validate

Returns the sandbox ValidationReport (the same data the web validator shows) as plain JSON.

POST /api/validate
Content-Type: application/json

{ "profile": "http://fhir.digitalhealth.gov.np/core/StructureDefinition/np-core-patient", "resource": { "resourceType": "Patient", … } }
{
  "id": "…run id…", "createdAt": "…", "valid": false,
  "resourceType": "Patient", "profile": "…", "profileTitle": "NP Core Patient",
  "summary": { "fatal": 0, "error": 1, "warning": 0, "information": 0 },
  "issues": [ {
    "severity": "error", "code": "structure", "messageId": "…",
    "location": "Patient", "line": 1, "col": 2, "message": "raw validator text",
    "explanation": { "title": "…", "what": "…", "why": "…", "fix": "…",
                     "example": "…", "igLink": "…", "category": "identifier" }
  } ],
  "operationOutcome": { "resourceType": "OperationOutcome", "issue": [ … ] }
}

Related: GET /api/profiles (catalog of NP Core profiles), GET /api/runs?limit=&cursor= and GET /api/runs/{id} (your history).

FHIR test server

Each approved company has its own private FHIR R4 test server built into the sandbox; a company only ever sees its own data. Writes are validated first: if there is any error, the request is rejected with 422 and the explained OperationOutcome, and nothing is stored.

JSON only: XML writes get 415 and _format=xml gets 406 (XML is fine for $validate).

RequestBehaviour
GET /fhir/metadataCapabilityStatement (public); lists the NP Core profiles as supportedProfile
GET /fhir/{type}/{id}Read. 404 unknown, 410 deleted. ETag W/"version"; If-None-Match gives 304.
GET /fhir/{type}/{id}/_history[/{vid}]History (newest first, max 100) and vread
POST /fhir/{type}Create; server-assigned id. Validated and references checked first: 422 with explained OperationOutcome, or 201 with Location and ETag. Prefer: return=minimal | representation | OperationOutcome.
PUT /fhir/{type}/{id}Update, or create with your own id (201). Body id must equal the URL id (else 400). If-Match mismatch gives 412.
DELETE /fhir/{type}/{id}Soft delete, 204, idempotent; If-Match supported
GET /fhir/{type}?…, POST /fhir/{type}/_searchSearch — see the parameters below
POST /fhirtransaction (all-or-nothing; order DELETE, POST, PUT, GET) or batch Bundle. urn:uuid fullUrls are resolved; every entry is validated. ifNoneExist and conditional requests give 400.
POST /fhir/$validate, /fhir/{type}/$validate, /fhir/{type}/{id}/$validateRaw resource or Parameters(resource, profile); always 200 with explained OperationOutcome

Search parameters

  • All types: _id, identifier (system|value or value), _lastUpdated with eq|gt|ge|lt|le (repeat for a range).
  • patient (Patient/x or x) on types with a subject or patient; subject (Type/x or x) on types with a subject. Comma-separated values mean OR.
  • Result controls: _count (default 20, max 100), _offset, _sort=_lastUpdated or -_lastUpdated (default), _summary=count, _pretty=true.
  • Anything else — other parameters, modifiers such as :exact, other _sort/_summary values — returns 400 listing the supported parameters.

References

  • Type/id must exist in your company's store or be created in the same Bundle, and the target type must be allowed by the NP Core profile (otherwise 422, e.g. SANDBOX_REFERENCE_TARGET_TYPE).
  • Absolute URLs to this sandbox are normalised to Type/id; other absolute URLs are accepted with a warning; #contained references are allowed; conditional references are rejected.

Not supported

Whole-system search and history, type-level _history, PATCH (405), _format=xml (406), conditional create/update/delete.

Quota and reset

Each company may store a limited number of live resources; above it writes get 403. Use “Reset my test data” on the dashboard to wipe your company's test data. CORS is enabled on /fhir only.

Scenarios & reports

GET /api/scenariosAll scenarios with your latest status
POST /api/scenarios/{id}/submitBody {"resource": …} or {"bundle": …}; returns the result of each check
GET /api/company/reportConformance summary (per group pass %)

Status codes

200OK ($validate always returns 200 with an OperationOutcome, valid or not)
201Created (FHIR test server)
204 / 304Deleted / not modified
400Malformed request (e.g. no resource in the body)
401Missing, wrong or revoked API key
403Company not approved or suspended, or storage quota reached
404 / 410Resource not found / deleted
405 / 406 / 415PATCH not supported / _format=xml / XML body on a write
412If-Match version conflict
413Request too large
422Write rejected because the resource is not conformant (body: explained OperationOutcome)
429Rate limit exceeded — retry later with back-off
503Validation engine temporarily unavailable — retry in a minute

Limits

  • Requests are rate-limited per API key; pending companies have lower limits in the web validator.
  • Maximum body size: 5 MB. Maximum 500 entries per Bundle.
  • Use a client timeout of at least 60 seconds.
  • Use synthetic test data only. Never send real patient information.

Example: a conformant NP Core Patient

{
  "resourceType": "Patient",
  "id": "ExampleNPCorePatient",
  "meta": {
    "profile": [
      "http://fhir.digitalhealth.gov.np/core/StructureDefinition/np-core-patient"
    ]
  },
  "identifier": [
    {
      "use": "official",
      "type": {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "NI",
            "display": "National unique individual identifier"
          }
        ]
      },
      "system": "http://donidcr.gov.np",
      "value": "1234-5678-9012-3"
    },
    {
      "use": "official",
      "type": {
        "coding": [
          {
            "system": "http://fhir.digitalhealth.gov.np/core/CodeSystem/np-core-identifier-type",
            "code": "health-id",
            "display": "Nepal Health ID"
          }
        ]
      },
      "system": "http://fhir.digitalhealth.gov.np/core/NamingSystem/nepal-health-id",
      "value": "10000000001"
    },
    {
      "use": "official",
      "type": {
        "coding": [
          {
            "system": "http://fhir.digitalhealth.gov.np/core/CodeSystem/np-core-identifier-type",
            "code": "citizenship-number",
            "display": "Nepal Citizenship Certificate Number"
          }
        ]
      },
      "system": "http://moha.gov.np",
      "value": "12-34-56-78901"
    },
    {
      "use": "official",
      "type": {
        "coding": [
          {
            "system": "http://fhir.digitalhealth.gov.np/core/CodeSystem/np-core-identifier-type",
            "code": "health-insurance-id",
            "display": "Nepal Health Insurance ID"
          }
        ]
      },
      "system": "http://hib.gov.np",
      "value": "HIB-000123456"
    },
    {
      "use": "official",
      "type": {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "PPN",
            "display": "Passport number"
          }
        ]
      },
      "system": "http://nepalpassport.gov.np",
      "value": "PA1234567"
    },
    {
      "use": "official",
      "type": {
        "coding": [
          {
            "system": "http://fhir.digitalhealth.gov.np/core/CodeSystem/np-core-identifier-type",
            "code": "ssf-number",
            "display": "Nepal Social Security Fund Number"
          }
        ]
      },
      "system": "http://ssf.gov.np",
      "value": "1-01-01-00001234"
    }
  ],
  "active": true,
  "name": [
    {
      "use": "official",
      "family": "Shrestha",
      "given": [
        "Aarav"
      ]
    }
  ],
  "gender": "male",
  "birthDate": "1990-05-15",
  "_birthDate": {
    "extension": [
      {
        "url": "http://fhir.digitalhealth.gov.np/core/StructureDefinition/np-core-bikram-sambat-date",
        "valueString": "2047-02-01"
      }
    ]
  },
  "address": [
    {
      "extension": [
        {
          "url": "http://fhir.digitalhealth.gov.np/core/StructureDefinition/np-core-province",
          "valueCoding": {
            "system": "http://fhir.digitalhealth.gov.np/core/CodeSystem/nepal-administrative-location",
            "code": "3",
            "display": "Bagmati Province"
          }
        },
        {
          "url": "http://fhir.digitalhealth.gov.np/core/StructureDefinition/np-core-district",
          "valueCoding": {
            "system": "http://fhir.digitalhealth.gov.np/core/CodeSystem/nepal-administrative-location",
            "code": "306",
            "display": "Kathmandu"
          }
        },
        {
          "url": "http://fhir.digitalhealth.gov.np/core/StructureDefinition/np-core-local-level",
          "valueCoding": {
            "system": "http://fhir.digitalhealth.gov.np/core/CodeSystem/nepal-administrative-location",
            "code": "30608",
            "display": "Kathmandu Metropolitan City"
          }
        }
      ],
      "use": "home",
      "type": "physical",
      "text": "Ward 10, Naxal, Kathmandu Metropolitan City, Kathmandu, Bagmati Province, Nepal",
      "line": [
        "Ward 10",
        "Naxal"
      ],
      "city": "Kathmandu Metropolitan City",
      "district": "Kathmandu",
      "state": "Bagmati Province",
      "postalCode": "44600",
      "country": "NP"
    }
  ]
}