Skip to main content

Digital assets (sandbox)

A business can hold digital-asset accounts — USDC, EURC and other stablecoins — next to its bank accounts, on the same API: /v1/banking/*. Each account holds one asset. Money arrives on chain (and, for USDC, by SEPA to an IBAN), and leaves on chain, to a bank account, to another CashXChain customer, or into your other accounts.

Sandbox only

Everything in this section runs in the sandbox, at https://api.sandbox.cashxchain.com and app.sandbox.cashxchain.com. Production does not offer digital-asset accounts, wallets or sends yet: there, onboarding answers 503 digital_assets_unavailable, opening a USDC account 422 currency_unavailable, a send 422 corridor_unsupported, and the sandbox routes 404. GET /v1/banking/capabilities says what the deployment you call offers — see Capabilities.

The accounts and wallets are held at our crypto-asset service provider. CashXChain holds no private keys: it sends instructions and records what happens. The provider is never named — not in a path, a field, an error or a route — and no provider id appears in a response.


Accounts per asset, wallets per chain​

  • An account per asset. USDC, EURC, USDT, USDB, PYUSD and PATHUSD can each be opened once. An account spans every chain where you hold a wallet that carries its asset.
  • A wallet per chain. You open one wallet on each chain you want. The asset accounts share the wallets: a Solana wallet carries your USDC, EURC and USDT on Solana alike.
  • Each asset is its own currency. An asset is never converted for display, never shown as fiat, and never added to another asset. A balance sums one asset over its wallets, and nothing else.
  • All digital assets together count as one currency of your plan's max_currencies, however many you open.

What the sandbox offers, per chain:

ChainAssets
solanaUSDC, EURC, USDT, USDB, PYUSD
baseUSDC, EURC, USDB
ethereumUSDC, USDT, USDB
tronUSDT
tempoUSDC, USDT, EURC, PATHUSD

A new account's first wallet is opened on Solana — on Tempo for PATHUSD. The USDC account also has an EUR IBAN: EUR sent to it by SEPA arrives as USDC. See Accounts and wallets.


What you can do​

FlowHowPage
Get verified with the providerGET/POST /v1/banking/kyb/digital-assets; in the sandbox, one call approves youAccounts and wallets
Open an accountPOST /v1/banking/accounts with {"currency": "USDC"} (or EURC, …)Accounts and wallets
Open a wallet on another chainPOST /v1/banking/digital-assets/walletsAccounts and wallets
Add test fundsPOST /v1/sandbox/banking/accounts/{account_id}/simulate-depositAccounts and wallets
Settle a send the provider's sandbox leaves in flightPOST /v1/sandbox/banking/payouts/{payout_id}/simulate-completionSandbox behaviour
Send on chain, to the same chain or across chainsPOST /v1/banking/payouts with destination.type onchainSending
Send to an IBAN (EUR over SEPA)destination.type ibanSending
Send to a US, UK, Mexican or Brazilian bank accountdestination.type us_bank, gb_bank, clabe, pixSending
Send to another CashXChain customer by @handledestination.type cxc_handleSending
Swap USDC and EURCdestination_account_id: your account in the other assetSending
Send USDC back to your own EUR accountdestination_account_id: your EUR accountSending
Convert EUR into your USDC accounta payout from your EUR account to the USDC accountSending
See the route and lock itPOST /v1/banking/payouts/quote, then quote_idQuotes and the route lock
Send with an API keyto a trusted beneficiary a person approvedAPI keys and trusted beneficiaries
Build it end to end with a key: wallet to wallet, bank to walletevery call in order, with timings and errorsAPI transfer guide

What the sandbox simulates​

The sandbox talks to the provider's own sandbox. Four things are simulated so you can test without a real business, real money or a bank behind the account:

  • Approval. POST /v1/sandbox/banking/kyb/digital-assets/approve approves you at the provider without its hosted verification form.
  • Test funds. simulate-deposit asks the provider's sandbox to deposit the asset into your wallet; it is then read and booked like any real deposit — balance, transaction, payin.received.
  • A send-back's arrival. No bank sits behind a sandbox EUR account, so simulate-arrival books the EUR of a send-back on it (a background pass does the same within about two minutes).
  • Completion. The provider's sandbox accepts sends to an IBAN or a bank account, send-backs and swaps, and leaves them in flight; it was seen to complete a send over ACH to a US account itself. The sandbox settles each one still in flight once the money has been seen leaving the wallet: from a minute after the provider accepts it (five minutes for a us_bank send), or without that wait with simulate-completion. It marks each one simulated: true.

Everything else is the provider's sandbox answering for real. Read Sandbox behaviour before you test.


Who may do what​

Every route takes a person's dashboard session or an API key. A restricted key (cxc_rk_) needs the scope shown; a secret key (cxc_sk_) and a master key hold every scope. Publishable keys reach none of these.

ActionRouteSessionAPI key
Onboarding: status, startGET / POST /v1/banking/kyb/digital-assets✓accounts:read / accounts:write
Sandbox approvalPOST /v1/sandbox/banking/kyb/digital-assets/approve✓accounts:write
Open an accountPOST /v1/banking/accounts✓accounts:write
Accounts, balances, pay-in detailsGET /v1/banking/accounts, …/{id}/balance, …/{id}/payin-instructions✓accounts:read
Wallets: list, openGET / POST /v1/banking/digital-assets/wallets✓accounts:read / accounts:write
CreditsGET /v1/transactions✓payments:read
PayoutsGET /v1/banking/payouts, …/{id}✓payments:read
Quotes and route locksPOST /v1/banking/payouts/quote✓payments:read
CapabilitiesGET /v1/banking/capabilities✓accounts:read
SwapPOST /v1/banking/payouts with destination_account_idstep-uppayments:write, no step-up
Convert EUR into USDCPOST /v1/banking/payouts from the EUR accountstep-uppayments:write, no step-up
Send back to your own EUR accountPOST /v1/banking/payouts from the USDC accountstep-uppayments:write, no step-up
Send on chain, to an IBAN or a bank account, by @handlePOST /v1/banking/payouts with destinationstep-up; inline or a trusted beneficiarypayments:write, a trusted beneficiary only, no step-up
Trusted beneficiaries: listGET /v1/banking/digital-assets/trusted-beneficiaries✓accounts:read
Trusted beneficiaries: approve, revokePOST …/trusted-beneficiaries, DELETE …/{id}a person only, step-upnever — 403 session_required
Test fundsPOST /v1/sandbox/banking/accounts/{id}/simulate-deposit✓payments:write
Fiat test funds (the EUR a convert starts from)POST /v1/sandbox/banking/faucet✓payments:write
A send-back's arrivalPOST /v1/sandbox/banking/payouts/{id}/simulate-arrival✓payments:write
A send the provider's sandbox leaves in flight, settledPOST /v1/sandbox/banking/payouts/{id}/simulate-completion✓payments:write

A session acting for another account (Cxc-Account) is refused 403 session_required on every send to a third party and on a send-back. A session's seat needs payouts.create to send or to approve a trusted beneficiary. See Step-up for sessions and API keys and trusted beneficiaries.

Start with the Quickstart. An integration that moves stablecoins with an API key follows the API transfer guide.