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:
| Code | What it asks | Typical use |
|---|---|---|
auth-requirements | Does this service require prior authorization? | Pre-order checks at point of care |
benefits | What are the benefit details for this service? | Cost estimation, benefit display |
discovery | What plans does this patient have with this payer? | Multi-plan or unknown-plan lookup |
validation | Is 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:
| Code | What it represents |
|---|---|
copay | Fixed copayment amount |
coinsurance | Percentage after deductible |
deductible | Deductible limit and amount used |
out-of-pocket | Annual out-of-pocket maximum and amount used |
benefit | Maximum benefit limit (e.g., visit count) |
visit | Maximum 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 CoverageEligibilityRequest | X12 270 equivalent |
|---|---|
purpose: validation | ISA header + NM1 (subscriber name loop) |
purpose: benefits | EQ Eligibility or Benefit Inquiry segment |
item.productOrService | EQ03 Service Type Code |
servicedDate | DTP Date - Service Date |
insurer | NM1 Information Source |
| FHIR CoverageEligibilityResponse | X12 271 equivalent |
|---|---|
inforce | AAA Reject Reason or EB Eligibility/Benefit information |
item.benefit | EB Eligibility/Benefit segments |
item.authorizationRequired | EB (code G - Prior Authorization Required) |
benefitPeriod | DTP 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
| Parameter | Type | Finds |
|---|---|---|
patient | reference | Eligibility requests for this patient |
status | token | Requests with this status |
created | date | Requests created on this date |
insurer | reference | Requests directed to this payer |
provider | reference | Requests submitted by this provider |
identifier | token | Request 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 apply | Requests formal approval to render a specific service |
| Non-binding; returns benefit information | Binding; generates an authorization number |
| Typically real-time (<2 seconds) | May be synchronous or pended (hours to days) |
| No authorization number generated | Returns preAuthRef that must accompany the claim |
| Does not satisfy a PA requirement | Required 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
- Claim and ClaimResponse — Claim structure and the preauthorization exchange after eligibility confirms PA is required
- Prior Authorization Workflow — end-to-end workflow from eligibility check through PA submission
- CRD (Coverage Requirements Discovery) — Da Vinci IG that queries auth requirements within the EHR ordering workflow