Insurance Claims
Use the b.well Kotlin SDK to read a user's claims — service dates, billed/paid amounts, and claim status — for all plans or for one specific plan.
New to the SDK? See Initialize and Authenticate before making your first call.
What can you do?
- Get all claims for the current user
- Get claims for one specific insurance plan
- Sort claims by service date instead of last-updated time
- Read billed, insurance-paid, and you-paid amounts from a claim
- Determine claim status from outcome, status, and payment.type
Need the full schema or error reference? Jump to Reference or Troubleshooting.
📘 Related Documents
- Filtering claims to one plan? You'll need a
Coverage.idfirst — see Insurance Coverage.
Get all claims for the current user
Method Signature :
suspend fun getExplanationOfBenefits(request: ExplanationOfBenefitRequest?): BWellResult<ExplanationOfBenefit>
Example code :
val eobRequest = ExplanationOfBenefitRequest.Builder()
.sort(listOf("-billablePeriod.start", "-created")) // Service date DESC
.page(0)
.pageSize(20)
.build()
viewLifecycleOwner.lifecycleScope.launch {
when (val result = BWellSdk.financials.getExplanationOfBenefits(eobRequest)) {
is BWellResult.ResourceCollection -> {
val claims = result.data ?: emptyList()
println("Found ${claims.size} claim(s)")
}
else -> {
println("getExplanationOfBenefits failed: ${result.error}")
}
}
}📘 Notes
getExplanationOfBenefitsreturns a sealedBWellResult<ExplanationOfBenefit>— same pattern asgetCoverages. Pattern-match withwhen; there is no.data()method..patient(patientId)/.patients(...)on the builder scope to one or more patients — omit to fetch everything the authenticated user can see.- An empty data list is a valid state (e.g. a brand-new plan with no claim history yet), not an error.
Get claims for one specific insurance plan
fun getClaimsForPlan(coverageId: String) {
// coverageId is a bare Coverage.id from getCoverages — a "Coverage/"-prefixed
// reference does not match. Requires b.well Kotlin SDK v1.18.0+.
val eobRequest = ExplanationOfBenefitRequest.Builder()
.coverage(coverageId)
.sort(listOf("-billablePeriod.start", "-created"))
.page(0)
.pageSize(20)
.build()
viewLifecycleOwner.lifecycleScope.launch {
when (val result = BWellSdk.financials.getExplanationOfBenefits(eobRequest)) {
is BWellResult.ResourceCollection -> {
val claims = result.data ?: emptyList()
println("Found ${claims.size} claim(s) for this plan")
}
else -> {
println("getExplanationOfBenefits failed: ${result.error}")
}
}
}
}📘 Notes
- This is a second, distinct server-side request built with
.coverage(coverageId)— it is not a client-side filter over the results of "Get all claims." .coverage(coverageId)requires b.well Kotlin SDK v1.18.0 or later. On older versions the builder method doesn't exist.- An empty result here is indistinguishable from "plan has no claims yet" — both return an empty data list, not an error.
Sort claims by service date instead of last-updated time
.sort(listOf("-billablePeriod.start", "-created")) // service date DESC, tiebreak on created📘 Notes
- If
.sort(...)isn't called, the request silently defaults tolistOf("-meta.lastUpdated")— server write time, not Service Date. This does not match the b.well Insurance embeddable's default ordering. - Always set
.sort(...)explicitly.-billablePeriod.startis the primary key (service date descending);-createdbreaks ties for claims with the same service date.
Read billed, insurance-paid, and you-paid amounts from a claim
val eob: ExplanationOfBenefit = /* one entry from the ResourceCollection above */
val billed = eob.total
?.firstOrNull { it.category?.coding?.any { c -> c.code == "submitted" } == true }?.amount
// Insurance Paid can appear under either code depending on the payor — check both
val insurancePaid = eob.total
?.firstOrNull { it.category?.coding?.any { c -> c.code == "benefit" || c.code == "paidtopatient" } == true }?.amount
val youPaid = eob.total
?.firstOrNull { it.category?.coding?.any { c -> c.code == "paidbypatient" } == true }?.amount📘 Notes
- Checking only "benefit" (or only "paidtopatient") for Insurance Paid misses claims from payors that use the other code — always check both in the same filter, as shown.
Determine claim status from outcome, status, and payment.type
val outcome = eob.outcome
val status = eob.status
val paymentType = eob.payment?.type
val claimType = eob.type?.coding
?.firstOrNull { it.system == "http://terminology.hl7.org/CodeSystem/claim-type" }
?.code // e.g. "medical", "pharmacy", "dental", "vision", "lab"📘 Notes
- There is no single field on
ExplanationOfBenefitthat represents a display-ready claim status —outcome,status, andpayment.typeare captured separately and combined by the caller. - For claim-type icons, key off
code("medical", "pharmacy", etc.), nevertype.coding[].display— display text isn't guaranteed to be stable across payors.
Reference
Result type cheat sheet
| Method | Returns | How to read it |
|---|---|---|
BWellSdk.financials.getExplanationOfBenefits(...) | BWellResult<ExplanationOfBenefit> | Pattern-match with when or as?. is BWellResult.ResourceCollection → .data: List<ExplanationOfBenefit>?. Any other branch → .error: OperationOutcome. |
ExplanationOfBenefitRequest fields
| Builder method | Required? | Notes |
|---|---|---|
.patient(patientId) / .patients(...) | Optional | Scope to one or more patients |
.coverage(coverageId) / .coverages(...) | Optional | Scope to claims tied to one or more Coverage ids — requires SDK v1.18.0+ |
.id(...) / .ids(...) | Optional | Fetch specific claim(s) by id |
.lastUpdated(...) | Optional | Filter by server last-write time |
.sort(List<String>) | Optional | FHIR _sort tokens; - prefix = descending. Defaults to ["-meta.lastUpdated"] if omitted — see notes above |
.page(n) / .pageSize(n) | Optional | Pagination — defaults to 0 / SDK standard page size |
ExplanationOfBenefit response shape
| Field | Type | Required | Notes |
|---|---|---|---|
id | String | Required | Unique identifier |
resourceType | String | Required | Always "ExplanationOfBenefit" |
meta | Meta | Optional | Resource metadata |
identifier | List<Identifier> | Optional | Claim Number is the entry where type.coding[].code == "uc" |
status | FinancialResourceStatusCodes | Required | Claim adjudication status |
type | CodeableConcept | Optional | Claim Type (Medical/Pharmacy/Dental/Vision/Lab) — code from system == "http://terminology.hl7.org/CodeSystem/claim-type" |
subType | CodeableConcept | Optional | Additional classification of the claim type |
use | ClaimUseCodes | Optional | Intended use of the claim |
patient | Reference | Optional | Member Name is patient.display |
billablePeriod | Period | Optional | Service Date(s): start–end |
benefitPeriod | Period | Optional | Period during which the benefit coverage is active |
created | String | Optional | Claim creation date; sort tiebreaker |
insurer | Reference | Optional | Party responsible for the claim |
provider | Reference | Optional | Provider display is provider.display |
outcome | RemittanceOutcomeCodes | Optional | One of three inputs for derived Claim Status |
disposition | String | Optional | Human-readable description of the adjudication status |
careTeam | List<…> | Optional | Members of the care team |
diagnosis | List<…> | Optional | Clinical diagnoses relevant to the claim |
insurance | List<…> | Optional | Insurance coverages relevant to the claim. insurance[].coverage is what .coverage(coverageId) filters on |
item | List<ExplanationOfBenefitItem> | Optional | Claim line items; Description is item[n].productOrService.text or ...coding[0].display |
adjudication | List<…> | Optional | Adjudication detail at the claim level. Distinct from item[].adjudication, which is per line item |
total | List<ExplanationOfBenefitTotal> | Optional | Powers Billed / Insurance Paid / You Paid |
supportingInfo | List<…> | Optional | Supporting information relevant to the claim |
payment | Payment | Optional | payment.type is the third input for derived Claim Status |
payee | Reference | Optional | Party receiving payment |
related | List<…> | Optional | Related claims that may be relevant to processing this claim |
processNote | List<…> | Optional | Note text associated with claim processing |
Claim-level vs item-level adjudication
ExplanationOfBenefit.adjudicationandExplanationOfBenefitItem.adjudicationare separate lists. Claim-level adjudication describes the claim as a whole; item-level adjudication describes one line. Reading one when you meant the other is a common source of totals that do not reconcile.
ExplanationOfBenefitTotal
| Field | Type | Notes |
|---|---|---|
category | CodeableConcept | Filter by category.coding[].code. "submitted" is Billed; "benefit" or "paidtopatient" is Insurance Paid; "paidbypatient" is You Paid |
amount | Money | Total amount for this category |
ExplanationOfBenefitItem
| Field | Type | Notes |
|---|---|---|
id | String | Unique identifier for the item |
sequence | Int | Position of this item in the claim |
productOrService | CodeableConcept | Product or service provided. Source of the claim-line Description |
noteNumber | List<Int> | Note numbers that apply to this item |
adjudication | List<…> | Adjudication detail for this item |
bodySite | CodeableConcept | Anatomical location where the service was performed |
locationCodeableConcept | CodeableConcept | Where the product or service was provided |
modifier | List<CodeableConcept> | Item typification or modifier codes |
net | Money | Total item cost |
quantity | Quantity | Count of products or services |
revenue | CodeableConcept | Revenue or cost center code |
servicedDate | String | Date of service or product delivery |
servicedPeriod | Period | Date range of service or product delivery |
Annotated shape
{
"id": "eob-77213",
"resourceType": "ExplanationOfBenefit",
"status": "active",
"type": { "coding": [
{ "system": "http://terminology.hl7.org/CodeSystem/claim-type", "code": "medical" }
]},
"patient": { "display": "Jordan Smith" },
"provider": { "display": "Dr. Alicia Chen" },
"billablePeriod": { "start": "2026-03-04", "end": "2026-03-04" },
"created": "2026-03-10",
"identifier": [
{ "type": { "coding": [{ "code": "uc" }] }, "value": "CLM-556213" }
],
"total": [
{ "category": { "coding": [{ "code": "submitted" }] }, "amount": { "value": 420.00 } },
{ "category": { "coding": [{ "code": "benefit" }] }, "amount": { "value": 336.00 } },
{ "category": { "coding": [{ "code": "paidbypatient" }] }, "amount": { "value": 84.00 } }
]
}Troubleshooting
Each heading below is the symptom or error you may encounter. Search this section for the closest match to what you're hitting.
Issue: Does not compile: data is not a member of BWellResult<ExplanationOfBenefit> You accessed .data before narrowing to BWellResult.ResourceCollection.
Fix: Pattern-match with when or as? first.
Issue: getExplanationOfBenefits returns an error result where it used to succeed The session is missing or expired.
Fix: Check the non-ResourceCollection branch and inspect result.error. Re-run SDK initialization/authentication and retry.
Issue: Claims come back in the wrong order .sort(...) wasn't called, so the request silently used the default -meta.lastUpdated order instead of Service Date.
Fix: Always pass .sort(listOf("-billablePeriod.start", "-created")) explicitly.
Issue: .coverage(coverageId) has no effect, or the build fails The Coverage-filtered request requires b.well Kotlin SDK v1.18.0 or later. On older SDK versions the builder method is unavailable.
Fix: Confirm the SDK version in use before adopting the plan-filtered claims flow.
Issue: Insurance Paid amount looks wrong or missing Filtering total for only "benefit" (or only "paidtopatient") misses claims from payors that use the other code.
Fix: Check both "benefit" and "paidtopatient" in the same filter.
Issue: Claim-type icon doesn't match the claim The icon logic reads type.coding[].display instead of code, and display text varies by payor.
Fix: Key icon selection off code from the http://terminology.hl7.org/CodeSystem/claim-type system, never display.
If your issue isn't listed here, reach out to support and include: the SDK version, the exact ExplanationOfBenefitRequest builder calls used, and the full OperationOutcome from result.error if the failure branch was hit.
Updated 28 days ago
