Free learning / 50-minute FHIR lab
FHIR eligibility: read the answer before saying approved
Understand FHIR, match an eligibility response to its business question and run fifteen synthetic cases that keep a missing requirement separate from approval or payment.
No account needed. Use your own copy for writing and keep the original as a reference.
Engineering lab library / Run locally
Read the eligibility response in running code.
Predict fifteen cases, expose an invented negative answer and select the intended coverage before reading its service requirement.
Real read-only Python interpretation of invented FHIR R4 records. No network, patient data or source writes. This teaching subset does not establish authorization approval or payment.
Start here / Python 3.11+ · Standard library
FHIR eligibility interpretation lab
Inspect fifteen real interpretations, reproduce an invented negative answer and match the intended plan.
Python 3.11+ · standard library only · synthetic FHIR R4 subset
An operations coordinator asks, “The system says active and complete. Is the visit approved?” Learn what the response actually establishes, then prove your interpretation in running code. Begin with the healthcare business introduction if eligibility and prior authorization are new terms.
Allow 50 minutes. You need Python 3.11 or newer and a terminal. The original lab uses invented references, a fictional service code and no network, patient records, API keys or database. Its narrow FHIR R4 teaching contract is not a complete profile validator or payer integration.
1. What FHIR is, in familiar terms
FHIR stands for Fast Healthcare Interoperability Resources, pronounced “fire”. It is a standard for exchanging healthcare information. A resource is a structured record with defined fields and references to related records. A profile specifies more particular rules for an exchange. Think of shared order, shipment and invoice contracts: receiving a valid invoice does not establish that someone paid it.
This exercise uses CoverageEligibilityResponse from the published R4 / 4.0.1 specification. It is not a claim payment record. Establish the actual version and profile before adapting it. Start with a business question, not a field called status.
Write one sentence explaining each: standard, resource, profile, eligibility and authorization requirement. Then answer the coordinator in plain language before opening a code editor.
2. Read five different questions
| Signal | What the lab reads | What it does not establish |
|---|---|---|
| HTTP 200 | Successful exchange | A business approval |
status: active | Resource lifecycle | The plan is in force |
outcome: complete | Processing outcome | The service is approved |
insurance[i].inforce | Coverage observation | Claim payment |
item[j].authorizationRequired | Service requirement | Granted authorization |
Match patient, payer, request, coverage, service date, coding system and code before interpreting the item. Array order and a familiar display name are not enough. This lab requires one exact date and one matching plan and service. Other valid forms need an explicitly extended contract.
Walk the visual below. At each event, say what the coordinator now knows and what is still unanswered. When the final event removes the requirement field, keep the answer unknown. Not supplied is different from false. Even a genuine preauthorization does not promise payment.
UNDERSTAND THE SYSTEM
Read the requirement before saying approved
An invented eligibility response arrives successfully. Follow what each field answers, then see the question that is still open. This is a FHIR R4 teaching example, not a patient record.
See what moves and why.
Read the connections in plain English
- 01Response arrives → FHIR response
Transport success is only the start of interpretation.
- 02FHIR response → Match the question
This mapper accepts an active, complete response to the exact synthetic question.
- 03Match the question → Coverage fact
Do not take insurance[0] just because it is first.
- 04Coverage fact → Service requirement
Match the requested service's coding namespace and code.
- 05Service requirement → Staff handoff
Carry the reported requirement without inventing an approval.
Check your understanding: The response is active and complete, but inforce is false. Is the plan active for this question?
The source reports that the matching coverage is not in force. active describes the resource, not the plan. Route the coverage observation to benefits operations; do not turn it into a clinical or claim decision.
3. Run the eligibility lab
In the online workbook, first explore seven recorded cases below. Read the actual fields, predict the interpretation and inspect the evidence paths. Compare the unchanged source with a deliberately broken default. These are saved Python observations, not code executing in your browser.
Then save the Python download in a new exercise folder and reproduce all fifteen cases. Predict the results before opening the output.
python3 fde-healthcare-eligibility.py --json > eligibility-guarded.json
python3 fde-healthcare-eligibility.py --default-missing-to-false --json > eligibility-broken.jsonThe program interprets fifteen synthetic inputs. It writes no records; the shell redirects the report into the two files you requested. Inspect input, http_status, result.evidence, trace, owner and next_action together. An exit code of zero means a report was produced, not that every case supports a handoff.
| Case group | Your prediction |
|---|---|
| Required, not required, requirement unreported | Keep true, false and unknown distinct |
| Coverage not in force or not reported | Identify a benefits observation versus missing evidence |
| Partial response, cancelled response, transport failure | Explain why the mapper stops without declaring denial |
| Wrong patient, coverage, service code or date | Refuse to answer a different question |
| Ambiguous coverage or service | Do not guess among duplicate matches |
| Matching plan second | Select by the intended reference, not first position |
In requirement-unreported, guarded mode returns requirement_unreported. Broken mode fabricates authorization_not_required by defaulting the absent field to false. Show the missing input and invented output side by side. The other fourteen cases should keep their business results. The defect is a plausible answer with no supporting field.
For a compact report, omit --json. For the array-selection example:
python3 fde-healthcare-eligibility.py --scenario matching-plan-second --jsonFind insurance[1].inforce and insurance[1].item[0].authorizationRequired in the evidence. Explain why the other plan's observation cannot answer this question.
FHIR ELIGIBILITY / READ THE ACTUAL FIELDS
What can this response tell the coordinator?
Read the question and source, make a prediction, then inspect the evidence the Python lab actually used.
Recorded Python runs · Synthetic R4 examples · No patient dataA missing answer is not a negative answer
The requested plan is in force. Processing is complete. The service item does not include an authorization requirement. What can staff say?
01 / THE QUESTION WE NEED TO ANSWER
Does this service require authorization?
- Coverage
- Coverage/SYNTHETIC-PLAN
- Service date
- 2026-10-22
- Service code
- SYNTHETIC-VISIT
- Coding system
- https://example.invalid/synthetic-services
02 / THE SOURCE WE RECEIVED
insurance[0] / SAME COVERAGE REFERENCE
Coverage/SYNTHETIC-PLAN
- Coverage in force
inforcetrue · Yes
item[0] / SERVICE
SYNTHETIC-VISIThttps://example.invalid/synthetic-services
insurance[0].item[0].authorizationRequiredInspect the exact JSON and question
The fixtures also bind patient, payer and the original request. The compact view above does not replace these checks.
{
"question": {
"patient": "Patient/SYNTHETIC-PERSON",
"coverage": "Coverage/SYNTHETIC-PLAN",
"request": "CoverageEligibilityRequest/SYNTHETIC-REQUEST",
"insurer": "Organization/SYNTHETIC-PAYER",
"service_date": "2026-10-22",
"code_system": "https://example.invalid/synthetic-services",
"service_code": "SYNTHETIC-VISIT"
},
"http_status": 200,
"response": {
"resourceType": "CoverageEligibilityResponse",
"id": "SYNTHETIC-RESPONSE",
"status": "active",
"purpose": [
"validation",
"auth-requirements"
],
"patient": {
"reference": "Patient/SYNTHETIC-PERSON"
},
"servicedDate": "2026-10-22",
"created": "2026-10-22T13:00:00Z",
"request": {
"reference": "CoverageEligibilityRequest/SYNTHETIC-REQUEST"
},
"outcome": "complete",
"insurer": {
"reference": "Organization/SYNTHETIC-PAYER"
},
"insurance": [
{
"coverage": {
"reference": "Coverage/SYNTHETIC-PLAN"
},
"inforce": true,
"item": [
{
"productOrService": {
"coding": [
{
"system": "https://example.invalid/synthetic-services",
"code": "SYNTHETIC-VISIT"
}
]
}
}
]
}
]
}
}Predict or go straight to the evidence. No grade or completion is recorded.
4. Change the evidence, then predict again
In a copy of scenarios(), add these two cases using its existing add helper:
add("wrong-code-system", lambda r: r["insurance"][0]["item"][0]["productOrService"]["coding"][0].update(system="https://example.invalid/other"))
add("string-false", lambda r: r["insurance"][0]["item"][0].update(authorizationRequired="false"))The same service code under another coding system must not match. The string "false" must not become a boolean through truthiness. Run the changed file and compare your prediction with service_not_unique and invalid_requirement_flag. Explain the exact predicate that enforces each result.
Now change the service date while leaving every other field alone. Ask whether the original handoff is still supported. Repeating the same inputs should produce the same result and leave the input records unchanged.
5. Give staff a useful next action
Use this handoff structure: business question, source reference, date, selected path, supported statement, unanswered question and receiving owner.
Example: “For SYNTHETIC-PLAN on 22 October 2026, the matched service reports authorization required. Evidence: insurance[1].item[0].authorizationRequired. Approval, payment and patient cost are not established here. Eligibility operations should route the requirement through the agreed authorization process.”
For a missing field, request the missing answer. Do not replace “unknown” with “not approved”. For reported coverage not in force, route the observation to benefits operations and the established human process. This administrative mapper has no authority to decide care.
An agent can draft readable text from the packet. The deterministic mapper preserves the business facts; the reviewer checks the draft against them. Before a real pilot, demonstrate a permitted and authenticated source adapter, reference mapping, profile validation, freshness handling and an owned exception route. Do not use real health records in this exercise.
6. Rehearse the receiving review
Use a peer or facilitator, or label the exercise self-rehearsed. This workbook does not book a human mentor.
- Explain what FHIR is without starting with API field names.
- Show the invented negative answer in the broken run.
- Let the reviewer change a plan, date or coding system. Predict before running.
- Show the exact evidence path for the supported observation.
- Name an unanswered business question and the role responsible for it.
- Ask what would change for a period or a profile-specific modifier. Keep that adapter work explicit.
Keep your dictionary, both original reports, changed Python file, unseen-case outputs and staff handoff. Assess whether someone else can reproduce the interpretation and act on the exception, not whether the explanation sounds confident.
7. Sources and the next lesson
Original instruction and invented fixtures, checked against primary references on 22 October 2026:
- HL7: FHIR overview.
- HL7: CoverageEligibilityResponse in R4.
- HL7: eligibility element definitions.
- HealthCare.gov: preauthorization and its limits.
Continue with the protected eligibility lesson and knowledge checks, then the receiving-owner review. To compare business contexts, explore financial-services operations.