# Errors

{/* AUTO-GENERATED - DO NOT EDIT. Run: bun run apps/gateway/docs/scripts/generate-error-docs.ts */}

## Error Response Format

All API errors return a consistent JSON response:

```json
{
  "errors": [
    {
      "error_code": "domain-YZZZ",
      "error_message": "Human-readable error description"
    }
  ]
}
```

## Error Code Convention

Error codes follow the format `{domain}-{YZZZ}` where:

- **domain** identifies the resource area (e.g., `accounts`, `payments`, `treasury`)
- **Y** indicates the HTTP status category
- **ZZZ** is the specific error number within that category

| Range | HTTP Status | Meaning |
| --- | --- | --- |
| 1000–1999 | 404 | Not Found |
| 2000–2999 | 401 / 403 | Unauthorized / Forbidden |
| 3000–3999 | 400 | Bad Request |
| 4000–4999 | 429 | Too Many Requests |
| 5000–5999 | 502 / 503 | Bad Gateway / Service Unavailable |

:::note
Some domains (Circle, Idempotency) use legacy numbering that does not follow the range convention above.
:::

## Status Reasons

When a step of a payment, deposit, withdrawal, or rebalance transitions to `failed`, the step carries a
`status_reasons` array explaining why. Each entry reuses the error vocabulary above — an
`error_code` and `error_message`:

```json
"status_reasons": [
  {
    "error_code": "transfers-9201",
    "error_message": "An upstream step failed, so this step was not executed"
  }
]
```

`status_reasons` is a single shared taxonomy across all resources, so the codes carry the resource-neutral
`transfers-` prefix (see the [Transfers](#transfers) table below) regardless of which resource's step
failed. They occupy a reserved `9xxx` block — `91xx` precondition, `92xx` lifecycle, `93xx` execution —
and are only present on `failed` steps; a non-failed step's `status_reasons` is an empty array. Provider or
chain error detail is incorporated into the `error_message`; the `error_code` always stays within this taxonomy.

## Accounts

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`accounts-1000`</td>
      <td>404</td>
      <td>Account with id '&#123;id&#125;' not found</td>
      <td>The specified account ID does not exist in this workspace</td>
    </tr>
    <tr>
      <td>`accounts-1001`</td>
      <td>404</td>
      <td>Entity with id '&#123;id&#125;' not found</td>
      <td>The tenant or counterparty specified does not exist</td>
    </tr>
    <tr>
      <td>`accounts-2000`</td>
      <td>403</td>
      <td>The entity does not belong to your workspace</td>
      <td>User tries to link an account to an entity that belongs to a different workspace</td>
    </tr>
    <tr>
      <td>`accounts-3000`</td>
      <td>400</td>
      <td>Cannot provide both tenant_id and counterparty_id</td>
      <td>User provides both tenant_id and counterparty_id when only one is allowed</td>
    </tr>
    <tr>
      <td>`accounts-3001`</td>
      <td>400</td>
      <td>A workspace-level bank account already exists. Only one is allowed per workspace.</td>
      <td>User tries to create a second workspace-level bank account</td>
    </tr>
    <tr>
      <td>`accounts-3002`</td>
      <td>400</td>
      <td>wallet_address is required for unmanaged wallets (is_managed=false)</td>
      <td>User creates an unmanaged wallet without providing a wallet_address</td>
    </tr>
    <tr>
      <td>`accounts-3003`</td>
      <td>400</td>
      <td>Cannot determine network for wallet type '&#123;type&#125;'</td>
      <td>The provided wallet type does not map to a known blockchain network</td>
    </tr>
    <tr>
      <td>`accounts-3004`</td>
      <td>400</td>
      <td>signature is required for managed wallets (is_managed=true)</td>
      <td>User creates a managed wallet without providing the required signature</td>
    </tr>
    <tr>
      <td>`accounts-3005`</td>
      <td>400</td>
      <td>Invalid signature format. Expected base64-encoded JSON with body and stamp fields.</td>
      <td>The signature parameter could not be decoded or is missing required fields</td>
    </tr>
    <tr>
      <td>`accounts-3006`</td>
      <td>400</td>
      <td>Circle Mint ledgers require a tenant_id or counterparty_id. Workspace-level sub-ledgers are not supported.</td>
      <td>User tries to create a Circle Mint ledger without linking it to a tenant or counterparty</td>
    </tr>
    <tr>
      <td>`accounts-3007`</td>
      <td>400</td>
      <td>This entity already has a Circle Mint ledger. Only one Circle Mint ledger per tenant/counterparty is allowed.</td>
      <td>User tries to create a duplicate Circle Mint ledger for the same entity</td>
    </tr>
    <tr>
      <td>`accounts-3008`</td>
      <td>400</td>
      <td>A workspace-level Circle Mint master wallet ledger already exists.</td>
      <td>User tries to create a second master wallet ledger for the workspace</td>
    </tr>
    <tr>
      <td>`accounts-3009`</td>
      <td>400</td>
      <td>CIRCLE_MINT provider requires a tenant_id or counterparty_id</td>
      <td>Circle Mint metadata preparation requires an entity to be linked</td>
    </tr>
    <tr>
      <td>`accounts-3010`</td>
      <td>400</td>
      <td>CIRCLE_MINT provider requires a business entity (not individual)</td>
      <td>Circle Mint only supports business-classified entities, not individuals</td>
    </tr>
    <tr>
      <td>`accounts-3011`</td>
      <td>400</td>
      <td>Entity is missing required fields for Circle</td>
      <td>The entity does not have all required business fields populated for Circle onboarding</td>
    </tr>
    <tr>
      <td>`accounts-3012`</td>
      <td>400</td>
      <td>Cannot create VAN: compliance state is not ACCEPTED</td>
      <td>Virtual account number creation requires the account to have ACCEPTED compliance state</td>
    </tr>
    <tr>
      <td>`accounts-3013`</td>
      <td>400</td>
      <td>Cannot create VAN: circle_wallet_id is missing from account metadata</td>
      <td>The ledger account does not have a Circle wallet ID configured</td>
    </tr>
    <tr>
      <td>`accounts-3014`</td>
      <td>400</td>
      <td>No workspace-level bank account found. Please create a bank account first.</td>
      <td>A workspace-level bank account is required but none exists</td>
    </tr>
    <tr>
      <td>`accounts-3015`</td>
      <td>400</td>
      <td>No wire bank accounts found in Circle. Please register a bank account on Circle dashboard first.</td>
      <td>Circle does not have any wire bank accounts registered for this workspace</td>
    </tr>
    <tr>
      <td>`accounts-3016`</td>
      <td>400</td>
      <td>Multiple wire bank accounts found in Circle</td>
      <td>Production requires exactly one bank account in Circle, but multiple were found</td>
    </tr>
    <tr>
      <td>`accounts-3017`</td>
      <td>400</td>
      <td>Could not determine Circle bank ID</td>
      <td>Failed to resolve the Circle bank ID needed for wire transfers</td>
    </tr>
    <tr>
      <td>`accounts-3018`</td>
      <td>400</td>
      <td>Unsupported provider. Must be one of : CIRCLE_MINT, KRAKEN</td>
      <td>The specified provider is not supported for this operation. Must be one of : CIRCLE_MINT, KRAKEN</td>
    </tr>
    <tr>
      <td>`accounts-3019`</td>
      <td>400</td>
      <td>Account does not have a provider configured</td>
      <td>The account metadata does not contain provider configuration</td>
    </tr>
    <tr>
      <td>`accounts-3020`</td>
      <td>400</td>
      <td>Entity type must be 'counterparty' or 'tenant'</td>
      <td>The referenced entity is not a valid type for account linking</td>
    </tr>
    <tr>
      <td>`accounts-3022`</td>
      <td>400</td>
      <td>Signature body has unexpected activity type '&#123;actual&#125;', expected '&#123;expected&#125;'</td>
      <td>The stamped Turnkey activity inside the signature is not the expected CREATE_WALLET activity</td>
    </tr>
    <tr>
      <td>`accounts-3023`</td>
      <td>400</td>
      <td>Signature body organizationId does not match the authenticated workspace's Turnkey sub-organization</td>
      <td>The caller stamped an activity targeting a sub-organization that does not belong to their workspace</td>
    </tr>
    <tr>
      <td>`accounts-3024`</td>
      <td>400</td>
      <td>Signed wallet account addressFormat '&#123;actual&#125;' does not match type '&#123;type&#125;' (expected '&#123;expected&#125;')</td>
      <td>The stamped CREATE_WALLET parameters describe an address format that does not match the dto.type</td>
    </tr>
    <tr>
      <td>`accounts-3025`</td>
      <td>400</td>
      <td>Managed wallets are only supported for type 'stablecoin_ethereum' (got '&#123;type&#125;')</td>
      <td>User attempted to create a managed (is_managed=true) wallet for a non-Ethereum wallet type</td>
    </tr>
    <tr>
      <td>`accounts-3100`</td>
      <td>400</td>
      <td>account_name is required and must be between 1-255 characters</td>
      <td>User provides an account name that doesn't meet length requirements</td>
    </tr>
    <tr>
      <td>`accounts-3101`</td>
      <td>400</td>
      <td>tenant_id must be a valid UUID</td>
      <td>User provides a tenant_id that is not a valid UUID</td>
    </tr>
    <tr>
      <td>`accounts-3102`</td>
      <td>400</td>
      <td>counterparty_id must be a valid UUID</td>
      <td>User provides a counterparty_id that is not a valid UUID</td>
    </tr>
    <tr>
      <td>`accounts-3103`</td>
      <td>400</td>
      <td>bank_name is required and must be between 1-255 characters</td>
      <td>User provides a bank name that doesn't meet length requirements</td>
    </tr>
    <tr>
      <td>`accounts-3104`</td>
      <td>400</td>
      <td>bank_code_type must be one of: SWIFT, BIC, IBAN, ROUTING</td>
      <td>User provides a bank_code_type that is not in the allowed enum</td>
    </tr>
    <tr>
      <td>`accounts-3105`</td>
      <td>400</td>
      <td>bank_identifier_code is required</td>
      <td>User creates a bank account without providing the bank identifier code</td>
    </tr>
    <tr>
      <td>`accounts-3106`</td>
      <td>400</td>
      <td>bank_account_number is required</td>
      <td>User creates a bank account without providing the account number</td>
    </tr>
    <tr>
      <td>`accounts-3107`</td>
      <td>400</td>
      <td>type must be one of: stablecoin_ethereum, stablecoin_solana, stablecoin_stellar</td>
      <td>User provides a wallet type that is not in the allowed enum</td>
    </tr>
    <tr>
      <td>`accounts-3108`</td>
      <td>400</td>
      <td>wallet_address must be a valid blockchain address for the specified network</td>
      <td>User provides a wallet address that doesn't match the expected format for the network</td>
    </tr>
    <tr>
      <td>`accounts-3109`</td>
      <td>400</td>
      <td>Wallet signature is malformed or invalid</td>
      <td>User provides a signature that is not properly formatted or cannot be verified</td>
    </tr>
    <tr>
      <td>`accounts-3110`</td>
      <td>400</td>
      <td>provider must be one of: CIRCLE_MINT, KRAKEN</td>
      <td>User provides a provider value that is not in the allowed enum</td>
    </tr>
    <tr>
      <td>`accounts-3111`</td>
      <td>400</td>
      <td>This account does not support on-chain deposit addresses</td>
      <td>User requests an on-chain deposit address for an account whose type or provider does not support them</td>
    </tr>
    <tr>
      <td>`accounts-3112`</td>
      <td>400</td>
      <td>Ledger account has not completed compliance review</td>
      <td>User requests an on-chain deposit address before the ledger's provider compliance review is accepted</td>
    </tr>
    <tr>
      <td>`accounts-3113`</td>
      <td>400</td>
      <td>network is not supported for on-chain deposit addresses</td>
      <td>User requests an on-chain deposit address on a network Circle does not support in this environment</td>
    </tr>
    <tr>
      <td>`accounts-5000`</td>
      <td>502</td>
      <td>Failed to create wallet. Please try again or contact support if the issue persists.</td>
      <td>Turnkey or other wallet provider failed during wallet creation</td>
    </tr>
    <tr>
      <td>`accounts-5001`</td>
      <td>502</td>
      <td>Failed to create Circle external entity</td>
      <td>Circle API call to create the external entity failed</td>
    </tr>
    <tr>
      <td>`accounts-5002`</td>
      <td>502</td>
      <td>Unable to create virtual account number (VAN) for this ledger account.</td>
      <td>Circle API call to create the virtual account number failed</td>
    </tr>
    <tr>
      <td>`accounts-5003`</td>
      <td>502</td>
      <td>Failed to retrieve entity business fields from vault</td>
      <td>Basis Theory vault call to retrieve entity fields failed</td>
    </tr>
    <tr>
      <td>`accounts-5004`</td>
      <td>502</td>
      <td>Failed to provision the on-chain deposit address</td>
      <td>Provider API call to list or create the deposit address failed</td>
    </tr>
  </tbody>
</table>

## Counterparties

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`counterparties-1000`</td>
      <td>404</td>
      <td>Counterparty not found</td>
      <td>The specified counterparty ID does not exist</td>
    </tr>
    <tr>
      <td>`counterparties-1001`</td>
      <td>404</td>
      <td>Tenant with id '&#123;id&#125;' not found. Cannot assign counterparty to non-existent tenant.</td>
      <td>User tries to assign a counterparty to a tenant_id that doesn't exist</td>
    </tr>
    <tr>
      <td>`counterparties-2000`</td>
      <td>403</td>
      <td>You do not have access to this counterparty</td>
      <td>User tries to access a counterparty that belongs to a different workspace</td>
    </tr>
    <tr>
      <td>`counterparties-3002`</td>
      <td>400</td>
      <td>classification must be 'individual' or 'business'</td>
      <td>User provides a classification value that is not 'individual' or 'business'</td>
    </tr>
    <tr>
      <td>`counterparties-3003`</td>
      <td>400</td>
      <td>business_legal_name is required for business counterparties and must be 1-255 characters</td>
      <td>User creates a business counterparty with missing or improperly formatted business_legal_name</td>
    </tr>
    <tr>
      <td>`counterparties-3004`</td>
      <td>400</td>
      <td>business_address_country is required for business counterparties and must be a valid ISO 3166-1 alpha-2 country code</td>
      <td>User provides a business_address_country that is not a valid 2-letter country code (e.g., &quot;US&quot;, &quot;GB&quot;)</td>
    </tr>
    <tr>
      <td>`counterparties-3005`</td>
      <td>400</td>
      <td>individual_first_name is required for individual counterparties and must be 1-255 characters</td>
      <td>User creates an individual counterparty with missing or improperly formatted first name</td>
    </tr>
    <tr>
      <td>`counterparties-3006`</td>
      <td>400</td>
      <td>individual_last_name is required for individual counterparties and must be 1-255 characters</td>
      <td>User creates an individual counterparty with missing or improperly formatted last name</td>
    </tr>
    <tr>
      <td>`counterparties-3007`</td>
      <td>400</td>
      <td>individual_address_country is required for individual counterparties and must be a valid ISO 3166-1 alpha-2 country code</td>
      <td>User provides an individual_address_country that is not a valid 2-letter country code</td>
    </tr>
    <tr>
      <td>`counterparties-3008`</td>
      <td>400</td>
      <td>individual_date_of_birth must be a valid date in YYYY-MM-DD format</td>
      <td>User provides a date_of_birth that doesn't match the required format or is not a valid date</td>
    </tr>
    <tr>
      <td>`counterparties-3009`</td>
      <td>400</td>
      <td>tenant_id must be a valid UUID</td>
      <td>User provides a tenant_id that is not a validly formatted UUID</td>
    </tr>
    <tr>
      <td>`counterparties-3010`</td>
      <td>400</td>
      <td>individual_street_address1 is required for individual counterparties</td>
      <td>User creates an individual counterparty without providing the street address</td>
    </tr>
    <tr>
      <td>`counterparties-3011`</td>
      <td>400</td>
      <td>individual_city is required for individual counterparties</td>
      <td>User creates an individual counterparty without providing the city</td>
    </tr>
    <tr>
      <td>`counterparties-3012`</td>
      <td>400</td>
      <td>individual_postal_code is required for individual counterparties</td>
      <td>User creates an individual counterparty without providing the postal code</td>
    </tr>
    <tr>
      <td>`counterparties-3013`</td>
      <td>400</td>
      <td>business_street_address1 is required for business counterparties</td>
      <td>User creates a business counterparty without providing the street address</td>
    </tr>
    <tr>
      <td>`counterparties-3014`</td>
      <td>400</td>
      <td>business_city is required for business counterparties</td>
      <td>User creates a business counterparty without providing the city</td>
    </tr>
    <tr>
      <td>`counterparties-3015`</td>
      <td>400</td>
      <td>business_postal_code is required for business counterparties</td>
      <td>User creates a business counterparty without providing the postal code</td>
    </tr>
  </tbody>
</table>

## Currencies

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`currencies-1000`</td>
      <td>404</td>
      <td>Currency not found</td>
      <td>The specified currency code does not exist</td>
    </tr>
    <tr>
      <td>`currencies-3000`</td>
      <td>400</td>
      <td>Invalid currency code format</td>
      <td>User provides a currency code that is not a valid ISO 4217 format (e.g., USD, EUR, GBP)</td>
    </tr>
    <tr>
      <td>`currencies-3001`</td>
      <td>400</td>
      <td>Currency is not supported for this operation</td>
      <td>User attempts to use a currency that is valid but not supported for the requested operation</td>
    </tr>
    <tr>
      <td>`currencies-3002`</td>
      <td>400</td>
      <td>Invalid currency pair for exchange</td>
      <td>User attempts to exchange between currencies where the pair is not supported</td>
    </tr>
  </tbody>
</table>

## Networks

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`networks-1000`</td>
      <td>404</td>
      <td>Network not found</td>
      <td>The specified network identifier does not exist</td>
    </tr>
    <tr>
      <td>`networks-3000`</td>
      <td>400</td>
      <td>Invalid network identifier</td>
      <td>User provides a network identifier that is not a valid format (e.g., ethereum, polygon, base)</td>
    </tr>
    <tr>
      <td>`networks-3001`</td>
      <td>400</td>
      <td>Network is not supported for this operation</td>
      <td>User attempts to use a network that is valid but not supported for the requested operation</td>
    </tr>
    <tr>
      <td>`networks-3002`</td>
      <td>400</td>
      <td>Currency is not compatible with the specified network</td>
      <td>User provides a currency/network combination that is not compatible (e.g., BTC on Ethereum network)</td>
    </tr>
    <tr>
      <td>`networks-3003`</td>
      <td>400</td>
      <td>Network is currently unavailable or under maintenance</td>
      <td>User attempts to use a network that is temporarily unavailable</td>
    </tr>
    <tr>
      <td>`networks-3004`</td>
      <td>400</td>
      <td>Currency is not yet transactable on this network</td>
      <td>The requested currency/network pair is supported for balance tracking but transactional flows (deposit, payment, rebalance) are not yet enabled.</td>
    </tr>
    <tr>
      <td>`networks-5000`</td>
      <td>502</td>
      <td>Failed to connect to network RPC endpoint</td>
      <td>Connection to the blockchain network RPC endpoint failed due to external service error</td>
    </tr>
  </tbody>
</table>

## Payments

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`payments-0007`</td>
      <td>500</td>
      <td>Account asset balance is in an invariant-violating state</td>
      <td>The stored account_assets row for &#123;account_asset_id&#125; has available_balance (&#123;available&#125;) greater than total_balance (&#123;total&#125;); refusing to mutate corrupt state</td>
    </tr>
    <tr>
      <td>`payments-0008`</td>
      <td>500</td>
      <td>Balance mutation amount must be non-negative</td>
      <td>BalanceService.&#123;method&#125; was called with a negative amount (&#123;amount&#125;); refusing to mutate</td>
    </tr>
    <tr>
      <td>`payments-1000`</td>
      <td>404</td>
      <td>Payment not found</td>
      <td>The specified payment ID does not exist</td>
    </tr>
    <tr>
      <td>`payments-1001`</td>
      <td>404</td>
      <td>Payment transfer step not found with id '&#123;id&#125;'</td>
      <td>The step does not exist or does not belong to this payment</td>
    </tr>
    <tr>
      <td>`payments-1002`</td>
      <td>404</td>
      <td>Destination account not found</td>
      <td>to_account did not resolve to an account in this workspace</td>
    </tr>
    <tr>
      <td>`payments-3000`</td>
      <td>400</td>
      <td>from_network must equal to_network</td>
      <td>User provides different networks for from_network and to_network</td>
    </tr>
    <tr>
      <td>`payments-3001`</td>
      <td>400</td>
      <td>invalid from_amount or to_amount</td>
      <td>from_amount and to_amount should be positive and be valid numbers</td>
    </tr>
    <tr>
      <td>`payments-3002`</td>
      <td>400</td>
      <td>Either from_amount or to_amount must be provided. Cannot create payment without an amount.</td>
      <td>User does not provide either from_amount or to_amount</td>
    </tr>
    <tr>
      <td>`payments-3003`</td>
      <td>400</td>
      <td>Only one of from_amount or to_amount should be provided. The other will be calculated using the exchange rate.</td>
      <td>User provides both from_amount and to_amount when only one should be provided</td>
    </tr>
    <tr>
      <td>`payments-3004`</td>
      <td>400</td>
      <td>from_network is required for crypto-to-crypto payments</td>
      <td>User creates a payment with stablecoin from_currency but does not provide from_network</td>
    </tr>
    <tr>
      <td>`payments-3005`</td>
      <td>400</td>
      <td>to_network is required for crypto-to-crypto payments</td>
      <td>User creates a payment with stablecoin to_currency but does not provide to_network</td>
    </tr>
    <tr>
      <td>`payments-3006`</td>
      <td>400</td>
      <td>Onramp (fiat-to-crypto) payments are not yet supported. Coming soon!</td>
      <td>User attempts to create an onramp payment which is not supported yet</td>
    </tr>
    <tr>
      <td>`payments-3007`</td>
      <td>400</td>
      <td>Invalid from_currency</td>
      <td>User provides a from_currency that is not supported</td>
    </tr>
    <tr>
      <td>`payments-3008`</td>
      <td>400</td>
      <td>Invalid to_currency</td>
      <td>User provides a to_currency that is not supported</td>
    </tr>
    <tr>
      <td>`payments-3009`</td>
      <td>400</td>
      <td>funding_account_id not found</td>
      <td>User provides a funding_account_id that does not exist</td>
    </tr>
    <tr>
      <td>`payments-3010`</td>
      <td>400</td>
      <td>to_account_id not found</td>
      <td>User provides a to_account_id that does not exist</td>
    </tr>
    <tr>
      <td>`payments-3011`</td>
      <td>400</td>
      <td>from_account_id not found</td>
      <td>User provides a from_account_id that does not exist</td>
    </tr>
    <tr>
      <td>`payments-3012`</td>
      <td>400</td>
      <td>Missing input parameter is_approved</td>
      <td>User submits a payment review without the required is_approved parameter</td>
    </tr>
    <tr>
      <td>`payments-3015`</td>
      <td>400</td>
      <td>The exchange rate quote has expired. Please create a new payment to get a fresh quote.</td>
      <td>User attempts to execute a payment with an expired exchange rate quote (valid for 24 hours)</td>
    </tr>
    <tr>
      <td>`payments-3016`</td>
      <td>400</td>
      <td>Payment quote expiration data is missing. Please create a new payment to get a fresh quote.</td>
      <td>Payment has an exchange rate but is missing expiration data, indicating a data integrity issue</td>
    </tr>
    <tr>
      <td>`payments-3017`</td>
      <td>400</td>
      <td>to_account has not yet been risk approved by custodian</td>
      <td>Beneficiary account has a Circle recipient that is still pending verification or has not been registered yet</td>
    </tr>
    <tr>
      <td>`payments-3018`</td>
      <td>400</td>
      <td>from_account_id and to_account_id should not both be managed accounts for payments. Use /v1/treasury/rebalances instead.</td>
      <td>Transfers between two managed accounts are treasury operations. Use /v1/treasury/rebalances instead.</td>
    </tr>
    <tr>
      <td>`payments-3019`</td>
      <td>400</td>
      <td>Account asset not found for &#123;from_account_id&#125;</td>
      <td>No matching account asset found for the from account with the specified currency and network</td>
    </tr>
    <tr>
      <td>`payments-3020`</td>
      <td>400</td>
      <td>No &#123;currency&#125; balance found on network &#123;network&#125; for &#123;to_account_id&#125;</td>
      <td>The to account does not have a balance for the specified currency and network</td>
    </tr>
    <tr>
      <td>`payments-3021`</td>
      <td>400</td>
      <td>Amounts not yet calculated. Payment may still be processing.</td>
      <td>Payment amounts have not been calculated yet, the payment may still be processing</td>
    </tr>
    <tr>
      <td>`payments-3022`</td>
      <td>400</td>
      <td>Payment missing currency information</td>
      <td>Payment is missing required currency or network data</td>
    </tr>
    <tr>
      <td>`payments-3023`</td>
      <td>400</td>
      <td>Payment has not passed compliance screening. Cannot execute.</td>
      <td>Payment has not been approved through compliance/risk screening</td>
    </tr>
    <tr>
      <td>`payments-3024`</td>
      <td>400</td>
      <td>Payment does not have reserved balance. Cannot execute.</td>
      <td>Payment balance has not been reserved prior to execution</td>
    </tr>
    <tr>
      <td>`payments-3025`</td>
      <td>400</td>
      <td>No transfer step found for payment</td>
      <td>Payment does not have a transfer step</td>
    </tr>
    <tr>
      <td>`payments-3026`</td>
      <td>400</td>
      <td>Transfer step is already in status &#123;status&#125;. Cannot execute.</td>
      <td>Transfer step is in a status that does not allow execution</td>
    </tr>
    <tr>
      <td>`payments-3027`</td>
      <td>400</td>
      <td>Transfer step missing account asset IDs. Cannot execute.</td>
      <td>Transfer step is missing the required from or to account asset IDs</td>
    </tr>
    <tr>
      <td>`payments-3028`</td>
      <td>400</td>
      <td>Could not load accounts for execution</td>
      <td>Failed to load the from or to account required for payment execution</td>
    </tr>
    <tr>
      <td>`payments-3029`</td>
      <td>400</td>
      <td>Payment missing required data for step creation</td>
      <td>Payment is missing required currency, amount, or network information for step creation</td>
    </tr>
    <tr>
      <td>`payments-3030`</td>
      <td>400</td>
      <td>To asset is required for onchain payments</td>
      <td>Onchain payment steps require a to account asset to be resolved</td>
    </tr>
    <tr>
      <td>`payments-3031`</td>
      <td>400</td>
      <td>To account &#123;id&#125; is not a fiat account</td>
      <td>The to account is not the expected fiat_bank type for offramp payments</td>
    </tr>
    <tr>
      <td>`payments-3032`</td>
      <td>400</td>
      <td>Account &#123;id&#125; does not belong to workspace</td>
      <td>The referenced account does not belong to the payment's workspace</td>
    </tr>
    <tr>
      <td>`payments-3033`</td>
      <td>400</td>
      <td>Account not found for address &#123;address&#125;</td>
      <td>No account found with the specified wallet address</td>
    </tr>
    <tr>
      <td>`payments-3034`</td>
      <td>400</td>
      <td>Account &#123;id&#125; has no entity ID</td>
      <td>The account is missing the required entity ID for payment processing</td>
    </tr>
    <tr>
      <td>`payments-3035`</td>
      <td>400</td>
      <td>Fiat account &#123;id&#125; not found for workspace</td>
      <td>The specified fiat account was not found in the workspace</td>
    </tr>
    <tr>
      <td>`payments-3036`</td>
      <td>400</td>
      <td>Payment has not been updated with accounts. Please call PATCH /payments/:paymentId first.</td>
      <td>Payment must be updated with account IDs before execution</td>
    </tr>
    <tr>
      <td>`payments-3038`</td>
      <td>400</td>
      <td>Unsupported network for signing: &#123;network&#125;</td>
      <td>The payment network is not supported for transaction signing</td>
    </tr>
    <tr>
      <td>`payments-3040`</td>
      <td>400</td>
      <td>Cannot execute payment from external account &#123;id&#125;</td>
      <td>External accounts support CRUD operations only. Use managed accounts for payment execution.</td>
    </tr>
    <tr>
      <td>`payments-3041`</td>
      <td>400</td>
      <td>No payment execution provider available for this payment</td>
      <td>No supported provider (Circle) could be resolved for this payment type and account combination</td>
    </tr>
    <tr>
      <td>`payments-3042`</td>
      <td>400</td>
      <td>Source account asset not found</td>
      <td>The source account asset could not be found for payment execution</td>
    </tr>
    <tr>
      <td>`payments-3043`</td>
      <td>400</td>
      <td>Source account wallet address not found</td>
      <td>The source account does not have a crypto wallet address</td>
    </tr>
    <tr>
      <td>`payments-3044`</td>
      <td>400</td>
      <td>Destination account asset not found</td>
      <td>The destination account asset could not be found for payment execution</td>
    </tr>
    <tr>
      <td>`payments-3045`</td>
      <td>400</td>
      <td>Destination account wallet address not found</td>
      <td>The destination account does not have a crypto wallet address</td>
    </tr>
    <tr>
      <td>`payments-3047`</td>
      <td>400</td>
      <td>Wallet address mismatch</td>
      <td>The provided wallet address does not match the account's wallet address</td>
    </tr>
    <tr>
      <td>`payments-3048`</td>
      <td>400</td>
      <td>Amount mismatch between transfer step and provided amount</td>
      <td>The provided amount does not match the transfer step amount</td>
    </tr>
    <tr>
      <td>`payments-3049`</td>
      <td>400</td>
      <td>Transfer step missing from account asset ID</td>
      <td>The transfer step does not have a from account asset ID set</td>
    </tr>
    <tr>
      <td>`payments-3052`</td>
      <td>400</td>
      <td>direction must be 'inbound' or 'outbound'</td>
      <td>GET /payments only filters transfers by direction; rebalance and other internal directions are rejected</td>
    </tr>
    <tr>
      <td>`payments-3053`</td>
      <td>400</td>
      <td>Simulated inbound payments are not available in production</td>
      <td>Inbound payment simulation is not available in production environments</td>
    </tr>
    <tr>
      <td>`payments-3054`</td>
      <td>400</td>
      <td>Unsupported network for inbound payment simulation</td>
      <td>Inbound simulation supports only the BASE_SEPOLIA, ETHEREUM_SEPOLIA and POLYGON_AMOY testnets with USDC</td>
    </tr>
    <tr>
      <td>`payments-3055`</td>
      <td>400</td>
      <td>Destination account cannot receive a simulated inbound</td>
      <td>to_account exists but is not a managed stablecoin_ethereum wallet with an on-chain address</td>
    </tr>
    <tr>
      <td>`payments-3060`</td>
      <td>400</td>
      <td>Payment step is not in a signable state</td>
      <td>The step must be a turnkey step in 'signature_requested' state with a prepared unsigned transaction to accept a signature</td>
    </tr>
    <tr>
      <td>`payments-3061`</td>
      <td>400</td>
      <td>Payment step is missing an unsigned transaction payload</td>
      <td>The payment has not yet prepared an unsigned transaction — retry in a moment</td>
    </tr>
    <tr>
      <td>`payments-3062`</td>
      <td>400</td>
      <td>Payment step is missing the source amount or currency</td>
      <td>The step's estimated source amount and currency must be set before signing</td>
    </tr>
    <tr>
      <td>`payments-3063`</td>
      <td>400</td>
      <td>Source wallet has insufficient on-chain balance</td>
      <td>The live on-chain balance of the source wallet is below the payment amount; fund the wallet and retry before the payment expires</td>
    </tr>
    <tr>
      <td>`payments-3064`</td>
      <td>400</td>
      <td>Turnkey could not produce a signed transaction</td>
      <td>Turnkey rejected or failed the stamped sign_transaction activity. Verify the stamp matches the body bytes, the API key is registered in the sub-org, and the wallet exists in that sub-org.</td>
    </tr>
    <tr>
      <td>`payments-3065`</td>
      <td>400</td>
      <td>Signature is invalid or could not be verified</td>
      <td>The Turnkey stamp did not produce a valid signed transaction</td>
    </tr>
    <tr>
      <td>`payments-3066`</td>
      <td>400</td>
      <td>Signed transaction does not match the payment details</td>
      <td>The destination address or amount in the signed transaction does not match the prepared payment step</td>
    </tr>
    <tr>
      <td>`payments-3067`</td>
      <td>400</td>
      <td>Signature is not a valid base64-encoded &#123;body, stamp&#125; envelope</td>
      <td>The signature field must be base64-encoded JSON containing the Turnkey activity body and stamp header value</td>
    </tr>
    <tr>
      <td>`payments-3068`</td>
      <td>400</td>
      <td>Currency is not supported for on-chain payment signing</td>
      <td>Only currencies with a registered token contract on the payment network can be signed</td>
    </tr>
    <tr>
      <td>`payments-3069`</td>
      <td>400</td>
      <td>Network is not supported for on-chain payment signing</td>
      <td>The payment network has no registered on-chain signing configuration</td>
    </tr>
    <tr>
      <td>`payments-3070`</td>
      <td>400</td>
      <td>Stamped activity type must be '&#123;expected&#125;', received '&#123;actual&#125;'</td>
      <td>The stamped Turnkey activity must be ACTIVITY_TYPE_SIGN_TRANSACTION_V2 to sign a payment step</td>
    </tr>
    <tr>
      <td>`payments-3071`</td>
      <td>400</td>
      <td>Stamped activity unsigned transaction does not match the payment step</td>
      <td>The unsigned transaction inside the stamped Turnkey activity must equal the unsigned transaction prepared by the payment step</td>
    </tr>
    <tr>
      <td>`payments-3072`</td>
      <td>400</td>
      <td>Stamped activity sign_with address does not match the payment source wallet</td>
      <td>The sign_with parameter inside the stamped Turnkey activity must equal the source wallet's on-chain address</td>
    </tr>
    <tr>
      <td>`payments-3073`</td>
      <td>400</td>
      <td>Stamped activity transaction type must be '&#123;expected&#125;', received '&#123;actual&#125;'</td>
      <td>The transaction type inside the stamped Turnkey activity must match the payment network's Turnkey transaction type</td>
    </tr>
    <tr>
      <td>`payments-3074`</td>
      <td>400</td>
      <td>Stamped activity organization does not match the workspace's Turnkey sub-organization</td>
      <td>The stamped Turnkey activity's organization id must equal the workspace's configured Turnkey sub-org ID</td>
    </tr>
    <tr>
      <td>`payments-3075`</td>
      <td>400</td>
      <td>Network '&#123;network&#125;' is not supported in this environment</td>
      <td>Payments from managed wallets only support mainnet networks in production and their testnet counterparts in non-production environments</td>
    </tr>
    <tr>
      <td>`payments-3076`</td>
      <td>400</td>
      <td>from_account_id '&#123;from_account_id&#125;' cannot fund outbound payments: no execution provider available for this account</td>
      <td>The source account does not resolve to a payment execution provider. Outbound payments must be funded from a managed wallet or a provider-backed ledger account (e.g. the Circle Mint master ledger).</td>
    </tr>
    <tr>
      <td>`payments-3077`</td>
      <td>400</td>
      <td>Required CPN compliance field &#123;field&#125; could not be resolved from the payment's counterparty/account data</td>
      <td>The Circle Payments Network quote requires a travel-rule or beneficiary-account field for which no value (or no mapping) exists on the originator, beneficiary, beneficiary bank account, or OFI identity. Tesser validates existing data and fails fast rather than collecting new data.</td>
    </tr>
    <tr>
      <td>`payments-3078`</td>
      <td>400</td>
      <td>Cross-currency payments are not supported. from_currency and to_currency must match.</td>
      <td>User attempts a cross-currency payment; payments are same-currency stablecoin only</td>
    </tr>
    <tr>
      <td>`payments-3079`</td>
      <td>409</td>
      <td>Payment accounts can no longer be changed; the payment has already been planned.</td>
      <td>PATCH attempted account changes after the payment's steps were planned; accounts are frozen once planning runs</td>
    </tr>
    <tr>
      <td>`payments-3080`</td>
      <td>409</td>
      <td>The on-chain transaction was rejected because its nonce was already used by another transaction from this wallet. This payment is now in a failed state. You must create a new payment in order to try again.</td>
      <td>Another transaction from the same wallet consumed this nonce before the signed transaction reached the network. The step is already failed and its signed transaction carries the spent nonce, so this payment cannot be retried — create a new payment, which is planned against a fresh nonce.</td>
    </tr>
    <tr>
      <td>`payments-3081`</td>
      <td>500</td>
      <td>The signed transaction could not be broadcast</td>
      <td>The network rejected the signed transaction for a reason other than a nonce conflict; the node's reason is on the step's status_reasons.</td>
    </tr>
    <tr>
      <td>`payments-3082`</td>
      <td>409</td>
      <td>This payment waited for earlier payments from the same wallet to be submitted, but the wait expired. This payment is now in a failed state. You must create a new payment in order to try again.</td>
      <td>The signed transaction's nonce was ahead of the wallet's submission watermark and the missing lower nonces were not submitted within the wait window. The step is already failed; a new payment is planned against a fresh nonce.</td>
    </tr>
    <tr>
      <td>`payments-3083`</td>
      <td>400</td>
      <td>Travel-rule inbound simulation is not enabled for this organization</td>
      <td>The notabene-travel-rule-inbound feature flag must be enabled for the calling organization</td>
    </tr>
    <tr>
      <td>`payments-3084`</td>
      <td>503</td>
      <td>Travel-rule inbound simulation is not configured in this environment</td>
      <td>The platform-level simulator VASP credentials are absent in this environment. Nothing in the request can fix this — the environment is missing configuration.</td>
    </tr>
    <tr>
      <td>`payments-3085`</td>
      <td>400</td>
      <td>This organization has no Notabene VASP configured</td>
      <td>The organization must have Notabene credentials, including its vaspDid, stored before it can receive a simulated travel-rule inbound</td>
    </tr>
    <tr>
      <td>`payments-3086`</td>
      <td>400</td>
      <td>The destination account '&#123;id&#125;' has no beneficiary name to claim</td>
      <td>The simulated counterparty claims the destination owner's own name by default, and the destination resolved to no usable party name. Supply claimed_beneficiary_name, or give the account's entity a name.</td>
    </tr>
  </tbody>
</table>

## Tenants

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`tenants-1000`</td>
      <td>404</td>
      <td>Tenant not found</td>
      <td>The specified tenant ID does not exist</td>
    </tr>
    <tr>
      <td>`tenants-2000`</td>
      <td>403</td>
      <td>You do not have access to this tenant</td>
      <td>User tries to access a tenant that belongs to a different workspace</td>
    </tr>
    <tr>
      <td>`tenants-3000`</td>
      <td>400</td>
      <td>business_legal_name is required to create a tenant</td>
      <td>User creates a tenant without providing the required business_legal_name field</td>
    </tr>
    <tr>
      <td>`tenants-3001`</td>
      <td>400</td>
      <td>business_legal_name is required and must be 1-255 characters</td>
      <td>User provides a business_legal_name that doesn't meet length requirements</td>
    </tr>
    <tr>
      <td>`tenants-3002`</td>
      <td>400</td>
      <td>business_address_country must be a valid ISO 3166-1 alpha-2 country code</td>
      <td>User provides a business_address_country that is not a valid 2-letter country code</td>
    </tr>
    <tr>
      <td>`tenants-3003`</td>
      <td>400</td>
      <td>webhook_url must be a valid HTTPS URL</td>
      <td>User provides a webhook_url that is not a properly formatted HTTPS URL</td>
    </tr>
  </tbody>
</table>

## Treasury

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`treasury-1000`</td>
      <td>404</td>
      <td>Rebalance with id '&#123;id&#125;' not found</td>
      <td>The specified rebalance ID does not exist</td>
    </tr>
    <tr>
      <td>`treasury-1001`</td>
      <td>404</td>
      <td>Transfer step not found for rebalance with id '&#123;id&#125;'</td>
      <td>The transfer step associated with the rebalance could not be found</td>
    </tr>
    <tr>
      <td>`treasury-1002`</td>
      <td>404</td>
      <td>Account with id '&#123;id&#125;' not found</td>
      <td>The specified account ID does not exist or does not belong to this workspace</td>
    </tr>
    <tr>
      <td>`treasury-1100`</td>
      <td>404</td>
      <td>Deposit with id '&#123;id&#125;' not found</td>
      <td>The specified deposit ID does not exist in this workspace</td>
    </tr>
    <tr>
      <td>`treasury-1101`</td>
      <td>404</td>
      <td>Account with id '&#123;id&#125;' not found</td>
      <td>The specified account ID does not exist or does not belong to this workspace</td>
    </tr>
    <tr>
      <td>`treasury-1102`</td>
      <td>404</td>
      <td>Source account with id '&#123;id&#125;' not found</td>
      <td>The source bank account for this deposit could not be found</td>
    </tr>
    <tr>
      <td>`treasury-1103`</td>
      <td>404</td>
      <td>VAN account with id '&#123;id&#125;' not found</td>
      <td>The virtual account number (VAN) account could not be found</td>
    </tr>
    <tr>
      <td>`treasury-1200`</td>
      <td>404</td>
      <td>Withdrawal with id '&#123;id&#125;' not found</td>
      <td>The specified withdrawal ID does not exist in this workspace</td>
    </tr>
    <tr>
      <td>`treasury-1201`</td>
      <td>404</td>
      <td>Source account '&#123;id&#125;' not found</td>
      <td>The withdrawal source account does not exist or does not belong to this workspace</td>
    </tr>
    <tr>
      <td>`treasury-1202`</td>
      <td>404</td>
      <td>Destination bank account '&#123;id&#125;' not found</td>
      <td>The withdrawal destination bank account does not exist or does not belong to this workspace</td>
    </tr>
    <tr>
      <td>`treasury-1203`</td>
      <td>404</td>
      <td>Transfer step not found for withdrawal with id '&#123;id&#125;'</td>
      <td>The transfer step associated with the withdrawal could not be found</td>
    </tr>
    <tr>
      <td>`treasury-2100`</td>
      <td>409</td>
      <td>Deposit is still being planned. Wait for the deposit.created webhook before fetching instructions.</td>
      <td>Instructions were requested while the deposit's async planning step is still running (steps array is empty). Retry after the deposit.created webhook fires.</td>
    </tr>
    <tr>
      <td>`treasury-3000`</td>
      <td>400</td>
      <td>Unsupported rebalance direction. Supported: ledger→ledger, ledger→wallet, wallet→wallet</td>
      <td>The source/destination account types are not a supported rebalance flow</td>
    </tr>
    <tr>
      <td>`treasury-3001`</td>
      <td>400</td>
      <td>Network must not be specified for ledger accounts</td>
      <td>Ledger-to-ledger rebalances operate without a blockchain network</td>
    </tr>
    <tr>
      <td>`treasury-3002`</td>
      <td>400</td>
      <td>At least one of from_amount or to_amount must be provided</td>
      <td>A rebalance requires at least one amount to determine the transfer size</td>
    </tr>
    <tr>
      <td>`treasury-3003`</td>
      <td>400</td>
      <td>Invalid currency pair for rebalance</td>
      <td>The specified from_currency and to_currency combination is not supported for Circle rebalancing</td>
    </tr>
    <tr>
      <td>`treasury-3004`</td>
      <td>400</td>
      <td>from_amount and to_amount must be equal when currencies are the same</td>
      <td>When both amounts are provided for same-currency rebalances, they must match</td>
    </tr>
    <tr>
      <td>`treasury-3005`</td>
      <td>400</td>
      <td>Source or destination account is missing Circle wallet ID</td>
      <td>The account does not have a Circle wallet ID configured, which is required for ledger transfers</td>
    </tr>
    <tr>
      <td>`treasury-3006`</td>
      <td>400</td>
      <td>Transfer step is missing account asset IDs</td>
      <td>The transfer step does not have the required from/to account asset references</td>
    </tr>
    <tr>
      <td>`treasury-3007`</td>
      <td>400</td>
      <td>Network is required when rebalancing between wallet accounts</td>
      <td>On-chain wallet-to-wallet rebalances need from_network and to_network to be set</td>
    </tr>
    <tr>
      <td>`treasury-3008`</td>
      <td>400</td>
      <td>from_network and to_network must match for wallet-to-wallet rebalance</td>
      <td>Cross-chain wallet-to-wallet rebalance is not supported yet; source and destination network must be identical</td>
    </tr>
    <tr>
      <td>`treasury-3009`</td>
      <td>400</td>
      <td>Wallet account is missing a crypto wallet address</td>
      <td>On-chain wallet-to-wallet rebalance requires both accounts to have a crypto wallet address</td>
    </tr>
    <tr>
      <td>`treasury-3010`</td>
      <td>400</td>
      <td>Wallet-to-wallet rebalance is only supported between managed wallets</td>
      <td>Both source and destination accounts must be Tesser-managed (is_managed = true) wallet accounts</td>
    </tr>
    <tr>
      <td>`treasury-3011`</td>
      <td>400</td>
      <td>Currency '&#123;currency&#125;' is not supported for wallet-to-wallet rebalance</td>
      <td>On-chain wallet-to-wallet rebalance currently supports USDC only</td>
    </tr>
    <tr>
      <td>`treasury-3012`</td>
      <td>400</td>
      <td>Network '&#123;network&#125;' is not supported for wallet-to-wallet rebalance</td>
      <td>On-chain wallet-to-wallet rebalance currently supports BASE and BASE_SEPOLIA only</td>
    </tr>
    <tr>
      <td>`treasury-3013`</td>
      <td>400</td>
      <td>Rebalance step is not in a signable state</td>
      <td>The step must be a turnkey step in 'signature_requested' state with a prepared unsigned transaction to accept a signature</td>
    </tr>
    <tr>
      <td>`treasury-3014`</td>
      <td>400</td>
      <td>Rebalance step is missing an unsigned transaction payload</td>
      <td>The rebalance has not yet prepared an unsigned transaction — retry in a moment</td>
    </tr>
    <tr>
      <td>`treasury-3015`</td>
      <td>400</td>
      <td>Signature is invalid or could not be verified</td>
      <td>The Turnkey stamp did not produce a valid signed transaction</td>
    </tr>
    <tr>
      <td>`treasury-3016`</td>
      <td>400</td>
      <td>Signed transaction does not match the rebalance details</td>
      <td>The destination address or amount in the signed transaction does not match the prepared rebalance step</td>
    </tr>
    <tr>
      <td>`treasury-3017`</td>
      <td>400</td>
      <td>Destination wallet is not registered with Circle or compliance is not active</td>
      <td>The destination managed wallet must have an active Circle business recipient registration before it can receive rebalance transfers</td>
    </tr>
    <tr>
      <td>`treasury-3018`</td>
      <td>400</td>
      <td>to_network is required when destination is a managed wallet</td>
      <td>Rebalances to a managed stablecoin wallet must specify the target blockchain network</td>
    </tr>
    <tr>
      <td>`treasury-3019`</td>
      <td>400</td>
      <td>Network '&#123;network&#125;' is not supported in this environment</td>
      <td>Rebalances to managed wallets only support BASE in production and BASE_SEPOLIA in non-production environments</td>
    </tr>
    <tr>
      <td>`treasury-3020`</td>
      <td>400</td>
      <td>Signature is not a valid base64-encoded &#123;body, stamp&#125; envelope</td>
      <td>The signature field must be base64-encoded JSON containing the Turnkey activity body and stamp header value</td>
    </tr>
    <tr>
      <td>`treasury-3021`</td>
      <td>400</td>
      <td>Stamped activity type must be '&#123;expected&#125;', received '&#123;actual&#125;'</td>
      <td>The stamped Turnkey activity must be ACTIVITY_TYPE_SIGN_TRANSACTION_V2 to sign a rebalance step</td>
    </tr>
    <tr>
      <td>`treasury-3022`</td>
      <td>400</td>
      <td>Stamped activity unsigned transaction does not match the rebalance step</td>
      <td>The unsignedTransaction inside the stamped Turnkey activity must equal the unsigned transaction prepared by the rebalance step</td>
    </tr>
    <tr>
      <td>`treasury-3023`</td>
      <td>400</td>
      <td>Stamped activity signWith address does not match the rebalance source wallet</td>
      <td>The signWith parameter inside the stamped Turnkey activity must equal the source wallet's on-chain address</td>
    </tr>
    <tr>
      <td>`treasury-3024`</td>
      <td>400</td>
      <td>Stamped activity organizationId does not match the workspace's Turnkey sub-organization</td>
      <td>The stamped Turnkey activity's organizationId must equal the workspace's configured Turnkey sub-org ID</td>
    </tr>
    <tr>
      <td>`treasury-3025`</td>
      <td>400</td>
      <td>Turnkey could not produce a signed transaction</td>
      <td>Turnkey rejected or failed the stamped sign_transaction activity. Verify the stamp matches the body bytes, the API key is registered in the sub-org, and the wallet exists in that sub-org.</td>
    </tr>
    <tr>
      <td>`treasury-3026`</td>
      <td>400</td>
      <td>Stamped activity parameters.type must be '&#123;expected&#125;', received '&#123;actual&#125;'</td>
      <td>The Turnkey transaction type inside parameters.type must match the network of the rebalance step (e.g. TRANSACTION_TYPE_ETHEREUM for BASE)</td>
    </tr>
    <tr>
      <td>`treasury-3027`</td>
      <td>500</td>
      <td>OpenFX rebalance step is missing required metadata (&#123;reason&#125;) for id '&#123;id&#125;'</td>
      <td>The transfer step or destination account is missing fields the OpenFX withdrawal trigger needs to dispatch the rebalance</td>
    </tr>
    <tr>
      <td>`treasury-3028`</td>
      <td>409</td>
      <td>Source wallet has insufficient on-chain balance to sign</td>
      <td>The wallet's live on-chain balance is below the rebalance amount at sign time. The balance is re-checked when you retry; rebalance.balance_updated fires with balance_status 'awaiting_funds'.</td>
    </tr>
    <tr>
      <td>`treasury-3029`</td>
      <td>502</td>
      <td>Failed to generate an OpenFX quote for &#123;fromCurrency&#125; → &#123;toCurrency&#125;</td>
      <td>OpenFX could not return a projection quote for the cross-currency rebalance swap leg. Retry; if it persists the pair may be unsupported by OpenFX.</td>
    </tr>
    <tr>
      <td>`treasury-3030`</td>
      <td>400</td>
      <td>Destination wallet is registered with Circle on a different network than the requested one</td>
      <td>Rebalance to a Circle-bound wallet whose registered recipient chain doesn't match the requested to_network.</td>
    </tr>
    <tr>
      <td>`treasury-3031`</td>
      <td>400</td>
      <td>Destination wallet is not registered with OpenFX for the requested coin and network</td>
      <td>Rebalance to a wallet that has no matching active OpenFX withdrawal address for the coin+network.</td>
    </tr>
    <tr>
      <td>`treasury-3100`</td>
      <td>400</td>
      <td>Account '&#123;id&#125;' is not a ledger account</td>
      <td>Deposits can only be made to ledger accounts</td>
    </tr>
    <tr>
      <td>`treasury-3101`</td>
      <td>400</td>
      <td>Account '&#123;id&#125;' is not configured for deposits. No supported provider found</td>
      <td>The destination account does not have a supported deposit provider configured</td>
    </tr>
    <tr>
      <td>`treasury-3102`</td>
      <td>400</td>
      <td>Ledger '&#123;id&#125;' is missing Circle Mint metadata</td>
      <td>The ledger account does not have the required Circle Mint configuration</td>
    </tr>
    <tr>
      <td>`treasury-3103`</td>
      <td>400</td>
      <td>Circle compliance not yet accepted for ledger. Cannot create deposit</td>
      <td>Circle compliance must be accepted before deposits can be created</td>
    </tr>
    <tr>
      <td>`treasury-3104`</td>
      <td>400</td>
      <td>Source account '&#123;id&#125;' does not match the configured source bank for this ledger</td>
      <td>The provided source account does not match the bank account configured for this ledger</td>
    </tr>
    <tr>
      <td>`treasury-3105`</td>
      <td>400</td>
      <td>Source bank account '&#123;id&#125;' not found or is not a fiat bank account</td>
      <td>The source bank account could not be found or is not the correct account type</td>
    </tr>
    <tr>
      <td>`treasury-3106`</td>
      <td>400</td>
      <td>Ledger account '&#123;id&#125;' does not have a '&#123;currency&#125;' asset</td>
      <td>The destination ledger account does not hold the requested currency</td>
    </tr>
    <tr>
      <td>`treasury-3107`</td>
      <td>400</td>
      <td>Invalid currency combination for Circle deposit: &#123;fromCurrency&#125; → &#123;toCurrency&#125;</td>
      <td>The specified from_currency and to_currency combination is not supported for Circle deposits</td>
    </tr>
    <tr>
      <td>`treasury-3108`</td>
      <td>400</td>
      <td>Deposit '&#123;id&#125;' is already finalized. Wire instructions are no longer available</td>
      <td>The deposit has already been finalized and instructions cannot be retrieved</td>
    </tr>
    <tr>
      <td>`treasury-3109`</td>
      <td>400</td>
      <td>Deposit '&#123;id&#125;' has no transfer step</td>
      <td>The deposit does not have the expected transfer step</td>
    </tr>
    <tr>
      <td>`treasury-3110`</td>
      <td>400</td>
      <td>Deposit '&#123;id&#125;' transfer step has no source account</td>
      <td>The deposit transfer step is missing its source account reference</td>
    </tr>
    <tr>
      <td>`treasury-3111`</td>
      <td>400</td>
      <td>Deposit '&#123;id&#125;' transfer step has no destination account</td>
      <td>The deposit transfer step is missing its destination account reference</td>
    </tr>
    <tr>
      <td>`treasury-3112`</td>
      <td>400</td>
      <td>Source account '&#123;id&#125;' is missing required bank details</td>
      <td>The source account does not have all required bank details (bank name, code type, identifier code, or account number)</td>
    </tr>
    <tr>
      <td>`treasury-3113`</td>
      <td>400</td>
      <td>VAN account '&#123;id&#125;' missing virtual_account_number metadata</td>
      <td>The VAN account does not have the required virtual account number metadata</td>
    </tr>
    <tr>
      <td>`treasury-3114`</td>
      <td>400</td>
      <td>VAN account '&#123;id&#125;' is missing required field: &#123;field&#125;</td>
      <td>The VAN account is missing a required field for wire instructions (e.g., bank name, account number, SWIFT code, beneficiary name)</td>
    </tr>
    <tr>
      <td>`treasury-3115`</td>
      <td>400</td>
      <td>Simulated deposits are not available in production</td>
      <td>Deposit simulation is only available in sandbox environments</td>
    </tr>
    <tr>
      <td>`treasury-3116`</td>
      <td>400</td>
      <td>to_network is required when destination is a managed wallet</td>
      <td>Deposits to a managed stablecoin wallet must specify the target blockchain network</td>
    </tr>
    <tr>
      <td>`treasury-3117`</td>
      <td>400</td>
      <td>to_network must not be specified for ledger accounts</td>
      <td>Deposits to ledger accounts operate without a blockchain network</td>
    </tr>
    <tr>
      <td>`treasury-3118`</td>
      <td>400</td>
      <td>Network '&#123;network&#125;' is not supported in this environment</td>
      <td>Deposits to managed wallets only support BASE in production and BASE_SEPOLIA in non-production environments</td>
    </tr>
    <tr>
      <td>`treasury-3119`</td>
      <td>400</td>
      <td>Deposit '&#123;id&#125;' has no estimated source amount yet</td>
      <td>The deposit's estimated.from.amount or estimated.from.currency is not populated. The estimate is filled in after planning; this can occur if instructions are requested before the deposit has been planned.</td>
    </tr>
    <tr>
      <td>`treasury-3120`</td>
      <td>400</td>
      <td>No deposit provider can handle this configuration. Verify the source bank account, destination account compliance state, and currency pair.</td>
      <td>getEligibleDepositProviders returned an empty array — no provider matches the deposit's source account, destination account, currency pair, or workspace provider configuration (e.g., missing Circle API key in the vault).</td>
    </tr>
    <tr>
      <td>`treasury-3133`</td>
      <td>400</td>
      <td>Ledger '&#123;id&#125;' is missing OpenFX metadata</td>
      <td>The destination ledger account does not have OpenFX configuration (metadata.openfx)</td>
    </tr>
    <tr>
      <td>`treasury-3134`</td>
      <td>400</td>
      <td>Currency pair &#123;fromCurrency&#125; → &#123;toCurrency&#125; is not supported for OpenFX deposits</td>
      <td>OpenFX deposits support same-currency fiat→fiat or fiat→stablecoin (on-ramp) pairs only</td>
    </tr>
    <tr>
      <td>`treasury-3136`</td>
      <td>502</td>
      <td>Failed to obtain OpenFX quote for &#123;fromCurrency&#125; → &#123;toCurrency&#125;</td>
      <td>OpenFX rejected or did not respond to the projection quote during deposit planning. The deposit cannot be created until OpenFX returns a valid rate.</td>
    </tr>
    <tr>
      <td>`treasury-3137`</td>
      <td>502</td>
      <td>OpenFX trade failed for deposit '&#123;id&#125;' after retry budget</td>
      <td>The swap leg of an OpenFX cross-currency deposit could not be executed within the retry budget. The swap step has been marked as failed.</td>
    </tr>
    <tr>
      <td>`treasury-3138`</td>
      <td>502</td>
      <td>OpenFX quote expired before trade could execute</td>
      <td>OpenFX rejected the trade because the quote had expired (HTTP 422). The next attempt will request a fresh quote.</td>
    </tr>
    <tr>
      <td>`treasury-3139`</td>
      <td>400</td>
      <td>Wallet address '&#123;address&#125;' is not registered in OpenFX for &#123;coin&#125; on &#123;network&#125;</td>
      <td>The wallet must be manually registered in the OpenFX dashboard before it can receive deposits</td>
    </tr>
    <tr>
      <td>`treasury-3140`</td>
      <td>400</td>
      <td>Multiple OpenFX withdrawal addresses matched (&#123;count&#125;) — registration is ambiguous</td>
      <td>More than one verified active withdrawal address matched; resolve via the OpenFX dashboard</td>
    </tr>
    <tr>
      <td>`treasury-3141`</td>
      <td>400</td>
      <td>OpenFX coinNetworkName '&#123;coinNetworkName&#125;' is not a known Tesser network</td>
      <td>The network returned by OpenFX does not map to a supported Tesser network identifier</td>
    </tr>
    <tr>
      <td>`treasury-3142`</td>
      <td>400</td>
      <td>to_network is required for OpenFX wallet deposits</td>
      <td>OpenFX wallet deposits must specify the target blockchain network via to_network</td>
    </tr>
    <tr>
      <td>`treasury-3143`</td>
      <td>502</td>
      <td>OpenFX withdrawal failed for deposit '&#123;id&#125;' (reason: &#123;reason&#125;)</td>
      <td>The wallet leg of an OpenFX deposit could not be submitted to OpenFX. The withdrawal step has been marked as failed.</td>
    </tr>
    <tr>
      <td>`treasury-3144`</td>
      <td>400</td>
      <td>Source bank '&#123;id&#125;' is not registered with OpenFX (no fiatWithdrawalAddressId)</td>
      <td>The funding bank account has no OpenFX fiatWithdrawalAddressId and lazy rematch failed. Register the bank in OpenFX (or fix the rematch) before retrying the deposit.</td>
    </tr>
    <tr>
      <td>`treasury-3145`</td>
      <td>400</td>
      <td>Wallet account '&#123;id&#125;' is missing a crypto wallet address</td>
      <td>The managed wallet has no on-chain address, so it cannot be matched to an OpenFX withdrawal address. This is a permanent data fault, not a transient error.</td>
    </tr>
    <tr>
      <td>`treasury-3146`</td>
      <td>400</td>
      <td>Destination wallet is not an active Circle business recipient</td>
      <td>Deposit to a Circle-bound wallet whose circleBusinessRecipientId is missing or whose status is not active.</td>
    </tr>
    <tr>
      <td>`treasury-3147`</td>
      <td>400</td>
      <td>Destination wallet is registered with Circle on a different network than the requested one</td>
      <td>Deposit to a Circle-bound wallet whose registered recipient chain doesn't match the requested to_network.</td>
    </tr>
    <tr>
      <td>`treasury-3148`</td>
      <td>400</td>
      <td>Source bank is not activated with OpenFX yet</td>
      <td>The funding bank account is registered with OpenFX but its fiat withdrawal address is not active yet (e.g. under review). Wait for OpenFX approval before retrying the deposit.</td>
    </tr>
    <tr>
      <td>`treasury-3200`</td>
      <td>400</td>
      <td>from_currency must be a valid currency code</td>
      <td>User provides an invalid from_currency value</td>
    </tr>
    <tr>
      <td>`treasury-3201`</td>
      <td>400</td>
      <td>to_currency must be a valid currency code</td>
      <td>User provides an invalid to_currency value</td>
    </tr>
    <tr>
      <td>`treasury-3202`</td>
      <td>400</td>
      <td>from_amount must be a valid decimal string</td>
      <td>User provides a from_amount that is not a valid number</td>
    </tr>
    <tr>
      <td>`treasury-3203`</td>
      <td>400</td>
      <td>to_amount must be a valid decimal string</td>
      <td>User provides a to_amount that is not a valid number</td>
    </tr>
    <tr>
      <td>`treasury-3204`</td>
      <td>400</td>
      <td>from_account_id must be a valid UUID</td>
      <td>User provides a from_account_id that is not a valid UUID</td>
    </tr>
    <tr>
      <td>`treasury-3205`</td>
      <td>400</td>
      <td>to_account_id must be a valid UUID</td>
      <td>User provides a to_account_id that is not a valid UUID</td>
    </tr>
    <tr>
      <td>`treasury-3206`</td>
      <td>400</td>
      <td>from_network must be a valid network identifier</td>
      <td>User provides an invalid from_network value</td>
    </tr>
    <tr>
      <td>`treasury-3207`</td>
      <td>400</td>
      <td>to_network must be a valid network identifier</td>
      <td>User provides an invalid to_network value</td>
    </tr>
    <tr>
      <td>`treasury-3300`</td>
      <td>400</td>
      <td>from_amount must be provided</td>
      <td>Withdrawals must specify the source amount in major units</td>
    </tr>
    <tr>
      <td>`treasury-3301`</td>
      <td>400</td>
      <td>from_network must not be specified for ledger sources</td>
      <td>Ledger-source withdrawals operate without a blockchain network; from_network is only valid for wallet-source withdrawals</td>
    </tr>
    <tr>
      <td>`treasury-3302`</td>
      <td>400</td>
      <td>Currency pair &#123;fromCurrency&#125; → &#123;toCurrency&#125; is not supported for withdrawals</td>
      <td>Only USDC → USD withdrawals are supported in this release</td>
    </tr>
    <tr>
      <td>`treasury-3303`</td>
      <td>400</td>
      <td>Source account '&#123;id&#125;' must be a Circle USDC ledger for ledger-source withdrawals</td>
      <td>Ledger-source withdrawals require a managed Circle Mint ledger account as the source</td>
    </tr>
    <tr>
      <td>`treasury-3304`</td>
      <td>400</td>
      <td>Destination account '&#123;id&#125;' must be a workspace bank account</td>
      <td>Withdrawals can only target a workspace-level bank account (type=fiat_bank, no entity_id)</td>
    </tr>
    <tr>
      <td>`treasury-3305`</td>
      <td>400</td>
      <td>No master Circle USDC ledger found for this workspace</td>
      <td>Wallet-source withdrawals route through the workspace's master Circle ledger, which is created when the Circle API key is configured</td>
    </tr>
    <tr>
      <td>`treasury-3306`</td>
      <td>400</td>
      <td>Withdrawal step is not in a signable state</td>
      <td>The step must be a turnkey step in 'signature_requested' state with a prepared unsigned transaction to accept a signature</td>
    </tr>
    <tr>
      <td>`treasury-3307`</td>
      <td>400</td>
      <td>Withdrawal step is missing an unsigned transaction payload</td>
      <td>The withdrawal has not yet prepared an unsigned transaction — retry in a moment</td>
    </tr>
    <tr>
      <td>`treasury-3308`</td>
      <td>400</td>
      <td>Signature is invalid or could not be verified</td>
      <td>The Turnkey stamp did not produce a valid signed transaction</td>
    </tr>
    <tr>
      <td>`treasury-3309`</td>
      <td>400</td>
      <td>Signed transaction does not match the withdrawal details</td>
      <td>The destination address or amount in the signed transaction does not match the prepared withdrawal step</td>
    </tr>
    <tr>
      <td>`treasury-3310`</td>
      <td>400</td>
      <td>Signature is not a valid base64-encoded &#123;body, stamp&#125; envelope</td>
      <td>The signature field must be base64-encoded JSON containing the Turnkey activity body and stamp header value</td>
    </tr>
    <tr>
      <td>`treasury-3311`</td>
      <td>400</td>
      <td>Stamped activity type must be '&#123;expected&#125;', received '&#123;actual&#125;'</td>
      <td>The stamped Turnkey activity must be ACTIVITY_TYPE_SIGN_TRANSACTION_V2 to sign a withdrawal step</td>
    </tr>
    <tr>
      <td>`treasury-3312`</td>
      <td>400</td>
      <td>Stamped activity unsigned transaction does not match the withdrawal step</td>
      <td>The unsignedTransaction inside the stamped Turnkey activity must equal the unsigned transaction prepared by the withdrawal step</td>
    </tr>
    <tr>
      <td>`treasury-3313`</td>
      <td>400</td>
      <td>Stamped activity signWith address does not match the withdrawal source wallet</td>
      <td>The signWith parameter inside the stamped Turnkey activity must equal the source wallet's on-chain address</td>
    </tr>
    <tr>
      <td>`treasury-3314`</td>
      <td>400</td>
      <td>Stamped activity organizationId does not match the workspace's Turnkey sub-organization</td>
      <td>The stamped Turnkey activity's organizationId must equal the workspace's configured Turnkey sub-org ID</td>
    </tr>
    <tr>
      <td>`treasury-3315`</td>
      <td>400</td>
      <td>Turnkey could not produce a signed transaction</td>
      <td>Turnkey rejected or failed the stamped sign_transaction activity. Verify the stamp matches the body bytes, the API key is registered in the sub-org, and the wallet exists in that sub-org.</td>
    </tr>
    <tr>
      <td>`treasury-3316`</td>
      <td>400</td>
      <td>Stamped activity parameters.type must be '&#123;expected&#125;', received '&#123;actual&#125;'</td>
      <td>The Turnkey transaction type inside parameters.type must match the network of the withdrawal step (e.g. TRANSACTION_TYPE_ETHEREUM for BASE)</td>
    </tr>
    <tr>
      <td>`treasury-3317`</td>
      <td>400</td>
      <td>Currency '&#123;currency&#125;' is not supported for wallet-source withdrawal</td>
      <td>On-chain wallet-source withdrawal currently supports USDC only</td>
    </tr>
    <tr>
      <td>`treasury-3318`</td>
      <td>400</td>
      <td>Network '&#123;network&#125;' is not supported for wallet-source withdrawal</td>
      <td>The network on the withdrawal step is not a supported EVM network for on-chain signing</td>
    </tr>
    <tr>
      <td>`treasury-3319`</td>
      <td>409</td>
      <td>Source wallet has insufficient on-chain balance to sign</td>
      <td>The wallet's live on-chain balance is below the withdrawal amount at sign time. The balance is re-checked when you retry; withdrawal.balance_updated fires with balance_status 'awaiting_funds'.</td>
    </tr>
    <tr>
      <td>`treasury-3320`</td>
      <td>400</td>
      <td>No withdrawal provider can handle this configuration. Verify the source account, destination bank account, and currency pair.</td>
      <td>getEligibleWithdrawalProviders returned an empty array — no provider matches the withdrawal's source account, destination bank account, currency pair, or workspace provider configuration (e.g., missing Circle API key in the vault).</td>
    </tr>
    <tr>
      <td>`treasury-3321`</td>
      <td>400</td>
      <td>Deposit '&#123;id&#125;' has already received its funding wire. Wire instructions are no longer available</td>
      <td>The funding wire has already been received and instructions cannot be retrieved</td>
    </tr>
    <tr>
      <td>`treasury-3322`</td>
      <td>400</td>
      <td>Circle compliance not yet accepted for the source ledger. Cannot create withdrawal</td>
      <td>Withdrawal source is a Circle ledger whose circleComplianceState is not ACCEPTED.</td>
    </tr>
    <tr>
      <td>`treasury-3323`</td>
      <td>400</td>
      <td>Same-account rebalances require different currencies</td>
      <td>A same-account OpenFX rebalance is an FX swap and cannot have matching from/to currencies</td>
    </tr>
    <tr>
      <td>`treasury-3324`</td>
      <td>400</td>
      <td>Currency '&#123;currency&#125;' is not supported for a same-account swap</td>
      <td>A same-account OpenFX swap settles on the ledger, so both currencies must be representable in the Tesser currency registry</td>
    </tr>
    <tr>
      <td>`treasury-3325`</td>
      <td>400</td>
      <td>Destination bank '&#123;id&#125;' has no active OpenFX fiat withdrawal address for currency &#123;currency&#125;</td>
      <td>OpenFX fiat withdrawals pay out to pre-registered, per-currency fiat withdrawal addresses. No active address matched the destination bank's account number for the payout currency.</td>
    </tr>
    <tr>
      <td>`treasury-3326`</td>
      <td>400</td>
      <td>OpenFX could not quote the withdrawal pair &#123;fromCurrency&#125; → &#123;toCurrency&#125;</td>
      <td>The plan-time OpenFX quote for the withdrawal's swap leg failed. Pair eligibility is quote-driven (no hardcoded whitelist), so a failed quote means the pair is unsupported or the provider is unavailable.</td>
    </tr>
    <tr>
      <td>`treasury-3327`</td>
      <td>400</td>
      <td>Destination bank '&#123;id&#125;' is not activated with OpenFX yet (status: &#123;status&#125;)</td>
      <td>The destination bank matched an OpenFX fiat withdrawal address, but none of its addresses are active yet (e.g. under review). Wait for OpenFX approval before retrying the withdrawal.</td>
    </tr>
    <tr>
      <td>`treasury-3328`</td>
      <td>400</td>
      <td>OpenFX ledger '&#123;id&#125;' has no deposit address registered for &#123;currency&#125; on &#123;network&#125;</td>
      <td>No OpenFX deposit address is registered for the requested asset and network, so the wallet-source withdrawal fails closed.</td>
    </tr>
    <tr>
      <td>`treasury-3329`</td>
      <td>400</td>
      <td>Workspace '&#123;workspaceId&#125;' has no OpenFX-bound ledger</td>
      <td>Wallet-source withdrawals settle through the workspace's OpenFX ledger, and none is bound to this workspace.</td>
    </tr>
    <tr>
      <td>`treasury-3330`</td>
      <td>400</td>
      <td>Amount &#123;amount&#125; &#123;currency&#125; is below the OpenFX minimum on-chain deposit of &#123;minimum&#125; &#123;currency&#125;</td>
      <td>OpenFX never credits on-chain deposits below its minimum — sub-minimum funds are not shown on the ledger and are unrecoverable, so wallet-source withdrawals below the minimum fail closed before anything is dispatched on-chain.</td>
    </tr>
    <tr>
      <td>`treasury-3331`</td>
      <td>400</td>
      <td>Amount &#123;amount&#125; &#123;currency&#125; is below the provider's minimum tradable amount of &#123;minimum&#125; &#123;currency&#125;</td>
      <td>The route includes a currency conversion, and the provider enforces a per-currency minimum on the sold amount. A sub-minimum trade would be rejected at execution — after inbound funds already landed on the provider ledger — so the request fails closed at creation instead.</td>
    </tr>
    <tr>
      <td>`treasury-3332`</td>
      <td>400</td>
      <td>Amount &#123;amount&#125; &#123;currency&#125; is above the provider's maximum tradable amount of &#123;maximum&#125; &#123;currency&#125;</td>
      <td>The route includes a currency conversion, and the provider enforces a per-currency maximum on the sold amount. An above-maximum trade would be rejected at execution — after inbound funds already landed on the provider ledger — so the request fails closed at creation instead.</td>
    </tr>
    <tr>
      <td>`treasury-3333`</td>
      <td>400</td>
      <td>OpenFX ledger '&#123;id&#125;' has no deposit address registered for &#123;currency&#125; on &#123;network&#125;</td>
      <td>No OpenFX deposit address is registered on the destination ledger for the requested asset and network, so the wallet-source rebalance fails closed.</td>
    </tr>
    <tr>
      <td>`treasury-3334`</td>
      <td>400</td>
      <td>Amount &#123;amount&#125; &#123;currency&#125; is below the OpenFX minimum on-chain deposit of &#123;minimum&#125; &#123;currency&#125;</td>
      <td>OpenFX never credits on-chain deposits below its minimum — sub-minimum funds are not shown on the ledger and are unrecoverable, so wallet-source rebalances below the minimum fail closed before anything is dispatched on-chain.</td>
    </tr>
    <tr>
      <td>`treasury-3335`</td>
      <td>400</td>
      <td>Destination ledger '&#123;id&#125;' has no on-chain deposit address for &#123;currency&#125; on &#123;network&#125;. Provision one via POST /v1/accounts/&#123;id&#125;/onchain-addresses</td>
      <td>OpenFX→Circle rebalances ride an on-chain withdrawal to the destination ledger's deposit address. The corridor never creates addresses — provision via the onchain-addresses endpoint, then register the address as an OpenFX withdrawal address (manual provider step).</td>
    </tr>
    <tr>
      <td>`treasury-3336`</td>
      <td>400</td>
      <td>to_network is required for rebalances from an OpenFX ledger to a Circle ledger account</td>
      <td>OpenFX→Circle rebalances move funds on-chain, so the caller must pick the transit network via to_network. There is no default.</td>
    </tr>
    <tr>
      <td>`treasury-3337`</td>
      <td>400</td>
      <td>Deposit address for ledger '&#123;id&#125;' (&#123;currency&#125; on &#123;network&#125;) is not registered as an OpenFX withdrawal address</td>
      <td>The destination ledger's on-chain deposit address exists at Circle but has no matching verified OpenFX withdrawal address for the coin+network, so OpenFX would reject the withdrawal. Registration is a manual OpenFX dashboard step.</td>
    </tr>
    <tr>
      <td>`treasury-3338`</td>
      <td>409</td>
      <td>The on-chain transaction was rejected because its nonce was already used by another transaction from this wallet. This rebalance is now in a failed state. You must create a new rebalance in order to try again.</td>
      <td>Another transaction from the same wallet consumed this nonce before the signed transaction reached the network. The step is already failed and its signed transaction carries the spent nonce, so this rebalance cannot be retried — create a new rebalance, which is planned against a fresh nonce.</td>
    </tr>
    <tr>
      <td>`treasury-3339`</td>
      <td>500</td>
      <td>The signed transaction could not be broadcast</td>
      <td>The network rejected the signed transaction for a reason other than a nonce conflict; the node's reason is on the step's status_reasons. The remedy is the same for every resource, so this code is shared.</td>
    </tr>
    <tr>
      <td>`treasury-3340`</td>
      <td>409</td>
      <td>The on-chain transaction was rejected because its nonce was already used by another transaction from this wallet. This withdrawal is now in a failed state. You must create a new withdrawal in order to try again.</td>
      <td>Another transaction from the same wallet consumed this nonce before the signed transaction reached the network. The step is already failed and its signed transaction carries the spent nonce, so this withdrawal cannot be retried — create a new withdrawal, which is planned against a fresh nonce.</td>
    </tr>
    <tr>
      <td>`treasury-3341`</td>
      <td>409</td>
      <td>This rebalance waited for earlier transfers from the same wallet to be submitted, but the wait expired. This rebalance is now in a failed state. You must create a new rebalance in order to try again.</td>
      <td>The signed transaction's nonce was ahead of the wallet's submission watermark and the missing lower nonces were not submitted within the wait window. The step is already failed; a new rebalance is planned against a fresh nonce.</td>
    </tr>
    <tr>
      <td>`treasury-3342`</td>
      <td>409</td>
      <td>This withdrawal waited for earlier transfers from the same wallet to be submitted, but the wait expired. This withdrawal is now in a failed state. You must create a new withdrawal in order to try again.</td>
      <td>The signed transaction's nonce was ahead of the wallet's submission watermark and the missing lower nonces were not submitted within the wait window. The step is already failed; a new withdrawal is planned against a fresh nonce.</td>
    </tr>
    <tr>
      <td>`treasury-3343`</td>
      <td>400</td>
      <td>Same-account rebalances are only supported for on-ledger FX swaps</td>
      <td>A rebalance where source and destination are the same account is only valid as an on-ledger OpenFX FX swap</td>
    </tr>
  </tbody>
</table>

## Transfers

:::note
Transfers codes never appear as a top-level API error response — they only surface inside a step's
`status_reasons` array (see [Status Reasons](#status-reasons) above). The HTTP Status column is a
placeholder for consistency with the other domains and carries no meaning for these codes.
:::

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`transfers-9101`</td>
      <td>500</td>
      <td>Destination asset is missing for the transfer step</td>
      <td>A Circle-dispatched step could not resolve the destination asset for the transfer.</td>
    </tr>
    <tr>
      <td>`transfers-9102`</td>
      <td>500</td>
      <td>Destination account not found for the transfer step</td>
      <td>The destination account referenced by a dispatched step could not be found.</td>
    </tr>
    <tr>
      <td>`transfers-9103`</td>
      <td>500</td>
      <td>Required provider fields are missing for the transfer step</td>
      <td>An OpenFX-dispatched step was missing fields required to initiate the provider transfer or swap.</td>
    </tr>
    <tr>
      <td>`transfers-9104`</td>
      <td>500</td>
      <td>Source account not found for the transfer step</td>
      <td>The source account referenced by an OpenFX-dispatched step could not be found.</td>
    </tr>
    <tr>
      <td>`transfers-9105`</td>
      <td>500</td>
      <td>Source organization is missing for the transfer step</td>
      <td>An OpenFX-dispatched step could not resolve the source organization for the transfer.</td>
    </tr>
    <tr>
      <td>`transfers-9106`</td>
      <td>500</td>
      <td>Account not found for the transfer step</td>
      <td>An account referenced by an OpenFX-dispatched step could not be found.</td>
    </tr>
    <tr>
      <td>`transfers-9107`</td>
      <td>500</td>
      <td>Fiat currency mismatch for the transfer step</td>
      <td>The fiat currency of an OpenFX-dispatched step did not match the expected currency.</td>
    </tr>
    <tr>
      <td>`transfers-9108`</td>
      <td>500</td>
      <td>Provider data is missing for the staged transfer step</td>
      <td>A staged (customer-signed) step was missing the provider data required to build the unsigned transaction.</td>
    </tr>
    <tr>
      <td>`transfers-9109`</td>
      <td>500</td>
      <td>Source is missing for the staged transfer step</td>
      <td>A staged step was missing its source wallet or source address.</td>
    </tr>
    <tr>
      <td>`transfers-9110`</td>
      <td>500</td>
      <td>Currency is not supported for the transfer step</td>
      <td>The currency of the step is not supported by the resolved provider or execution path.</td>
    </tr>
    <tr>
      <td>`transfers-9111`</td>
      <td>500</td>
      <td>Network is not supported for the transfer step</td>
      <td>The network of the step is not supported by the resolved provider or execution path.</td>
    </tr>
    <tr>
      <td>`transfers-9112`</td>
      <td>500</td>
      <td>Destination could not be resolved for the transfer step</td>
      <td>The destination address for the step could not be resolved at execution time.</td>
    </tr>
    <tr>
      <td>`transfers-9113`</td>
      <td>500</td>
      <td>Planning failed for the transfer</td>
      <td>The planner hit a deterministic rejection while preparing the step graph; the domain error code and detail are appended.</td>
    </tr>
    <tr>
      <td>`transfers-9201`</td>
      <td>500</td>
      <td>An upstream step failed, so this step was not executed</td>
      <td>A prior step in the transfer failed and the failure cascaded to this downstream step.</td>
    </tr>
    <tr>
      <td>`transfers-9202`</td>
      <td>500</td>
      <td>The inbound transaction was reorganized away before finality</td>
      <td>A confirmed inbound step was dropped by a chain reorganization before reaching finality.</td>
    </tr>
    <tr>
      <td>`transfers-9203`</td>
      <td>500</td>
      <td>The transfer was rejected by risk screening</td>
      <td>Outbound risk screening rejected the payment (fail-closed); its non-terminal steps were failed.</td>
    </tr>
    <tr>
      <td>`transfers-9204`</td>
      <td>500</td>
      <td>The transfer expired before it could be executed</td>
      <td>The payment expired (e.g. quote/funding window elapsed) and its pre-broadcast steps were failed.</td>
    </tr>
    <tr>
      <td>`transfers-9205`</td>
      <td>500</td>
      <td>Insufficient funds to execute the transfer step</td>
      <td>The source did not hold enough balance to execute the on-chain send for the step.</td>
    </tr>
    <tr>
      <td>`transfers-9206`</td>
      <td>500</td>
      <td>The on-chain transaction for this inbound transfer was included in a block but reverted, so no funds arrived. The credit applied when it was detected has been taken back.</td>
      <td>Inbound funds are credited when the transfer is detected, before finality. A transfer that succeeded when reported can revert when re-executed after a reorg, since it runs against different preceding state. The credit is then reversed. If the recipient already spent it, the reversal recovers only what remains and the shortfall is reported for manual recovery.</td>
    </tr>
    <tr>
      <td>`transfers-9207`</td>
      <td>500</td>
      <td>The on-chain transaction for this inbound transfer succeeded but did not move the expected funds to the expected address. The credit applied when it was detected has been taken back.</td>
      <td>The transaction did not revert, but the token contract emitted no Transfer event matching the reported sender, recipient and amount. Distinct from a revert: execution succeeded, it simply did not deliver what was reported. Sustained for ten minutes before acting, because a node that is behind produces the same answer as a genuine absence.</td>
    </tr>
    <tr>
      <td>`transfers-9301`</td>
      <td>500</td>
      <td>The provider rejected the transfer step</td>
      <td>The provider returned a terminal rejection (e.g. a 4xx) when initiating the step.</td>
    </tr>
    <tr>
      <td>`transfers-9302`</td>
      <td>500</td>
      <td>The provider payout failed</td>
      <td>A provider payout/transfer webhook reported failure; the provider's raw code is appended when available.</td>
    </tr>
    <tr>
      <td>`transfers-9303`</td>
      <td>500</td>
      <td>The transfer step failed to execute</td>
      <td>A dispatched provider step failed to execute after exhausting its retry budget.</td>
    </tr>
    <tr>
      <td>`transfers-9304`</td>
      <td>500</td>
      <td>The currency conversion trade failed</td>
      <td>An OpenFX swap/trade leg failed; the provider's error detail is appended when available.</td>
    </tr>
    <tr>
      <td>`transfers-9305`</td>
      <td>500</td>
      <td>The on-chain transaction failed to broadcast</td>
      <td>Broadcasting the signed transaction to the network failed; the chain error is appended.</td>
    </tr>
    <tr>
      <td>`transfers-9306`</td>
      <td>500</td>
      <td>The Circle deposit failed</td>
      <td>A Circle Mint inbound deposit leg reported failure via webhook.</td>
    </tr>
    <tr>
      <td>`transfers-9307`</td>
      <td>500</td>
      <td>The simulated settlement send failed</td>
      <td>Staging-only: the simulated on-chain settlement send (airdrop) failed.</td>
    </tr>
    <tr>
      <td>`transfers-9308`</td>
      <td>500</td>
      <td>The simulated settlement transaction reverted</td>
      <td>Staging-only: the simulated on-chain settlement transaction reverted.</td>
    </tr>
    <tr>
      <td>`transfers-9309`</td>
      <td>500</td>
      <td>The withdrawal settlement failed at the provider</td>
      <td>An OpenFX withdrawal settlement webhook reported a failed/terminal status; the status is appended.</td>
    </tr>
    <tr>
      <td>`transfers-9310`</td>
      <td>500</td>
      <td>The on-chain transaction was rejected because its nonce was already used by another transaction from this wallet. This transfer is now in a failed state. You must create a new transfer in order to try again.</td>
      <td>Another transaction from the same wallet consumed this nonce before the signed transaction reached the network. The step is terminal and its signed transaction carries the spent nonce, so the transfer cannot be retried — a new one must be created.</td>
    </tr>
    <tr>
      <td>`transfers-9311`</td>
      <td>500</td>
      <td>This transfer waited for earlier transfers from the same wallet to be submitted, but the wait expired. This transfer is now in a failed state. You must create a new transfer in order to try again.</td>
      <td>The signed transaction's nonce was ahead of the wallet's submission watermark and the missing lower nonces were not submitted within the wait window. The step is terminal; a new transfer is planned against a fresh nonce.</td>
    </tr>
    <tr>
      <td>`transfers-9312`</td>
      <td>500</td>
      <td>An earlier transfer from this wallet failed before being submitted, so this transfer's position in the submission queue became invalid. This transfer is now in a failed state. You must create a new transfer in order to try again.</td>
      <td>A transfer holding a lower allocated nonce died before broadcast (wait timeout, expiry, risk rejection, or an on-chain nonce conflict), which invalidates every allocated nonce above it. The causing transfer's id is appended when known.</td>
    </tr>
    <tr>
      <td>`transfers-9313`</td>
      <td>500</td>
      <td>The on-chain transaction for this transfer was included in a block but reverted, so no funds moved. The reserved balance has been released. You must create a new transfer in order to try again.</td>
      <td>The transaction was mined and finalized, but its execution reverted — commonly insufficient token balance at execution time, or a token contract rejecting the transfer. Gas was still spent and is recorded as a fee on the step. The nonce was consumed, so later transfers from the same wallet are unaffected.</td>
    </tr>
    <tr>
      <td>`transfers-9314`</td>
      <td>500</td>
      <td>The on-chain transaction for this transfer succeeded but did not move the expected funds to the expected address. The reserved balance has been released. You must create a new transfer in order to try again.</td>
      <td>The transaction did not revert, but the token contract emitted no Transfer event matching the expected sender, recipient and amount. Distinct from a revert: execution succeeded, it simply did not deliver. Gas was spent and is recorded as a fee. The nonce was consumed.</td>
    </tr>
  </tbody>
</table>

## Vault

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`vault-0001`</td>
      <td>500</td>
      <td>Failed to store sensitive data in vault</td>
      <td>The vault provider failed to store the token. This may be due to a temporary outage or configuration issue.</td>
    </tr>
    <tr>
      <td>`vault-0002`</td>
      <td>500</td>
      <td>Vault provider did not return a token ID</td>
      <td>The vault provider accepted the data but did not return a token ID. This indicates an unexpected API response.</td>
    </tr>
    <tr>
      <td>`vault-0003`</td>
      <td>400</td>
      <td>Unknown vault field</td>
      <td>The specified field name is not configured for vault storage. Check the VaultFieldConfig for supported fields.</td>
    </tr>
    <tr>
      <td>`vault-0004`</td>
      <td>400</td>
      <td>Invalid field type for operation</td>
      <td>The operation does not match the field type. For example, trying to store text in a file-only field.</td>
    </tr>
    <tr>
      <td>`vault-0005`</td>
      <td>409</td>
      <td>Vault record already exists for this resource and field</td>
      <td>A create-only vault write found an existing record for the same (resourceId, fieldName). Rotate or delete the existing record instead.</td>
    </tr>
    <tr>
      <td>`vault-0010`</td>
      <td>404</td>
      <td>Vault token not found</td>
      <td>The specified token does not exist in the vault. It may have been deleted or never created.</td>
    </tr>
    <tr>
      <td>`vault-0011`</td>
      <td>500</td>
      <td>Failed to retrieve token from vault</td>
      <td>The vault provider failed to retrieve the token. This may be due to a temporary outage or authentication issue.</td>
    </tr>
    <tr>
      <td>`vault-0012`</td>
      <td>500</td>
      <td>Failed to reveal token value</td>
      <td>The vault provider failed to reveal the token value. The API key may not have sufficient permissions.</td>
    </tr>
    <tr>
      <td>`vault-0020`</td>
      <td>500</td>
      <td>Failed to delete token from vault</td>
      <td>The vault provider failed to delete the token. This may be due to a temporary outage or authentication issue.</td>
    </tr>
    <tr>
      <td>`vault-0030`</td>
      <td>502</td>
      <td>Vault proxy request failed</td>
      <td>The vault proxy failed to forward the request to the destination. Check the destination URL and authentication.</td>
    </tr>
    <tr>
      <td>`vault-0031`</td>
      <td>502</td>
      <td>Vault proxy destination returned an error</td>
      <td>The vault proxy successfully forwarded the request, but the destination returned an error response.</td>
    </tr>
    <tr>
      <td>`vault-0040`</td>
      <td>503</td>
      <td>Vault provider is not configured</td>
      <td>The vault provider API key is not configured. Contact support to enable vault functionality.</td>
    </tr>
    <tr>
      <td>`vault-0041`</td>
      <td>400</td>
      <td>Liquidation provider not found</td>
      <td>The specified liquidation provider is not configured. Check the available providers.</td>
    </tr>
    <tr>
      <td>`vault-0050`</td>
      <td>502</td>
      <td>Failed to forward vaulted data to provider</td>
      <td>The vaulted data could not be forwarded to the liquidation provider. This may be due to a provider outage or misconfiguration.</td>
    </tr>
    <tr>
      <td>`vault-0051`</td>
      <td>422</td>
      <td>Provider rejected the forwarded data</td>
      <td>The liquidation provider rejected the forwarded data. Check the data format and provider requirements.</td>
    </tr>
  </tbody>
</table>

## Circle

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`circle-1000`</td>
      <td>404</td>
      <td>Circle API key not configured for organization</td>
      <td>The organization does not have a Circle Mint API key configured in the vault</td>
    </tr>
    <tr>
      <td>`circle-2000`</td>
      <td>401</td>
      <td>Circle API key authentication failed</td>
      <td>The configured Circle Mint API key failed authentication with Circle API</td>
    </tr>
    <tr>
      <td>`circle-4290`</td>
      <td>429</td>
      <td>Cannot complete request because rate limited by provider Circle Mint</td>
      <td>The Circle Mint API returned a 429 rate limit response</td>
    </tr>
    <tr>
      <td>`circle-5000`</td>
      <td>502</td>
      <td>Circle Mint service error</td>
      <td>An error occurred while communicating with the Circle Mint API</td>
    </tr>
    <tr>
      <td>`circle-5001`</td>
      <td>503</td>
      <td>Circle Mint service temporarily unavailable</td>
      <td>The Circle Mint API is temporarily unavailable</td>
    </tr>
  </tbody>
</table>

## Idempotency

<table className="wrap-first-col error-table">
  <thead>
    <tr>
      <th>Error Code</th>
      <th>HTTP Status</th>
      <th>Error Message</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`idempotency-0001`</td>
      <td>409</td>
      <td>A request with this idempotency key is currently being processed. Please wait and retry.</td>
      <td>Another request with the same idempotency key is still in progress</td>
    </tr>
    <tr>
      <td>`idempotency-0002`</td>
      <td>400</td>
      <td>Keys for idempotent requests can only be used with the same parameters they were first used with.</td>
      <td>The idempotency key was previously used with a different request body. Use a different key for different requests.</td>
    </tr>
    <tr>
      <td>`idempotency-0003`</td>
      <td>503</td>
      <td>Idempotency cannot be guaranteed right now. The request was not processed. Please retry with the same key.</td>
      <td>The idempotency store is unreachable, so the request was rejected rather than executed without protection</td>
    </tr>
  </tbody>
</table>
