What happened
You called asimulate/* endpoint against an entity (a payout, transaction, order, or deposit) that has already reached a terminal state. This returns HTTP 409 with error code RESOURCE_TERMINAL.
The first simulate call wins. Once an entity is terminal (succeeded, failed, or cancelled), no further simulation is possible on that entity.
Common causes
- Replay of a successful simulate call — the simulate call succeeded earlier and you called it again (e.g., a retry loop that did not check the prior response)
- Race between simulate and autopilot — in sandbox, the chain-confirm autopilot runs automatically after a cosign approval; if autopilot completes before your next simulate call, the entity is already terminal
- Simulate called on an already-terminal entity — the entity reached a terminal state through a different path (e.g., a
simulate/terminalcall or an earlier auto-terminate)
Recovery
1. Re-fetch the entity to see its terminal statefailureCode (for failed states) or status to understand how it reached the terminal state. If a prior simulate call or autopilot drove it to an unexpected state, that is the root cause to address.
Prevention
- Check the response from each simulate call — treat a 200 response as authoritative; if the entity is already terminal, the response body will show the terminal state
- Do not retry simulate calls in a loop — simulate calls are idempotent at the semantic level: once the entity is terminal, the first call’s outcome stands
- Account for sandbox autopilot — after approving a cosign, the sandbox chain-confirm autopilot runs automatically; do not issue a follow-up
simulate/confirmcall unless you disabled autopilot
Related endpoints
- GET /v2/payouts/:id — read payout state
- GET /v2/transactions/:id — read transaction state
- GET /v2/orders/:id — read order state
- POST /v2/sandbox/transactions/:id/simulate/terminal — force a transaction terminal (will return RESOURCE_TERMINAL if already done)