# The Connect Account Widget

The Connect Account Widget is a single-use, time-limited URL for a Sail-rendered flow:

* Connecting an account
* Reconnecting one
* Uploading a receipt

Sail's API calls this a hosted session. This page explains why it exists and what each of the three flows does.

## How it works and why it exists

It works by calling the [Create Hosted Session](/reference/connect-account-widgets/post-hosted-sessions) endpoint server-side with a `user_id` and a `flow`, and Sail returns a single-use, time-limited `url` and an `expires_at` timestamp. You embed that URL, and once the user completes the flow inside it, or its time runs out, the session ends.

It exists so your backend never has to see, store, or transmit a user's actual login: a user's bank, merchant, or HSA/FSA administrator credentials are entered only inside it, and stored only by Sail. Your backend still authenticates every other API call with a partner key, but a user's own credentials never pass through your systems.

## The widget's three flows

The `flow` you request determines what the user sees.

* `connect_account`: the only way to establish a Sail-managed connection (`card`, `store`, or `benefit_account`). Requires `connection_type` in `options`.
* `reconnect`: re-authenticates an existing Sail-managed connection once its credentials go stale. Requires `connection_id` in `options`. Calling this against an `external` connection, which has no credentials to refresh, returns `409 connection_not_reconnectable`.
* `upload_receipt`: lets a user submit an itemized receipt, optionally against a specific `itemization_required` expense by passing `expense_id`.

Both `connect_account` and `reconnect` accept a `modal` option to render the flow as an overlay instead of a full-page redirect.

## Scope and expiry

Not every integration uses the Connect Account Widget. If you're pushing your own transaction data through an external connection, there's no end-user login step at all, the connection is created directly through the API with no widget involved.

When a session is used, it doesn't necessarily complete: a session that expires before the user finishes fires a `hosted_session.expired` webhook, naming the `session_id` and `flow`. Treat this as a prompt to give the user a way to start over, not as an error to surface directly.

## Next steps

* To connect a user's card or store accounts, see [Enrich Transactions with Item-Level Data](/docs/guides/enrich-transactions-with-item-level-data).
* To connect a user's HSA/FSA administrator, see [Connect HSA/FSA Accounts](/docs/guides/connect-hsa-fsa-accounts).
* To see how the three connection types relate, see [Account Connections](/docs/concepts/account-connections).