Read an HSA/FSA Balance
Connect a user's HSA/FSA administrator and read their first balance in three calls.
Read a user's HSA/FSA balance from your own backend. Follow this quickstart to connect their administrator and pull back every account behind that login.
Requirements
Before you start, make sure you have:
- A Sail user created for your end user
- An API key with the
benefit_accountscope - A webhook endpoint configured to receive events
Step 1: Open the Connect Account Widget
Your end user needs to log into their HSA/FSA administrator before Sail can read anything. Create a session with Create Hosted Session, setting flow to connect_account and connection_type to benefit_account.
curl -X POST https://live.savewithsail.com/api/v1/hosted-sessions \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"user_id": "usr_abc123",
"flow": "connect_account",
"options": {
"connection_type": "benefit_account"
}
}'{
"url": "https://<HOSTED_SESSION_URL>",
"expires_at": "2026-08-10T15:31:07Z",
"flow": "connect_account"
}Open the url in an iframe or redirect your end user to it. The session is single-use and stops working at expires_at. Your end user's administrator credentials are entered inside Sail's iframe only, so they never reach your backend.
To skip administrator selection and open straight into one administrator's login screen, pass administrator_id in options. The List HSA/FSA Administrators endpoint returns the administrators Sail supports.
Step 2: Wait for the accounts to appear
Sail connects to the administrator and discovers the accounts behind the login after your end user finishes. Results arrive by webhook, so there's nothing to poll.
| Event | What it means |
|---|---|
connection.created | Your end user finished the widget and the connection exists. |
connection.status_changed | The connection moved to a new status, for example syncing to active. |
connection.synced | Sync finished. The data is ready to fetch. |
Fetch accounts once you receive connection.synced. One administrator login can hold more than one account, for example an HSA and a limited-purpose FSA, so expect a list rather than a single record.
Check the
Sail-Signatureheader before you process any event. Delivery is at-least-once, so deduplicate on the eventid. See Receiving New Data for both.
Step 3: Read balances
Call List Accounts & Balances to get every account under the user's connections.
curl https://live.savewithsail.com/api/v1/users/usr_abc123/accounts \
-H "Authorization: Bearer sk_live_..."{
"data": [
{
"id": "acct_77b1",
"connection_id": "conn_9f2c",
"external_id": "HE-12345678",
"name": "HealthEquity HSA",
"type": "hsa",
"start_date": "2024-01-01",
"end_date": null,
"balance": {
"cash": 1050.50,
"invested": 500.00
},
"last_sync_at": "2026-08-10T14:35:00Z"
}
],
"pagination": { "limit": 25, "offset": 0, "total": 1 }
}Amounts are decimal numbers in USD, so 1050.50 means $1,050.50.
The connection is live from here. balance is present only when the owning connection carries the benefit_account product, and end_date is null for an HSA because an HSA has no plan-year end.
Next steps
- To read full account and routing numbers for deposits, which need an ephemeral user token on top of your API key, see Connect a User's HSA/FSA.
- To understand why deposit credentials need a second key, see Scoped API Keys.
- To pay a user back from a linked account, see Reimbursement.
Updated 14 days ago