Skip to main content

Overview

A virtual account is a US bank account β€” account number plus ABA routing number β€” issued in your user’s own name. Funds sent to it land directly in that user’s balance, with no shared account and no manual reference matching. Virtual accounts are provisioned through banking onboarding: Capa submits the user’s verified identity to our US banking partner, the partner runs its own review, and on approval the account is created and attached to the user.
Virtual accounts are currently available for the United States (US) only. country must be US on both endpoints β€” any other value is rejected with 400.

Before You Start

The user must have completed KYB with Capa. Banking onboarding does not collect identity data of its own β€” it consumes what KYB already produced, so a user who has cleared KYB is ready to be onboarded. See Create and Verify a User.

The Flow

1

Check eligibility

Call Get Virtual Account Status to see whether the user can be onboarded.
Use canRequest to gate the action in your UI. It is true only when KYB is complete, the user has no existing virtual account, and no onboarding is already in flight.
2

Request the account

Call Request Virtual Account.
Branch on data.status β€” a 201 does not always mean a new onboarding was started:The endpoint is safe to call repeatedly β€” it returns the existing onboarding rather than starting a second one.
3

Complete KYB if it is still pending

status: "REQUIREMENTS_MISSING" means the user’s KYB is not complete. Send them to kybLink to finish it:
missingRequirements lists what is still outstanding β€” useful for surfacing a reason in your UI, but you do not need to collect those fields yourself. Completing KYB satisfies them. kybLink is optional; if it is absent, direct the user through your usual KYB flow.Once KYB is complete, call the request endpoint again.
4

Poll until completion

There is no webhook for virtual account onboarding. Poll the status endpoint until status is COMPLETED or FAILED.Approval typically takes minutes to hours, so poll every few minutes β€” not every few seconds.
5

Read the account details

Once hasVirtualAccount is true, fetch the account from List Bank Accounts:
The provisioned account appears as a normal bank account record carrying the user’s accountNumber, routingNumber, bankName, and accountType. It is stored with rampType: "CROSS_RAMP", so you can filter on that to isolate virtual accounts from bank accounts the user added themselves.

Retrying a Failed Onboarding

A FAILED onboarding is not terminal. canRequest flips back to true, and calling the request endpoint again starts a fresh attempt. If the user’s KYB is not complete, the retry returns REQUIREMENTS_MISSING rather than failing again.

What’s Next