Skip to main content
In the sandbox there are no real banks or payment networks, so deposits never arrive and payouts never settle on their own. Simulation endpoints (/v1/simulations/*) let you drive those outcomes yourself, so you can build and test a complete money movement flow end to end before going live. This walkthrough takes a new integration through the full lifecycle: you open an account (operating or virtual, whichever fits your product), fund it with a simulated incoming deposit, and pay out to a counterparty. You advance each step yourself with the simulation endpoints.

In this guide

Prerequisites

The scopes and sandbox API key you need before you start.

Core walkthrough

Open an account, receive a simulated deposit, and send a payout.

Failed and returned payouts

Reject a payout before sending or return one after it is sent.

Freeze, drain, and close

Wind down an account or an account program end to end.

Return a deposit you received

Send a received deposit back to its sender and follow the return.

SWIFT

What differs for international USD: counterparty requirements and simulation rules.

Conversions

Convert funds between your accounts.

What you’ll build

  1. Open an account (operating or virtual).
  2. Receive a simulated deposit and watch it settle.
  3. Save a payout counterparty.
  4. Send a payout and advance it to sent.

Prerequisites

  • A sandbox API key with these scopes (or full_access). See Scopes and inspect your key with GET /v1/api_key.

Steps

1

Configure your environment

The SDK reads its configuration from environment variables, so point it at the sandbox.
2

Open an account

Pick the account model that matches your product and expand it. Both accounts come back ready to receive a deposit, and every step after this one is identical: they all run against the ACCOUNT_ID you capture here.
  • Operating account: one account you hold directly. Simplest option, good for treasury or a single balance.
  • Virtual account: a dedicated account per end customer (embedded-banking or FBO model), created under an account program and tied to an account holder.
Create an operating (DDA) account. In the sandbox this is a single call; the account comes back active with its own US payment details.
The response returns the new account’s ID:
Capture the returned ID as ACCOUNT_ID for the steps below:
POST /v1/simulations/accounts in the API Reference →
A virtual account belongs to an account program and an account holder, so you create those two first, then the account itself.
1

Create an account program

Capture the returned ID for the following steps:
POST /v1/simulations/account_programs in the API Reference →
2

Create an account holder

Provide the beneficiary’s details. The shape follows country_of_citizenship: use the US individual shape below when it is US, the non-US individual shape for any other country, and the business shape when holder_type is business.
Capture the returned ID for the following step:
Account holders are processed asynchronously. See the full beneficiary_data schemas (US individual, non-US individual, business) in the POST /v1/account_holders API Reference →.
3

Create the virtual account

Capture the returned account ID as ACCOUNT_ID for the steps below:
POST /v1/accounts in the API Reference →
For the full virtual-accounts model, see Virtual accounts.
3

Read the account's payment details

Retrieve the account to see its ABA payment details (US routing and account number). These are the details a sender would use to pay into the account.
GET /v1/accounts/{id} in the API Reference →
4

Simulate an incoming deposit

Simulate a deposit arriving over Fedwire from an external sender. A wire carries the originator’s account details, so you provide them as the counterparty. The currency must match the account currency. Give it an unstructured_remittance_information value you can recognize later. You use it to find the settled deposit.
Deposits and payouts support the ach, fedwire, and swift rails. ACH does not carry the sender’s account details, so use fedwire when you want to attach a counterparty. SWIFT deposit simulations require a counterparty with an iban financial address. See ACH, Fedwire, and SWIFT.
POST /v1/simulations/deposits in the API Reference →
Dashboard equivalent: Payments → Deposits → Create deposit, pick the account, amount, reference, and rail (ACH, Fedwire, or SWIFT).
5

Confirm the deposit settled

Deposits are processed asynchronously and appear once they reach settled. Poll the deposits list and match on the remittance information you set.
The settled deposit is credited to your account:
GET /v1/deposits in the API Reference →
6

Save a payout counterparty

A payout is always sent to a saved counterparty, so create one first. For a payout over ACH or Fedwire, use an aba financial address.
Capture the returned ID for the following step (the create response returns it as id):
POST /v1/counterparties in the API Reference →
7

Create a payout

Debit your account and send funds to the counterparty. Reference the counterparty by counterparty_id; the rail is validated against the counterparty’s financial address and selected automatically when omitted.
The payout is created as initiated and moves to submitted while it is in flight.
Capture the returned ID for the following step (the create response returns it as id):
POST /v1/payouts in the API Reference →
8

Simulate a successful send

In production the payment network settles the payout. In the sandbox you advance it yourself. Simulate a successful send.
POST /v1/simulations/payouts/{id}/send in the API Reference →
Dashboard equivalent: open the payout under Payments → Payouts and use Sandbox Tools → Simulate payout → succeeded. The same menu offers failed and returned, matching the reject and return simulations below.
9

Poll until the payout is sent

Retrieve the payout until its status reaches sent.
GET /v1/payouts/{id} in the API Reference →
10

Review the account's transactions

Every settled movement is recorded as a transaction. List them for your account to see the full ledger: the incoming deposit as a credit and the outgoing payout as a debit. Each transaction’s source links back to the deposit or payout that created it (null when it does not map to a retrievable resource). account_id is required. Narrow the results with the optional booked_at.gte and booked_at.lte filters.
You’ve now completed the full lifecycle end to end: account, deposit, payout, and the transactions that record them.GET /v1/transactions in the API Reference →

Simulate a failed or returned payout

Beyond the happy path, you can drive failure outcomes to test how your integration reacts.
While a payout is still submitted (before you simulate a send), simulate the network rejecting it. The payout moves to failed and the funds are released back to your account. Use invalid_routing_number for domestic rails or invalid_account_format for a SWIFT rejection.
POST /v1/simulations/payouts/{id}/reject in the API Reference →
After a payout reaches sent, simulate the receiving bank returning it. The original payout stays sent; the returned funds arrive as a new standalone deposit (a credit transaction) on your account. Valid reasons are account_closed, invalid_account_format, invalid_routing_number, account_blocked, and unknown.
POST /v1/simulations/payouts/{id}/return in the API Reference →The returned funds show up as a new deposit rather than a change to the payout. List your deposits to find it:
GET /v1/deposits in the API Reference →

Return a deposit you received

A deposit you do not want to keep (an unexpected sender, a wrong amount) is sent back with a return. Returns are their own resource with the payout lifecycle: initiatedsent, then failed if the network rejects it or returned if the sender’s bank sends it back. The deposit itself stays settled; the return is linked to it and debits your account when it is sent.
1

Create the return

Pass the deposit_id of a settled deposit. The return goes back over the rail the deposit arrived on; you do not choose a rail or a reason code.
POST /v1/returns in the API Reference →
2

Follow the return

A new return stays initiated until you drive it, the same way as a payout: POST /v1/simulations/returns/{id}/send makes it sent, /reject (with a reason) makes it failed, and /return on a sent return plays the sender’s bank sending it back: the return moves to returned and the funds are credited to your account again. Retrieve the return to follow each step.
GET /v1/returns/{id} in the API Reference →
Dashboard equivalent: open the deposit under Payments → Deposits and use Return in its detail view.

SWIFT

International USD moves over SWIFT and follows the same simulations as the domestic rails, with two differences: SWIFT is USD only in both directions: currency: "EUR" with rail: "swift" is rejected at creation. Payout simulations (send, reject, return) work the same way as for the domestic rails. Use invalid_account_format as the reject reason to mimic a correspondent bank refusing the beneficiary details. Field-level rules and country requirements are on the SWIFT rail page.
1

Save an international counterparty

An IBAN beneficiary with a physical address. For non-IBAN countries use type: "bic" with account_number instead.
Capture the ID for the next steps:
POST /v1/counterparties in the API Reference →
2

Send a SWIFT payout

Same call as a domestic payout, with rail: "swift". Then drive it with send, reject, or return as above.
POST /v1/payouts in the API Reference →
3

Receive an international wire

The sender has to be an IBAN counterparty: pass the saved counterparty_id, or an inline counterparty with an iban financial address.
POST /v1/simulations/deposits in the API Reference →

Scripted outcomes by beneficiary BIC

The sandbox also plays the legs a SWIFT payment travels after the first one. Once you send a SWIFT payout, the beneficiary’s bank decides what happens next. Three German test beneficiaries have scripted outcomes; save one as an iban counterparty with the BIC in the bic field and pay it. Any other reachable bank succeeds on every leg. A scripted return behaves like a real one:
  • The payout moves to returned and the payout.returned webhook fires. No deposit is created: Augustus matches the return to the payout on the original payment reference and credits the amount back to your account. Follow it on the payout, not on the deposits list.
  • The re-credited amount is net of a fixed USD 10.00 return charge: a USD 100.00 payout puts USD 90.00 back on your account, while the payout itself keeps showing USD 100.00. Never reconcile a return by its amount.
  • A payout of USD 10.00 or less is consumed by the charge, so no return arrives and the rejection is final.
POST /v1/simulations/payouts/{id}/return is unaffected: the payout moves to returned and the full amount is credited back.

Freeze, drain, and close

Winding down an account or an account program follows the same sequence: freeze it, drain the residual balance to an external destination, settle the drain payout(s), then close it. A frozen account or program can be reactivated with the matching unfreeze endpoint before you close it.
1

Freeze the account

Freezing stops new movements and is required before draining.
POST /v1/simulations/accounts/{id}/freeze in the API Reference →Changed your mind before closing? Reactivate the account with unfreeze:
POST /v1/simulations/accounts/{id}/unfreeze in the API Reference →
2

Drain the residual balance

Drain sends the remaining balance to an external destination and returns the payout that carries it. Use an aba financial address for a USD destination.
The response returns the drain payout’s ID:
Capture the returned ID to settle it in the next step:
POST /v1/simulations/accounts/{id}/drain in the API Reference →
3

Settle the drain payout

Send the drain payout so the balance reaches zero, the same way you settle any payout.
POST /v1/simulations/payouts/{id}/send in the API Reference →
4

Close the account

With the balance at zero you can close the account. Valid reasons are client_request and aml_risk_fraud.
POST /v1/simulations/accounts/{id}/close in the API Reference →
Closing a program winds down every virtual account under it. Drain returns one payout per funded account, so settle each returned ID.
1

Freeze the program

POST /v1/simulations/account_programs/{id}/freeze in the API Reference →Changed your mind before closing? Reactivate the program and its accounts with unfreeze:
POST /v1/simulations/account_programs/{id}/unfreeze in the API Reference →
2

Drain the program

Drain every frozen account under the program to an external destination. The response returns one payout ID per funded account.
The response returns one payout ID per funded account:
POST /v1/simulations/account_programs/{id}/drain in the API Reference →
3

Settle each drain payout

Send every payout returned by the drain so each account balance reaches zero.
POST /v1/simulations/payouts/{id}/send in the API Reference →
4

Close the program

POST /v1/simulations/account_programs/{id}/close in the API Reference →

Conversions

1

Prerequisites

Make sure you have USD and USDC accounts. Conversions can be done in both directions. The example below shows a conversion of 10 USD to 10 USDC.Note the per-operation $1,000.00 and 24h $10,000.00 net sandbox limits.
2

Create a conversion

Capture the returned ID for the following steps:
3

Simulate outcome

4

Get conversion

If you simulate conversion failure, its status will be updated immediately. Otherwise, a conversion implies an on-chain transaction, it might take some time to transition from pending to the terminal state.