POST /v1/internal_transfer and it processes automatically: within seconds it moves from processing to posted and fires the internal_transfer.posted webhook, the same sequence you’ll see in production.
What’s Different From Production
The sandbox is not connected to a ledger for this rail, which has two consequences:- Every transfer succeeds. No balance checks run, so you don’t need to fund the sender before testing, and you can’t trigger a rejection like
non_sufficient_funds. Build your rejection handling from the webhook and rejection reasons documented in Handling Failures; theinternal_transfer.rejectedevent can’t be produced in sandbox. - Balances don’t move. A posted transfer doesn’t change the sender or receiver balance, so don’t reconcile balances against internal transfers in sandbox.
400 the same way it does in production (see Sending an Internal Transfer).
Test the Happy Path
- Create the transfer with
POST /v1/internal_transfer. The 200 response returns the transfer inprocessing. - Within seconds, the transfer moves to
postedand fires theinternal_transfer.postedwebhook. No advancement call is needed.

