Platform ToolsSandbox Testing

Sandbox Testing

Simulate verification decisions, treasury funding, and deposits, and rehearse every failure path before real money moves.

What the sandbox is

https://sandbox.rasto.co with an sk_test_ key serves the same endpoints, objects, statuses, and signed webhooks as live. Wallets and on-chain deliveries run for real on testnets. The parts with no testnet (bank rails, verification decisions, and exchange rates) are simulated, and you drive them through endpoints under /api/sandbox/*. Each one mirrors the resource it acts on, so POST /api/sandbox/virtual_accounts/{virtual_account_id}/deposits reads like the virtual account path with sandbox in front.

On the live host every simulator returns 403 sandbox_only.

Sandbox and live, precisely

DimensionSandboxLive
Endpoints, objects, statuses, error envelopesIdenticalIdentical
WebhooksDelivered and signed like liveReal
VerificationYou decide, through the simulator. A submitted review stays pending until you doDecided by the real review
Document readingEvery document reads as the same sample values, and none is refusedRead and checked from the images
Document asksThe same as live, by customer kind and legal form. See Documents we ask forThe same, plus anything the review asks of one customer later
Profile asksOnly the fields required to request an endorsementThe review can ask for any field in the code catalog
Bank depositsSimulated with POST /api/sandbox/virtual_accounts/{virtual_account_id}/depositsReal bank credits
Wallet addressesDerived the same way, on testnetsDerived the same way, on mainnets
Wallet fundingSend testnet tokens to the addressAny on-chain send to the address
On-chain delivery and sendsReal transactions on testnetsReal transactions on mainnets
network on chain objectstestnetmainnet
Treasury inventoryYou fund it with POST /api/sandbox/treasury/depositsFunded operationally
Exchange rateFixed and deterministic. USD to USDC is at parUSD to USDC at par (1); USD to USDT at the market rate. Your plan's spread applies
Simulation endpointsAvailable403 sandbox_only
Account gatesOpen once your partner account exists403 until your Partner Terms, KYB, and live wallet keys are in place. See Get set up

Sandbox and live keys, wallet keys, and webhook endpoints are separate, so nothing you register in sandbox carries over to live.

Verification decisions

You make the verification decision in sandbox. After a submit, the endorsement sits pending until you decide, and the decision applies to the customer's latest submitted review. The simulator runs the same decision path a real review takes, so statuses, requirement buckets, and webhooks behave as they do in live.

curl -s $BASE/api/sandbox/customers/cus_.../verification_decisions \
  -H "Api-Key: $KEY" -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"decision": "approved"}'
decisionSimulatesWhat to test
approvedA clean passThe happy path, and endorsement.approved
request_for_informationThe review asks again for proof_of_address, or registration_document for a businessYour requirement-bucket UI, and the PATCH with a new document that resubmits by itself
rejectedA final adverse decisionYour terminal-state handling

The call returns the decided verification round. You can also decide an approved endorsement, which rehearses the review asking for more, or refusing the customer, after approval.

Two refusals apply:

  • 400 verification_not_started: the customer was never submitted. Call POST /api/customers/{customer_id}/verifications first.
  • 400 verification_not_under_review: no review is running, for example while the endorsement is in issues. Answer the ask with a PATCH, which resubmits, then decide again.

Document reading

At submit, sandbox reads every document as fixed sample values, for an individual, a business, and each controller alike. The reading fills only fields you left empty, as in live.

DocumentFieldSample value
Identity documentfirst_name, last_nameSandbox, User
Identity documentdate_of_birth1990-01-15
Identity documentnationalityUS
Identity documentKind, number, issuing countrythe kind you sent, else passport; SANDBOX-0001; US
proof_of_addressaddress (physical_address for a business)123 Sandbox Lane, Sandbox City, 00000, US
registration_documentlegal_namethe legal_name you sent, else Sandbox Company Inc.
registration_documentbusiness_kind, registration_number, incorporation_datecorporation, SBX-0001, 2020-01-15
registration_documentaddress1 Sandbox Plaza, Sandbox City, DE, 19901, US
proof_of_tax_identificationtax_id, tax_residence_country12-3456789, US

A business created without business_kind therefore reads as a corporation, and the submit asks for a corporation's documents. Send business_kind to rehearse another legal form's list.

Sandbox reading never finds a problem with a document, so the document checks only refuse in live.

Treasury funding

Deliveries come from prefunded inventory, and the sandbox treasury starts empty. Fund the asset and chain you are testing first.

curl -s $BASE/api/sandbox/treasury/deposits \
  -H "Api-Key: $KEY" -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"asset": "usdc", "chain": "solana", "amount": "10000"}'

Without it, a deposit waits in orchestrating for inventory, as it would in live during an inventory gap, for at most one hour. After that it stays in orchestrating for our team to resolve, so fund first.

Bank deposits

curl -s $BASE/api/sandbox/virtual_accounts/va_.../deposits \
  -H "Api-Key: $KEY" -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"amount": "100.00", "sender_name": "ANA SILVA", "remittance_info": "invoice 42"}'

The deposit arrives on the account's primary rail, or on the payment_rail you name (one of the account's payment_rails), and runs the real pipeline: deposit, conversion, payout, with every webhook. Assert on the conversion's fee_lines and delivered_amount in your integration tests.

Magic amounts

Specific amounts trigger the failure paths.

AmountResult
666.00Deposit returned, with the deposit.returned webhook
777.00Deposit on_hold, with the deposit.on_hold webhook
anything elseNormal orchestration

For the two magic amounts, no conversion runs.

Wallet deposits

Wallets have no simulator. Sandbox wallets live on Solana devnet, so you fund one by sending devnet USDC to its address, from a devnet faucet or any devnet wallet. The sandbox mint is in the Signing Guide. wallet_transaction.created (with kind: "deposit") fires when the deposit lands, and balances are read from the chain, as in live.

A complete test checklist

Onboarding

Terms accepted, customer created with documents, submitted. Handle approved, request_for_information plus the PATCH that resubmits, and rejected. Also assert the 422 verification_incomplete you get from submitting too early.

Money

Treasury funded, deposit landed. Verify the delivered amount, the fee_lines, and the tx_hash. Then run 666.00 and 777.00.

Wallets

Create a wallet, fund it with devnet USDC, read the balance back, and run one operation end to end including the verify step. Let one operation expire on purpose.

Webhooks

Every event kind processed idempotently. Replay one with POST /api/webhook_events/{webhook_event_id}/replay to prove your dedupe works, and shuffle two events to prove your ordering uses sequence.

Failure hygiene

Retry a POST with the same Idempotency-Key and expect a replay, not a duplicate. Reuse a key on a different body and expect 422 idempotency_key_reused. Send a POST with no key and expect 400 missing_idempotency_key.

When all five pass in sandbox, work through Going Live.