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" |
| status | FinancialResourceStatusCodes | Required | Claim adjudication status: ACTIVE, CANCELLED, DRAFT, ENTERED_IN_ERROR |
| identifier | List<Identifier> | Optional | Claim Number is the entry where type.coding[].code == "uc" |
| type | CodeableConcept | Optional | Claim Type (Medical/Pharmacy/Dental/Vision/Lab) — code from system == "http://terminology.hl7.org/CodeSystem/claim-type" |
| use | ClaimUseCodes | Optional | Intended use of the claim: CLAIM, PREAUTHORIZATION, PREDETERMINATION |
| patient | Reference | Optional | Member Name is patient.display |
| billablePeriod | Period | Optional | Service Date(s): start–end |
| created | String | Optional | Claim creation date; sort tiebreaker |
| provider | Reference | Optional | Provider display is provider.display |
| outcome | RemittanceOutcomeCodes | Optional | One of three inputs for derived Claim Status: QUEUED, COMPLETE, ERROR, PARTIAL |
| payment | ExplanationOfBenefitPayment | Optional | ExplanationOfBenefitPayment.type is the third input for derived Claim Status |
| item | List<ExplanationOfBenefitItem> | Optional | Claim line items; Description is item[n].productOrService.text or ...coding[0].display |
| total | List<ExplanationOfBenefitTotal> | Optional | Powers Billed / Insurance Paid / You Paid |
ExplanationOfBenefitTotal — filter category.coding[].code: "submitted" → Billed; "benefit" or "paidtopatient" → Insurance Paid; "paidbypatient" → You Paid.
ExplanationOfBenefitPayment fields
| Field | Type | Required | Notes |
|---|---|---|---|
| id | String | Optional | Unique identifier for the payment record |
| type | CodeableConcept | Optional | Partial vs. complete payment |
| amount | Money | Optional | Payable amount after adjustment |
| adjustment | Money | Optional | Payment adjustment for non-claim issues (e.g., prior overpayment) |
| adjustmentReason | CodeableConcept | Optional | Explanation for the adjustment |
| date | Date | Optional | Expected date of payment |
ExplanationOfBenefitItem fields
| Field | Type | Required | Notes |
|---|---|---|---|
| id | String | Optional | Unique identifier for the item |
| sequence | Int | Optional | Position of this item in the claim |
| productOrService | CodeableConcept | Optional | Source of the claim-line Description — read .text, fall back to .coding[0].display |
| net | Money | Optional | Total cost for this line item |
| quantity | Quantity | Optional | Count of products/services |
| revenue | CodeableConcept | Optional | Revenue or cost-center code |
| servicedDate | Date | Optional | Date of service for this line item |
| servicedPeriod | Period | Optional | Date range of service, when the item spans more than one day |
| modifier | List<CodeableConcept> | Optional | Item typification/modifier codes |
| bodySite | CodeableConcept | Optional | Anatomical location where the service was performed |
| locationCodeableConcept | CodeableConcept | Optional | Where the product or service was provided |
| noteNumber | List<Int> | Optional | Note numbers applicable to this item |
| adjudication | List<ExplanationOfBenefitAdjudication> | Optional | Item-level adjudication detail |
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 about 13 hours ago
