{
  "resourceType": "OperationDefinition",
  "id": "eligibility-check",
  "url": "https://fhir.apps.health/OperationDefinition/eligibility-check",
  "title": "Eligibility check",
  "description": "Ask a patient's province, through one clinic's payer account, whether that patient may be billed,\nand report how that run ended.\n\n    POST [base]/$eligibility-check\n\n**The caller names a patient, never a card.** The health card the payer is asked about is read from\nthe patient's own record. No health number travels in the request, and a caller cannot ask about a\ncard the record does not hold. The caller's identity is likewise taken from the session rather than\nfrom the body, so a disclosure cannot be attributed to somebody else.\n\n**`affectsState` is `true`.** A run spends the clinic's payer credential, writes an audit record,\nand on success replaces the settled answer stored on the patient's health card `Identifier` in the\n[`health-card-eligibility`](StructureDefinition-health-card-eligibility.md) extension. It is a\n`POST`, it is not cacheable, and it is **not safe to repeat blindly** -- see the retry rule below.\n\n**There is no freshness rule and no cache.** Every request asks the payer, unless a check for the\nsame patient at the same clinic is already queued or running, in which case the second press\ncollapses into the first rather than opening a second call. There is no parameter that forces,\nbypasses or re-asks: an unrecognised part in the body changes nothing and is ignored.\n\n**Do not feature-detect this operation from a running server's `/metadata`.** Two different\ndocuments are easy to conflate here. This guide's server statement has `kind = requirements`: it\nsays what a conformant endpoint must offer, and it does declare this operation. What a running\ninstance publishes at `/metadata` is its own `kind = instance` statement, and the gateway serves\nthis operation itself without advertising it there -- so a live capability lookup answers \"absent\"\nwhile the operation works. Neither document is wrong; they answer different questions.\n\nSo do not branch on `/metadata`. A practice that has the feature switched off is refused with an\n[`OperationOutcome`](https://hl7.org/fhir/R4/operationoutcome.html) at `403`, and that refusal is\nthe signal to act on.\n\n### What a reply can say, and what never reaches one\n\nA reply is published only for a request that settled, was taken on, or collapsed into one already\nrunning. On a `200` the `status` parameter carries exactly one of four words:\n\n| `status` | what it means |\n|---|---|\n| `answered` | The payer settled the question while the caller waited. The `answer` part is present. |\n| `pending` | The request is queued. The answer lands on the patient's record when it arrives. **Never means \"not eligible\".** |\n| `alreadyInFlight` | A check for this patient at this clinic was already running, so no second one was taken on. |\n| `noAnswer` | The run reached the end and the payer settled nothing. Terminal: nothing further is queued and the record is unchanged. |\n\nEvery other ending is an `OperationOutcome` rather than a reply, so the words naming those endings\nare **never readable from a `status` parameter**:\n\n| HTTP | `issue.code` | the endings that read this way |\n|---|---|---|\n| `403` | `forbidden` | The caller may not ask, or the practice has eligibility checking switched off. |\n| `400` | `invalid` | The body does not describe a check, or the platform refused the request before the payer was asked. |\n| `422` | `business-rule` | The practice's own data cannot produce a question: an unsupported province, no usable card on record, a card issued by another province, or a patient the store does not hold. |\n| `503` | `transient` | A fault stopped the question being put, or stopped its outcome being read. |\n\n**Match on the HTTP status and `issue.code`, never on the sentence beside them.** The sentence in\n`issue.diagnostics` is developer-facing, is not a translation of anything, and is not stable.\n\n### Retrying is not free\n\nA `503` covers two different situations that the wire does not distinguish. In one, the payer was\nnever asked and the identical request may be sent again. In the other -- a reply that could not be\nread, or a wait that ran out after the request had gone out -- **the check may already have run**,\nbecause the platform does not stop when the caller's wait does. Re-read the patient's card before\nasking again rather than retrying on a timer. A `400`, `403` or `422` is not worth repeating\nunchanged.\n\n### Reading the answer\n\nThe `answer` part is present **exactly** when `status` is `answered`, and its three children are\nnamed and typed exactly as the same three children are stored on the card in\n[`health-card-eligibility`](StructureDefinition-health-card-eligibility.md), so one parser serves\nboth this reply and a [Patient](StructureDefinition-nexus-emr-core-patient.md) read.\n\nRead it whole or not at all: `eligible` and `answeredAt` are both required for the answer to mean\nanything. `answeredAt` is when the payer gave THIS answer, not when the patient was last checked --\na re-check that agrees leaves the moment alone, so no freshness may be inferred from it. An absent\n`coverageExpiry` means the payer delivered none, **not** that coverage is unlimited.\n\nFor any status other than `answered`, this run settled nothing, and the patient's own record remains\nthe place to read the current answer.\n\nAsking for a check requires both the eligibility-check execute right and the eligibility write\nright. A caller holding one but not the other is refused at `403` before anything in the body is\njudged, so that outcome describes nothing that was sent.",
  "name": "EligibilityCheck",
  "status": "draft",
  "kind": "operation",
  "experimental": false,
  "publisher": "WELLSTAR Technologies Corp.",
  "affectsState": true,
  "code": "eligibility-check",
  "system": true,
  "type": false,
  "instance": false,
  "parameter": [
    {
      "name": "patient",
      "use": "in",
      "min": 1,
      "max": "1",
      "type": "Reference",
      "targetProfile": [
        "https://fhir.apps.health/StructureDefinition/nexus-emr-core-patient"
      ],
      "documentation": "The patient to ask about, as a literal relative reference of the form `Patient/{id}` and nothing else. It must be a `Reference`: a plain string carrying the same text is not read. The shape is judged exactly -- a bare id, an absolute URL, a versioned reference (`Patient/1/_history/2`), a reference to another type, and a trailing empty id are each refused, because each carries either no slash or more than one."
    },
    {
      "name": "clinicId",
      "use": "in",
      "min": 1,
      "max": "1",
      "type": "string",
      "documentation": "The clinic whose payer account asks the question, and whose credential the run spends. A string that must parse as a UUID; a value that does not parse is refused. The clinic is verified against the caller's own tenant before anything is queued."
    },
    {
      "name": "serviceDate",
      "use": "in",
      "min": 0,
      "max": "1",
      "type": "date",
      "documentation": "The day the check is asked for. CONTEXT ONLY: it gates nothing, opens no window, and does not change the answer -- it is carried alongside the queued work and echoed back. It must name a whole day: `2026-08` and `2026` are refused rather than rounded, and a string carrying the same text is not read. Omitting it is normal and is not read as today."
    },
    {
      "name": "status",
      "use": "out",
      "min": 1,
      "max": "1",
      "type": "string",
      "documentation": "How the run ended, published as a `valueString`. On a reply it is one of exactly four words: `answered`, `pending`, `alreadyInFlight`, `noAnswer`. The endings named `featureDisabled`, `provinceNotSupported`, `noCardOnRecord`, `cardOutOfProvince`, `patientNotFound`, `patientUnreadable`, `credentialMissing` and `vendorUnavailable` are published as OperationOutcomes and can never be read here. Tolerate a word this guide does not list: the platform and this guide ship on different cadences."
    },
    {
      "name": "problem",
      "use": "out",
      "min": 0,
      "max": "1",
      "type": "string",
      "documentation": "Why the run ended the way it did, when it ran and produced a typed problem, published as a `valueString`. Finer-grained than `status` and never a substitute for it. The vocabulary is `credentialMissing`, `vendorUnavailable`, `vendorRejected`, `vendorAnswerUnknown`, `vendorPending`, `rateLimited`, `pollTimeout`, `alreadyInFlight`, `patientNotFound`, `patientUnreadable`, `noCardOnRecord`, `cardOutOfProvince`, `cardChangedDuringCheck`, `provinceNotSupported`, `featureDisabled`, `answerNotStored`. Not every word can accompany every status, and a word this guide does not list must not break a reader."
    },
    {
      "name": "message",
      "use": "out",
      "min": 1,
      "max": "1",
      "type": "string",
      "documentation": "Display words a caller may show. Never a card value and never the payer's own text. Display it; do not branch on it."
    },
    {
      "name": "patient",
      "use": "out",
      "min": 1,
      "max": "1",
      "type": "Reference",
      "targetProfile": [
        "https://fhir.apps.health/StructureDefinition/nexus-emr-core-patient"
      ],
      "documentation": "The patient the request named, echoed back exactly as sent, so a reply read out of band still says who it is about."
    },
    {
      "name": "serviceDate",
      "use": "out",
      "min": 0,
      "max": "1",
      "type": "date",
      "documentation": "The day the request named, echoed back when it named one. Absent when the request named none; it is never filled in."
    },
    {
      "name": "answer",
      "use": "out",
      "min": 0,
      "max": "1",
      "documentation": "The settled answer this run produced. Present EXACTLY when `status` is `answered`, and absent for every other status -- a `pending` reply carrying an answer is malformed. Its three children are named and typed exactly as the same three are stored on the card in the `health-card-eligibility` extension.",
      "part": [
        {
          "name": "eligible",
          "use": "out",
          "min": 1,
          "max": "1",
          "type": "boolean",
          "documentation": "The payer's settled answer for the card that was asked about. Required: an answer part without it carries no answer."
        },
        {
          "name": "answeredAt",
          "use": "out",
          "min": 1,
          "max": "1",
          "type": "instant",
          "documentation": "When the payer gave THIS answer -- NOT when the patient was last checked. The stored answer is rewritten only when it changes, so a re-check that agrees leaves this moment untouched and no freshness may be inferred from it. Required."
        },
        {
          "name": "coverageExpiry",
          "use": "out",
          "min": 0,
          "max": "1",
          "type": "date",
          "documentation": "The coverage expiry the payer delivered alongside the answer. Absent means the payer delivered none, NOT that coverage is unlimited."
        }
      ]
    }
  ]
}
