TheFhirStorm

Three ways to check eligibility: 270/271, portal, EHR

Claims data · · Abhinav Srivastava

A patient books a visit for Monday. Your scheduler needs to know whether the plan is active and what the copay is. The practice management system shows an insurance record with a member ID and a plan name from a visit last year. You have three ways to find out, and they return different answers.

The 270/271 transaction

HIPAA adopts the X12 270 inquiry and 271 response, version 005010X279, as the eligibility standard in 45 CFR 162.1202. 45 CFR 162.1203 adds the CAQH CORE Phase I and Phase II operating rules, in force since January 1, 2013. CMS states that the rules require health plans to respond in real time (CMS).

The rules shape what comes back. Under the CORE Eligibility and Benefits Infrastructure Rule, a health plan must return a 271, or a 999 rejection, within 20 seconds of a real-time 270. Conformance is 90 percent of requests in a calendar month. The system must be available 90 percent of each calendar week.

The CORE 260 data content rule lists 51 service type codes a plan must answer for an explicit inquiry, 12 of them carried over from Phase I. For each code the plan returns coverage status. For most codes it also returns patient financial responsibility: base and remaining deductible, copay and coinsurance. The plan may withhold cost share for a short list, including 1 (medical care), 35 (dental), 88 (pharmacy), AL (vision) and MH (mental health). It must still return coverage status for those codes. For code 30, health benefit plan coverage, the base and remaining plan deductible are always required.

The data arrives in EB segments inside loop 2110C for a subscriber or 2110D for a dependent. CORE 260 specifies the remaining plan deductible like this:

EB*C*IND*30***29*1250~

EB01 C means deductible, EB02 IND means individual, EB03 30 is the service type, EB06 29 means remaining, and EB07 is the amount. Copay uses EB01 B and coinsurance uses EB01 A. EB12 carries Y or N for in-network, and a plan whose deductible differs by network returns two EB segments.

EB03 repeats. A CMS compliance bulletin from June 2022 states that EB03 may repeat up to 99 times in one segment. A plan that sends one 2110C loop per service type with otherwise identical data violates the standard. Your parser must split EB03 on the repetition separator. The CMS HETS companion guide shows a Medicare Part A response with 14 service types in one segment:

EB*1**30^42^45^48^49^69^76^83^A5^A7^AG^BT^BU^BV*MA~
DTP*291*RD8*CCYYMMDD-CCYYMMDD~

EB01 1 means active coverage. The HETS guide uses EB01 6 for inactive and I for non-covered. The DTP 291 segment carries the eligibility dates.

Rejections come back in AAA segments. HETS returns AAA03 72 when the submitted Medicare ID is not the active one, 62 when the date of service is outside the allowed range, and 42 when it cannot process the request. The code list is shared, but each payer's companion guide states which codes it sends.

You reach the payer through a clearinghouse. The clearinghouse routes on payer ID, wraps the envelope, and returns the 271, usually also as JSON. The content is the payer's. A clearinghouse cannot add a deductible the payer left out.

The payer portal

A portal shows the same adjudication system through a web page. It often shows more than the 271: accumulators by benefit, prior authorization rules, and network status for one provider NPI. The response-time and data-content rules do not apply to it, because they apply to the standard transaction. Portal data arrives as HTML with no field names, no code sets and no schema version. To store it you capture the page, extract fields, and record the time and the user who read them.

The EHR's built-in check

A practice management system with built-in eligibility runs a 270/271 through its clearinghouse when a visit is scheduled. It stores the result on the insurance record. The FHIR layer exposes that record as a US Core Coverage resource: member ID or subscriberId, status, type, beneficiary, relationship, period, payor, and group and plan class values. The profile warns that status alone does not confirm coverage. Coverage carries no deductible, copay or coinsurance, and no timestamp of the check behind it beyond meta.lastUpdated.

Vendors gate the write side. eClinicalWorks lists Coverage read as available, and Coverage create, update and delete as operations that require a contract (documentation).

Where the answers differ

Field271PortalEHR Coverage
Active on date of serviceEB01 1 to 5 active, 6 inactive, with DTP datesYes or no, with datesstatus plus period
Remaining deductibleEB01 C, EB06 29, EB07 amountOften per benefitNot present
CopayEB01 B, EB07 amount, per service typePer serviceVendor field, not in US Core
NetworkEB12 Y or NProvider lookupNot present
Payer rankNot returnedSometimesVendor field

How to store the result

Store each check as its own record. Do not overwrite the insurance row. Record the source (271, portal or EHR), payer ID, member ID as sent and as returned, request date, date of service, response timestamp, and the raw payload: the X12 string, the portal capture or the FHIR JSON. Store parsed benefits as rows with service type code, EB01 status, network flag, amount type, amount and time period qualifier. Keep AAA codes on rejected checks.

The scheduler then reads the latest check for this patient, this payer, service type 30, in network, and gets one answer with provenance. When the 271 and the EHR disagree, the 271 is newer and more specific. Write the member ID and plan back to the EHR only through a supported update endpoint, and keep the 271 as the record of why.

All posts