CoverageEligibilityRequest and CoverageEligibilityResponse

CoverageEligibilityRequest and CoverageEligibilityResponse

CoverageEligibilityRequest is a real-time query to a payer: “Is this patient covered, and what does their coverage include for this service?” The CoverageEligibilityResponse answers with benefit details, coverage status, cost-sharing information, and — critically — whether prior authorization is required for a specific service.

This resource pair is the FHIR replacement for the X12 270/271 eligibility transaction, which has been the industry standard for real-time eligibility checking since the 1990s. In practice, most implementations route FHIR eligibility requests through clearinghouses that translate to X12 at the payer’s edge.

The purpose field determines what the request is asking for. A single request can ask multiple questions simultaneously — coverage status, benefit details, and auth requirements can all be checked in one call.


The purpose codes

This is the most structurally important field in the request:

CodeWhat it asksTypical use
auth-requirementsDoes this service require prior authorization?Pre-order checks at point of care
benefitsWhat are the benefit details for this service?Cost estimation, benefit display
discoveryWhat plans does this patient have with this payer?Multi-plan or unknown-plan lookup
validationIs the patient’s coverage currently active?Eligibility verification at check-in

A request can include multiple purpose codes:

"purpose": ["auth-requirements", "benefits"]

This asks both whether PA is required and what the benefit details are — the most common combination for a point-of-care eligibility check before ordering.


CoverageEligibilityRequest structure

Minimum required fields

{
  "resourceType": "CoverageEligibilityRequest",
  "id": "elig-request-001",
  "status": "active",
  "purpose": ["auth-requirements", "benefits"],
  "patient": { "reference": "Patient/patient-001" },
  "created": "2025-03-15",
  "insurer": { "reference": "Organization/payer-acme" },
  "insurance": [
    {
      "focal": true,
      "coverage": { "reference": "Coverage/member-coverage-001" }
    }
  ]
}

status: active is required for a valid request. created is the request date. insurer is the payer organization being queried.

servicedDate and servicedPeriod

Optional but important. When a future service date is included, the payer checks coverage as of that date rather than today:

"servicedDate": "2025-04-01"

For procedures that span multiple days, servicedPeriod with start/end dates applies.

item — service-specific benefit query

When asking about auth requirements or benefits for a specific service, include an item:

"item": [
  {
    "category": {
      "coding": [
        {
          "system": "http://terminology.hl7.org/CodeSystem/ex-benefitcategory",
          "code": "medical"
        }
      ]
    },
    "productOrService": {
      "coding": [
        {
          "system": "http://www.ama-assn.org/go/cpt",
          "code": "96413",
          "display": "Chemotherapy administration"
        }
      ]
    },
    "provider": { "reference": "Practitioner/dr-jones" },
    "facility": { "reference": "Location/outpatient-infusion-center" }
  }
]

Without item, the request asks about general coverage — is the patient covered at all, what are their general benefits? With item, the request is specific: is this CPT code covered, does it require PA, what is the cost-sharing?

Including provider and facility in the item matters. PA requirements and benefit levels often depend on whether the provider is in-network and whether the facility type is covered.

provider

Who is making the request (the provider system submitting to the payer):

"provider": { "reference": "Practitioner/dr-jones" }

This is distinct from the item.provider (which is the provider who would perform the service). The top-level provider is the requester.


CoverageEligibilityResponse structure

inforce

The most important single field in the response:

"inforce": true

inforce: true means the patient’s coverage is currently active. inforce: false means the coverage is not active — the patient is not covered. When inforce is false, benefit details may still be returned to explain why (e.g., coverage terminated, benefit period ended).

insurance

The insurance array in the response mirrors the insurance in the request, with added benefit detail:

"insurance": [
  {
    "coverage": { "reference": "Coverage/member-coverage-001" },
    "inforce": true,
    "benefitPeriod": {
      "start": "2025-01-01",
      "end": "2025-12-31"
    },
    "item": [...]
  }
]

benefitPeriod is the coverage year — the window in which the deductible, out-of-pocket maximums, and benefit limits reset.

item — benefit details

The response items correspond to the request items. Each returned item includes:

"item": [
  {
    "category": {
      "coding": [
        {
          "system": "http://terminology.hl7.org/CodeSystem/ex-benefitcategory",
          "code": "medical"
        }
      ]
    },
    "productOrService": {
      "coding": [{ "system": "http://www.ama-assn.org/go/cpt", "code": "96413" }]
    },
    "network": {
      "coding": [
        {
          "system": "http://terminology.hl7.org/CodeSystem/benefit-network",
          "code": "in"
        }
      ]
    },
    "unit": {
      "coding": [
        {
          "system": "http://terminology.hl7.org/CodeSystem/benefit-unit",
          "code": "individual"
        }
      ]
    },
    "term": {
      "coding": [
        {
          "system": "http://terminology.hl7.org/CodeSystem/benefit-term",
          "code": "annual"
        }
      ]
    },
    "benefit": [
      {
        "type": {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/benefit-type",
              "code": "copay"
            }
          ]
        },
        "allowedMoney": { "value": 50.00, "currency": "USD" }
      },
      {
        "type": {
          "coding": [{ "code": "deductible" }]
        },
        "allowedMoney": { "value": 1500.00, "currency": "USD" },
        "usedMoney": { "value": 750.00, "currency": "USD" }
      }
    ],
    "authorizationRequired": true,
    "authorizationSupportingInfo": [
      {
        "reference": "Coverage/member-coverage-001"
      }
    ],
    "authorizationUrl": "https://payer.example.org/pa-requirements/96413"
  }
]

authorizationRequired

This is the field that drives the prior authorization workflow. When authorizationRequired: true is returned for a service item, the provider must obtain PA before rendering the service:

"authorizationRequired": true

The Da Vinci CRD IG uses this field (and the related authorizationUrl) to signal to the EHR that it should launch the DTR workflow to gather documentation for PA submission.

authorizationUrl points to the payer’s documentation of what is required for authorization — the Questionnaire endpoint or policy documentation URL.

benefit types

Common benefit.type codes:

CodeWhat it represents
copayFixed copayment amount
coinsurancePercentage after deductible
deductibleDeductible limit and amount used
out-of-pocketAnnual out-of-pocket maximum and amount used
benefitMaximum benefit limit (e.g., visit count)
visitMaximum allowed visits per term

allowedMoney is the plan limit. usedMoney is what has been consumed so far in the benefit period. For deductible and out-of-pocket, both are typically returned: a patient who has met 50% of their deductible will see allowedMoney: 1500 and usedMoney: 750.


Full request/response example

Request — check auth requirements for chemotherapy

{
  "resourceType": "CoverageEligibilityRequest",
  "id": "elig-chemo-check",
  "status": "active",
  "purpose": ["auth-requirements"],
  "patient": { "reference": "Patient/patient-001" },
  "created": "2025-03-15",
  "insurer": { "reference": "Organization/payer-acme" },
  "insurance": [
    {
      "focal": true,
      "coverage": { "reference": "Coverage/member-456" }
    }
  ],
  "item": [
    {
      "productOrService": {
        "coding": [
          { "system": "http://www.ama-assn.org/go/cpt", "code": "96413" }
        ]
      },
      "provider": { "reference": "Practitioner/dr-jones" },
      "facility": { "reference": "Location/infusion-center-01" }
    }
  ]
}

Response — PA required

{
  "resourceType": "CoverageEligibilityResponse",
  "id": "elig-chemo-response",
  "status": "active",
  "purpose": ["auth-requirements"],
  "patient": { "reference": "Patient/patient-001" },
  "created": "2025-03-15",
  "request": { "reference": "CoverageEligibilityRequest/elig-chemo-check" },
  "outcome": "complete",
  "insurer": { "reference": "Organization/payer-acme" },
  "insurance": [
    {
      "coverage": { "reference": "Coverage/member-456" },
      "inforce": true,
      "benefitPeriod": {
        "start": "2025-01-01",
        "end": "2025-12-31"
      },
      "item": [
        {
          "productOrService": {
            "coding": [
              { "system": "http://www.ama-assn.org/go/cpt", "code": "96413" }
            ]
          },
          "network": {
            "coding": [{ "code": "in" }]
          },
          "authorizationRequired": true,
          "authorizationUrl": "https://payer.example.org/pa/oncology-chemo"
        }
      ]
    }
  ]
}

X12 270/271 relationship

The legacy standard for real-time eligibility is X12 270 (Eligibility Inquiry) and X12 271 (Eligibility Response). Most payer backends still run on X12, and most clearinghouses translate FHIR CoverageEligibilityRequest → X12 270 at the network edge.

FHIR CoverageEligibilityRequestX12 270 equivalent
purpose: validationISA header + NM1 (subscriber name loop)
purpose: benefitsEQ Eligibility or Benefit Inquiry segment
item.productOrServiceEQ03 Service Type Code
servicedDateDTP Date - Service Date
insurerNM1 Information Source
FHIR CoverageEligibilityResponseX12 271 equivalent
inforceAAA Reject Reason or EB Eligibility/Benefit information
item.benefitEB Eligibility/Benefit segments
item.authorizationRequiredEB (code G - Prior Authorization Required)
benefitPeriodDTP Date loops

Translation fidelity is imperfect. X12 271 carries benefit information in terse segment structures; the FHIR mapping is approximate. Payers that have implemented native FHIR eligibility endpoints will return richer, more structured responses than intermediary-translated X12 responses.

What gets lost in translation: X12 271 supports multiple insurance benefit levels (Medicare A/B, Medicaid, commercial) in a single response; FHIR maps these as separate insurance array entries. X12 271 EB segment codes for benefit types don’t map cleanly to FHIR benefit type codes — intermediaries make judgment calls that can vary by clearinghouse. Structured authorizationRequired flags (EB code G) translate reliably; nuanced benefit limits (e.g., visit count caps, age restrictions) often degrade to processNote text.


R5 changes

The core CoverageEligibilityRequest/Response model is stable between R4 and R5. Notable R5 additions:

  • CoverageEligibilityRequest.event — allows attaching event-type context (admission date, discharge date) for hospital-based eligibility checks.
  • CoverageEligibilityResponse.item.authorizationSupporting — formalizes the reference to documents or resources that support the authorization decision, replacing ad hoc extensions used in some R4 implementations.

For current US implementation, R4 is the relevant version. US Core and Da Vinci IGs are built on R4.


Search parameters

ParameterTypeFinds
patientreferenceEligibility requests for this patient
statustokenRequests with this status
createddateRequests created on this date
insurerreferenceRequests directed to this payer
providerreferenceRequests submitted by this provider
identifiertokenRequest with this business identifier

Most payer FHIR eligibility endpoints are request-only (POST only) — they accept requests synchronously and return responses in the HTTP body. Persistent search for historical eligibility requests is typically not supported by payer systems; it is more relevant for provider-side audit logs.


Eligibility vs prior authorization

These two workflows are frequently confused because both ask “can this service be rendered?”:

Eligibility (CoverageEligibilityRequest)Prior Authorization (Claim with use: preauthorization)
Checks whether coverage exists and what benefits applyRequests formal approval to render a specific service
Non-binding; returns benefit informationBinding; generates an authorization number
Typically real-time (<2 seconds)May be synchronous or pended (hours to days)
No authorization number generatedReturns preAuthRef that must accompany the claim
Does not satisfy a PA requirementRequired when authorizationRequired: true

Passing authorizationRequired: true check from eligibility is a signal that a PA is needed — it does not grant authorization. The provider must still submit a Claim with use: preauthorization and receive an approved ClaimResponse before rendering the service.


Implementation considerations

Check authorizationRequired before ordering. The single highest-value use of CoverageEligibilityRequest is asking purpose: auth-requirements at the point of order entry. If the response returns authorizationRequired: true, the clinical workflow shifts to initiate PA before the service is scheduled. Checking after the order is complete — or at billing — is too late.

Include item with the specific CPT/HCPCS code. A general coverage check (no item) tells you whether the patient is covered. It does not tell you whether this specific service requires PA. Always include the service code when the clinical question is about a specific procedure.

inforce and benefitPeriod are independent. A patient can be inforce: true at the time of the request but have a benefitPeriod that ends before the proposed service date. Check whether servicedDate falls within benefitPeriod before confirming coverage.

Deductible and out-of-pocket tracking. usedMoney in benefit items is a point-in-time snapshot — it reflects claims adjudicated as of the response date. Pending claims not yet adjudicated are not included. Eligibility responses should not be used for precise patient cost estimation; they are directional.

Real-time eligibility is not a guarantee. An eligibility response confirming coverage does not guarantee a claim will be paid. Coverage can terminate, authorization can be denied, and adjudication can find exclusions that the eligibility check did not surface. Eligibility is a pre-visit check; adjudication is the final word.

Real-time vs batch eligibility. Individual point-of-care eligibility checks (one patient, one request) use the synchronous CoverageEligibilityRequest pattern. High-volume batch verification — such as eligibility checks the night before a full appointment schedule — is typically done via X12 270 batch files or payer portal bulk APIs, not FHIR. The FHIR eligibility resource is optimized for interactive, patient-specific use.

Handle partial responses. Payers are not required to return benefit detail for every service category. A response may return inforce: true with no item entries, or with items for some categories but not the one queried. Provider systems must handle the absence of expected benefit items gracefully, rather than treating a missing item as a denial or as zero coverage.


Common mistakes

Using eligibility as a substitute for prior authorization. An eligibility response saying authorizationRequired: false for a service on a specific date is not a guarantee — coverage rules can change, and some services require PA based on clinical context the eligibility system doesn’t have. When in doubt, verify with the payer.

Omitting purpose. A CoverageEligibilityRequest without purpose is invalid (required field). Always specify what you are asking for. Sending a request that asks for everything when you only need auth requirements wastes processing time and returns more data than needed.

Not using item for service-specific checks. A top-level eligibility check (no item) tells you the patient is covered but not whether the specific service requires PA. For point-of-care authorization checking, always include the service code in item.

Treating the response as real-time payment authorization. The response tells you about benefit design, not about whether a specific claim will be paid. A covered service can still be denied at adjudication for medical necessity, coding errors, or missing documentation.

Not propagating authorizationUrl. When authorizationRequired: true is returned, the authorizationUrl tells the provider system where to get PA documentation requirements. Systems that ignore this field miss the entry point into the payer’s PA process.

Assuming inforce: true means full coverage. A patient can be actively enrolled (inforce: true) but have exceeded their annual benefit limit for the specific service, or have the service excluded from their plan. inforce confirms the coverage is active — not that the specific service is covered or affordable. Always check the item-level benefit detail.

Not handling error in the response. CoverageEligibilityResponse can include an error array with coded reasons when the request could not be fully processed — invalid member ID, unknown subscriber, policy terminated. A response with outcome: error does not necessarily mean the patient is uncovered; it often means the request had a data quality problem (wrong member ID, wrong payer routing). Provider systems that don’t surface error codes to staff will silently fail eligibility checks.

See also

Section: fhir Content Type: reference Audience: technical
FHIR Versions:
R4 R5
Published: 30/11/2022 Modified: 03/02/2026 12 min read
Keywords: FHIR CoverageEligibilityRequest CoverageEligibilityResponse eligibility check benefit discovery authorizationRequired X12 270 271 real-time eligibility coverage verification