Reimbursement
A reimbursement pays a user back from their own HSA or FSA for expenses Sail has already classified as eligible. This page explains what a reimbursement needs before Sail creates one, how its status changes from creation to a successful payout, and the two distinct ways it can fail.
What a reimbursement is
A reimbursement is a request to pay a user back from their own benefit account for a set of expenses. Sail doesn’t fund it, and neither does your application. It draws from a benefit_account connection, the same connection type covered in Account Connections, and it only ever returns money the user already has in that account.
Scope required
Creating, getting, or listing reimbursements needs the benefit_account key scope. Creating one also needs the benefit_account product on the funding account’s connection.
Preconditions
Two things must be true before Sail accepts a request to create a reimbursement.
- Every included expense must carry an
eligibleSection 213(d) classification. An expense that’sineligible, stillitemization_required, orlmn_requiredcan’t be reimbursed until it resolves toeligible. - The funding account’s cash balance must cover the sum of the included expenses. Sail checks that total against the account’s available balance, not against each expense individually.
An expense can only belong to one reimbursement at a time. Including an expense that isn’t eligible, or one that’s already part of an in-flight reimbursement, returns a 409 conflict error instead of creating a new reimbursement.
Creating a reimbursement
A reimbursement request names the expenses to pay back and the account to pay them from: an array of expense IDs plus the funding account_id, matching the ReimbursementCreateRequest shape. Sail responds with a Reimbursement object, identified by an ID like reimb_8c1f, whose amount field reports the sum of the included expenses as a decimal USD value (for example, 1050.50 for $1,050.50).
The status lifecycle
A reimbursement moves through four statuses on its way to a successful payout:
pending: Sail has created the reimbursement and is about to contact the funding account’s administrator.submitted: Sail has submitted the included expenses to the administrator.processing: the administrator is processing the submitted claim.completed: the administrator has finished processing the claim, and the money has moved out of the account back to the user.completedreflects money actually moving, not just the administrator approving the claim.
Once a reimbursement reaches completed, its expenses move to a reimbursed status, and a receipt document becomes available through Get Reimbursement’s receipt_url field, which stays empty until then.
Why a reimbursement fails
A failed status covers two distinct causes, both surfaced the same way today:
-
Failed to submit: something went wrong on Sail’s side before the claim reached the administrator. Sail doesn’t automatically retry, but you can resubmit the same expenses and account as a new reimbursement request.
-
Failed after submission: the administrator denied the claim. Sail returns a reason alongside the failure. Denial reasons aren’t a fixed set, since administrators’ review processes vary and are still evolving. For example, an administrator can ask for a Letter of Medical Necessity on an expense Sail classified as
eligible, since each administrator applies its own documentation standards when it reviews a claim. Afailedreason is context on that decision, not a fixed, retryable error code.LMN required after submission
Support for resolving a Letter of Medical Necessity request through Sail is on the way. We’ll update these docs as soon as it’s live.
How you find out the result
Sail sends a reimbursement.status_changed webhook on every status transition, naming the reimbursement_id, the previous_status, the new status, and a failure_reason when the new status is failed. See Receiving New Data for how to verify and deduplicate any webhook delivery, reimbursements included.
The current status is also available any time from Get Reimbursement or List Reimbursements, so polling either endpoint on any cadence stays a valid alternative to only listening for the webhook.
Next steps
- To confirm eligibility and balance, create a reimbursement, and track it to completion, see Create and Track a Reimbursement.
- To see the three ways Sail connects to an account, including the
benefit_accountconnections a reimbursement draws from, see Account Connections. - To see how an expense reaches
eligiblein the first place, see Expense Classification.