Onboarding
An onboarding session is Frame's hosted UI for collecting whatever a capability still needs to activate. Create the session for an account, redirect the account holder to the session URL, and Frame walks them through identity verification, document upload, and bank account setup — scoped to the capabilities that aren't yet active.
You don't build the forms. You don't store the documents. You hand off to a Frame-hosted flow and check the account when they come back.
When you need a session
Look at the capability's currently_due array. If it has entries, those are fields the account holder needs to supply, and an onboarding session is the easiest way to collect them.
Some common cases:
- You created an account with
kycrequested but no profile data. The KYC capability ispendingandcurrently_duelistsname,address,birthdate,ssn_last_four. Onboarding session collects all of it. - You're activating a payout flow.
card_receiverequires verified KYC plus an attached debit card. Session walks the user through both. - The account holder hasn't accepted your terms of service. Onboarding session can capture acceptance, IP, and user agent in the same flow as the rest.
If currently_due is empty across every capability, you don't need a session. The account is good.
How a session works
A session is a time-boxed handoff. The URL stays valid for the 30-minute window — the account holder can reopen it within that window if they need to — but expires after that and can't be revived.
- Create the session with
account_idand (optionally) areturn_url. The response contains a sessionurland anexpires_attimestamp. - Redirect the account holder to the session URL from your application. The URL is short-lived and tied to that specific session.
- Frame collects what's needed. The hosted flow scopes itself to exactly the requirements on file — KYC fields if
kycis pending, bank account verification ifbank_account_receiveis pending, terms-of-service capture if that's outstanding. - Account holder completes (or exits) the flow. Frame redirects them to your
return_url. - Verify on your side. Retrieve the account and inspect the capability statuses. A redirect to
return_urlmeans the user clicked through — not that every requirement was met.
The steps array on the session tells you in advance which flows are bundled into this session (["kyc"], ["kyc", "bank_account_verification"], etc.) — useful if you want to surface progress or set expectations in your UI.
Expiry
Sessions expire 30 minutes after creation. If the account holder doesn't complete the flow in time, the session URL stops working — create a new session and redirect them again. The account itself is unaffected; only the session handoff is short-lived.
Don't share session URLs over email, SMS, or any external channel. Always redirect from within your authenticated application, since the URL grants access to the account holder's verification flow.
Incremental onboarding
You don't have to collect everything upfront. Common pattern:
- Account is created with just
card_send(so they can pay). - Months later they opt into a creator payout program. You request
card_receiveon the existing account. card_receivearrivespendingwith KYC and address verification incurrently_due.- Create a fresh onboarding session — Frame scopes it to only the new requirements, not what's already on file — and redirect.
Each session is a snapshot of "what's outstanding right now." Capabilities you've already activated stay activated.
Relationship to capabilities
Sessions are how requirements get satisfied; capabilities are what the account can do. The session itself doesn't "grant" anything. It collects data, runs verifications, and updates capability statuses as results come back. If you want a programmatic equivalent — supplying KYC fields via API instead of a hosted flow — you can update the account directly with the same fields, but you'll need to handle the document-upload and verification UX yourself.
Gotchas
Symptom: the account holder completed the session and was redirected back, but the account is still pending. Why: the redirect fires when the user clicks through, not when every check resolves. KYC and bank verification can take seconds to minutes to settle. Fix: poll the account, or listen for account.activated, capability.activated, and capability.disabled webhooks rather than acting on the redirect alone.
Symptom: you created a second session before the first one expired and now the account holder has two URLs. Why: sessions don't auto-invalidate each other — both URLs remain valid until they expire individually. Fix: harmless, but if it's a problem, just send the latest URL and let the older one expire.
Symptom: the session URL works in test mode but the account holder hits a "session expired" page in production. Why: clock drift on either side, or the URL was generated more than 30 minutes before the user clicked it. Fix: generate the session immediately before redirecting, not at account creation time.
Reference
For the full session lifecycle, see POST/v1/onboarding_sessions.