Skip to main content
A managed Laso account can have real banking rails attached to it: a US bank account that receives dollars and turns them into USDC in the managed wallet, and a crypto address that pays dollars out to a bank account. Your agent can open both, and retrieve the resulting bank details, through ordinary authenticated calls. One step is deliberately not automatable. Identity verification has to be completed by the person who owns the account. Everything around it, including the rest of the bank application, is something your agent can do on its own.
These calls are Firebase callables at https://us-central1-kyc-ts.cloudfunctions.net/<name>, authorized with the id_token from sign-in. Arguments are wrapped in a data object and replies in a result object, the same convention as the managed wallet.

The two account types

On-ramp: dollars in

A virtual US bank account with real ACH and wire details. Dollars sent to it are converted and delivered as USDC to the managed wallet. Use it to get paid, or to fund the agent from a normal bank transfer.

Off-ramp: dollars out

A Solana deposit address. USDC sent to it is paid out automatically to a bank account you registered beforehand. Use it to pay someone in dollars.

Step 1: open the banking profile

If the owner has not verified their identity yet, this returns a link rather than a profile:
This is the one step your agent cannot do. Give kycUrl to your human, wait for them to finish, then call again. Never attempt to complete an identity check on someone else’s behalf.
Once they have verified, the same call returns profileId, applicationStatus, and an applicationUrl. Identity carries over automatically, so what remains is a short set of non-identity questions.

Step 2: complete the application

Your agent can answer the remaining questions itself. Start by reading what is outstanding:
If hostedOnly is true, this particular application can only be finished on the partner’s own page. Give the human applicationUrl and skip ahead to step 3. Otherwise submit the details:
These are the account owner’s real personal details on a real bank application. Send only values the owner actually gave you. Do not invent, guess, or infer them: a wrong answer is a compliance problem for your human, not a retryable error.
Then submit for approval:
The required legal attestations (e-sign, terms of service, privacy policy, funds transfer agreement) are accepted on the owner’s behalf as part of this call, so only make it once they have agreed to those terms. Retrying is safe: attestations already recorded are not sent again. Poll getBankingProfileStatus with the same body until applicationStatus shows approval.

Step 3: open the account

For an on-ramp:
For an off-ramp, first register who gets paid, then point the account at them:
A recipient needs an address before a bank account can be attached to it. That is the postal address of whoever is being paid, not the bank’s address: street1, optional street2, city, region, postal_code, country. A crypto destination does not need one; fiat_us and fiat_iban do, and step 2 fails with failed-precondition without it.Already created a recipient without an address? Pass recipientAddress to addBankingDestination and it sets the address before attaching the account, so you do not have to create a second recipient.
Use only the address and bank details your human actually gave you. Do not guess an address to get past the requirement. createBankingAccount is idempotent. Calling it again returns the account that already exists rather than opening a second one.

Step 4: retrieve your bank details

To read the details back at any time, without creating anything:
Each entry carries accountId, accountType, and status, plus whichever side applies:
  • On-ramp: bankAccount with account_holder_name, account_number, aba_routing_number, bank_name, bank_address, and capabilities such as ["ach","fedwire"]. These are the details to give whoever is paying.
  • Off-ramp: depositCryptoAddress to send USDC to, and the fiatDestinationId it pays out to.
These are real bank details. Share them only with people who are meant to pay the account, and treat the account number like a credential.

Following the money

Every ramp transaction is mirrored as it settles, so you can follow one without polling the partner:
A transaction reports status (pending, then completed, failed, or cancelled), direction (onramp or offramp), amount with amountAsset, sendAmount with sendAsset, and txHash once it settles on-chain. Your human is notified automatically when one reaches a terminal state.
A fiat on-ramp settles in two stages. The bank transfer clears first, and the USDC arrives in the managed wallet minutes to hours later. Both stages show up on your human’s dashboard, so a gap between “bank transfer complete” and the wallet balance moving is expected rather than an error.

What your agent can and cannot do