# Tesser Documentation > Complete documentation for Large Language Models --- ## Document: Treasury Updates Webhook events fired during the deposit and withdrawal lifecycle URL: /webhooks/treasury-updates # Treasury Updates Treasury webhook events are delivered inside the standard envelope described on the [General](./general) page. The `data.object` field contains a [Deposit](/api/~schemas#Deposit) or [Withdrawal](/api/~schemas#Withdrawal) resource. ## Deposit Events | Event | Fired when | | --- | --- | | `deposit.created` | Deposit record is created | | `deposit.submitted` | Deposit has been submitted for processing | | `deposit.confirmed` | Deposit is confirmed on-chain or by the partner | ## Withdrawal Events | Event | Fired when | | --- | --- | | `withdrawal.created` | Withdrawal record is created | | `withdrawal.submitted` | Withdrawal has been submitted for processing | | `withdrawal.confirmed` | Withdrawal is confirmed on-chain or by the partner | ## Step Events Once a deposit or withdrawal begins execution, individual step lifecycle events fire as each step progresses: | Event | Fired when | | --- | --- | | `step.submitted` | Step has been submitted for execution | | `step.confirmed` | Step execution is confirmed on-chain or by the partner | | `step.finalized` | Step has reached finality | | `step.completed` | Step finished successfully | | `step.failed` | Step encountered an error and could not complete | The `data.object` for step events is a [TransferStep](/api/~schemas#transfer-step) resource. ## Payload The `data.object` in each event contains the full resource. For the complete field reference, see the [Deposit schema](/api/~schemas#Deposit) and [Withdrawal schema](/api/~schemas#Withdrawal). --- ## Document: Payment Updates Webhook events fired during the payment lifecycle URL: /webhooks/payment-updates # Payment Updates Payment webhook events are delivered inside the standard envelope described on the [General](./general) page. The `data.object` field contains a [Payment](/api/~schemas#Payment) resource. ## Event Types | Event | Fired when | | --- | --- | | `payment.quote_created` | Exchange rate is locked and the quote is ready | | `payment.steps_created` | Route planning is complete and execution steps are created | | `payment.balance_updated` | Balance check result is available (reserved or awaiting funds) | | `payment.risk_updated` | Risk status has changed (e.g. `auto_approved`, `awaiting_decision`, or `auto_rejected`) | For a detailed breakdown of what each event means in the context of a payout, see [Payout Workflow](/how-tos/send-a-stablecoin-payout/payout-workflow). ## Step Events Once steps are created (`payment.steps_created`), individual step lifecycle events fire as each step progresses: | Event | Fired when | | --- | --- | | `step.submitted` | Step has been submitted for execution | | `step.confirmed` | Step execution is confirmed on-chain or by the partner | | `step.finalized` | Step has reached finality | | `step.completed` | Step finished successfully | | `step.failed` | Step encountered an error and could not complete | The `data.object` for step events is a [TransferStep](/api/~schemas#transfer-step) resource. ## Payload The `data.object` in each event contains the full payment resource, including its steps. For the complete field reference, see the [Payment schema](/api/~schemas#Payment). For a walkthrough of how these events appear during a real payout lifecycle, see [Create a Payout](/how-tos/send-a-stablecoin-payout/create-a-stablecoin-payout). ## Key Status Fields For details on how `risk_status` and `balance_status` evolve through a payout, see [Payout Workflow](/how-tos/send-a-stablecoin-payout/payout-workflow). --- ## Document: General Common envelope structure shared by all Tesser webhook events URL: /webhooks/general # General All Tesser webhook events share a common envelope structure. The envelope wraps event-specific data in a consistent format so your handler can route and process events uniformly. ## Envelope Fields | Field | Type | Description | | --- | --- | --- | | `id` | string | Unique event identifier | | `type` | string | Event type in `scope.action` format (e.g. `payment.quote_created`) | | `created_at` | string | ISO 8601 timestamp of when the event was created | | `data` | object | Contains the event-specific payload under `data.object` | ## Event Type Format Event types follow the pattern **`scope.action`**. Current scopes are `payment`, `deposit`, `withdrawal`, and `step`. See [Payment Updates](./payment-updates) and [Treasury Updates](./treasury-updates) for event details. ## Example Payload ```json { "id": "event_111", "type": "payment.quote_created", "created_at": "2025-12-01T09:00:00.045Z", "data": { "object": { "id": "550e8400-e29b-41d4-a716-446655440020", "workspace_id": "550e8400-e29b-41d4-a716-446655440001", "organization_reference_id": "ref_123", "direction": "outbound", "from_account_id": null, "funding_account_id": null, "to_account_id": null, "from_amount": "55.85", "from_currency": "USDC", "from_network": null, "to_amount": "1000", "to_currency": "MXN", "to_network": null, "risk_status": "unchecked", "risk_status_reasons": [], "risk_reviewed_by": null, "risk_reviewed_at": null, "balance_status": "unreserved", "balance_reserved_at": null, "steps": [], "created_at": "2025-12-01T09:00:00.000Z", "updated_at": "2025-12-01T09:00:00.040Z", "expires_at": "2025-12-01T23:59:59.999Z" } } } ``` --- ## Document: Webhook Authentication Verify that webhooks originate from Tesser using Ed25519 signatures URL: /webhooks/authentication # Webhook Authentication Tesser signs every outgoing webhook request with an **Ed25519** asymmetric signature. You should verify this signature on your server before processing the payload. ## Signature Header Each webhook request includes the following headers: | Header | Description | | --- | --- | | `X-Tesser-Signature` | Base64-encoded Ed25519 signature of the request body | | `Content-Type` | Always `application/json` | | `User-Agent` | `Tesser-Webhooks/1.0` | The signature is computed over the exact UTF-8 bytes of the JSON request body. Do not parse and re-serialize the body before verifying — use the raw bytes. ## Public Key Tesser's webhook public key is provided in **SPKI DER** format, base64-encoded. You can also import it from the SDK types package: ```ts import { WEBHOOK_PUBLIC_KEY } from "@tesser-payments/types"; ``` ## Verifying Signatures ```js import { createPublicKey, verify } from "node:crypto"; import { WEBHOOK_PUBLIC_KEY } from "@tesser-payments/types"; function verifyWebhook(rawBody, signature) { const publicKeyObj = createPublicKey({ key: Buffer.from(WEBHOOK_PUBLIC_KEY, "base64"), type: "spki", format: "der", }); return verify( null, Buffer.from(rawBody, "utf8"), publicKeyObj, Buffer.from(signature, "base64"), ); } // In your webhook handler: const signature = req.headers["x-tesser-signature"]; const isValid = verifyWebhook(req.rawBody, signature); if (!isValid) { return res.status(401).json({ error: "Invalid signature" }); } ``` ## Important Notes - Always verify using the **raw request body** bytes. Parsing the JSON and re-serializing may change whitespace or key order, which will invalidate the signature. - If verification fails, respond with `401` and do not process the event. - The public key may be rotated in the future. Key rotation will be announced in advance and communicated through the Tesser Dashboard. --- ## Document: Treasury Management Stablecoin balance and yield management URL: /overviews/treasury-management # Treasury Management Tesser provides comprehensive treasury management capabilities for stablecoins. > Note: Most treasury management features are currently under development. Contact us to learn more about our roadmap and early access programs. **Balance Management** Effective balance management ensures payments can be processed successfully: - **Balance checks:** Before payment processing, the system validates that the source treasury wallet has sufficient funds to cover the payment amount and associated network fees and processing costs - **Balance reconciliation:** Regular balance verification for wallets against blockchain state - **Balance Monitoring:** Low balance alerts when balances fall below thresholds or based on typical usage - **Automatic Rebalancing**: Rebalance across tokens and chains to maintain optimal distribution **Yield Generation** Generate yield on otherwise idle stablecoin balances: - **Multiple Providers**: Integrations with yield providers to offer a range of options - **Risk Spectrum**: From US treasury-backed yield (lower risk) to DeFi yield options (higher yield, higher risk) - **Policy Controls**: Enable yield only where allowed by your policy and risk appetite - **Operational Safety**: Emphasis on capital preservation and liquidity availability for payments **Treasury Analytics** Comprehensive reporting and analytics: - **Utilization Reports**: Track fund usage across corridors - **Yield Performance**: Monitor returns on treasury holdings - **Cash Flow Forecasting**: Predict funding needs based on historical patterns - **Cost Analysis**: Compare treasury costs across different strategies --- ## Document: Transfers Internal movement of funds URL: /overviews/transfers # Transfers A Transfer is a movement of funds on the Tesser platform among accounts that your organization or your customers own. There are no arms-length third parties involved in a transfer. Transfers involving two treasury/customer wallets are not routed through shield wallets. **Transfers occur during:** - **Rebalancing among treasury wallets:** To ensure sufficient funds in your organization’s wallet(s), you or Tesser with your authorization may redistribute funds among your treasury wallets. - **Funds flow through a shield wallet to/from a Treasury wallet:** When processing a payment, funds will move from a treasury wallet to a shield wallet prior to being distributed to a beneficiary (outbound payment) or from a shield wallet to a treasury wallet (inbound payment). --- ## Document: Supported Tokens and Networks Supported blockchain networks and stablecoins URL: /overviews/tokens-and-networks # Supported Tokens and Networks
| **Chain** | **Token** | **Availability** |
|---|---|---|
| POLYGON | USDC, USDT | Available |
| ETHEREUM | USDC, USDT | Coming soon |
| STELLAR | USDC | Coming soon |
| SOLANA | USDC, USDT | Coming soon |
| Resource | Description |
|---|---|
| Organization |
An organization represents Tesser’s customer, with whom Tesser has a contractual relationship. All other resources belong to an organization.{" "} |
| Workspace |
A workspace is a container for counterparties, accounts, payments, and deposits/withdrawals. Users and their roles, API keys, and webhooks are also established at the workspace level. Every organization is starts out with with one workspace in the Tesser platform. Additional workspaces can be created by contacting Tesser Customer Support. You may want an additional workspace to segregate activity by line of business, business unit, geography, etc. |
| Tenant |
A tenant represents an organization’s customer when that customer is itself a platform with its own users who need to be represented in Tesser’s systems. When an organization’s customers are tenants, originators and/or beneficiaries are customers of the tenant, and thus end-customers to the organization.{" "} {"*Note: Most organizations will not need to use tenants to manage their integrations with Tesser."} |
| Counterparty |
A counterparty represents an originator (ultimate sender) or beneficiary (ultimate receiver) of a payment. Counterparties can be individuals or businesses. Counterparties are associated to Accounts and belong to a Workspace. Registering counterparties in advance of submitting payments enables sanction screening and helps meet regulatory requirements. Counterparty information will be transmitted for fiat payouts and, as applicable,{" "} for stablecoin payouts and be included in payment instructions sent to fiat off-ramps to comply with Travel Rule obligations. |
| Account |
An account represents a store of value that holds fiat currency(ies) or stablecoin(s). Accounts can belong to a counterparty or to a workspace. Accounts may be external to the Tesser platform (e.g. pre-existing fiat bank accounts or wallets) or wallets provisioned by Tesser. |
| Quote |
A quote represents the cost to deliver a payment to a beneficiary. Quotes include the exchange rate between the source currency and the destination currency.{" "} Quotes can be based on a source amount and currency to be sent or a destination amount and currency to be delivered. |
| Payment |
A payment is the movement of funds from an account provisioned by Tesser to a third party, or vice versa. Most commonly, payments will move funds from an originator to a beneficiary. Payments may be outbound (aka payouts) or inbound (receiving stablecoins, aka pay-ins).{" "} Payments also include funds movement to/from a yield provider. |
| Deposit/Withdrawal |
Deposits and withdrawals are first-party movements of funds into or out of treasury wallets. Deposits can occur by on-ramping funds through a liquidity provider or via an on-chain transfer that you originate from a wallet your organization custodies that was not provisioned by Tesser. Withdrawals can occur by off-ramping funds through a liquidity provider or by creating a stablecoin payout to your organization as a beneficiary.{" "} |
| Transfer |
A transfer represents funds movement among Tesser-provisioned wallets for treasury management purposes. |
| **Originator is you or your customer/end-customer** | **Beneficiary is you or your customer/end-customer** | |
|---|---|---|
| **Outbound payment** | ✅ | ❌ |
| **Inbound payment** | ❌ | ✅ |
| Error Code | HTTP Status | Error Message | Description |
|---|---|---|---|
| `accounts-1000` | 404 | Account with id '{id}' not found | The specified account ID does not exist in this workspace |
| `accounts-1001` | 404 | Entity with id '{id}' not found | The tenant or counterparty specified does not exist |
| `accounts-2000` | 403 | The entity does not belong to your workspace | User tries to link an account to an entity that belongs to a different workspace |
| `accounts-3000` | 400 | Cannot provide both tenant_id and counterparty_id | User provides both tenant_id and counterparty_id when only one is allowed |
| `accounts-3001` | 400 | A workspace-level bank account already exists. Only one is allowed per workspace. | User tries to create a second workspace-level bank account |
| `accounts-3002` | 400 | wallet_address is required for unmanaged wallets (is_managed=false) | User creates an unmanaged wallet without providing a wallet_address |
| `accounts-3003` | 400 | Cannot determine network for wallet type '{type}' | The provided wallet type does not map to a known blockchain network |
| `accounts-3004` | 400 | signature is required for managed wallets (is_managed=true) | User creates a managed wallet without providing the required signature |
| `accounts-3005` | 400 | Invalid signature format. Expected base64-encoded JSON with body and stamp fields. | The signature parameter could not be decoded or is missing required fields |
| `accounts-3006` | 400 | Circle Mint ledgers require a tenant_id or counterparty_id. Workspace-level sub-ledgers are not supported. | User tries to create a Circle Mint ledger without linking it to a tenant or counterparty |
| `accounts-3007` | 400 | This entity already has a Circle Mint ledger. Only one Circle Mint ledger per tenant/counterparty is allowed. | User tries to create a duplicate Circle Mint ledger for the same entity |
| `accounts-3008` | 400 | A workspace-level Circle Mint master wallet ledger already exists. | User tries to create a second master wallet ledger for the workspace |
| `accounts-3009` | 400 | CIRCLE_MINT provider requires a tenant_id or counterparty_id | Circle Mint metadata preparation requires an entity to be linked |
| `accounts-3010` | 400 | CIRCLE_MINT provider requires a business entity (not individual) | Circle Mint only supports business-classified entities, not individuals |
| `accounts-3011` | 400 | Entity is missing required fields for Circle | The entity does not have all required business fields populated for Circle onboarding |
| `accounts-3012` | 400 | Cannot create VAN: compliance state is not ACCEPTED | Virtual account number creation requires the account to have ACCEPTED compliance state |
| `accounts-3013` | 400 | Cannot create VAN: circle_wallet_id is missing from account metadata | The ledger account does not have a Circle wallet ID configured |
| `accounts-3014` | 400 | No workspace-level bank account found. Please create a bank account first. | A workspace-level bank account is required but none exists |
| `accounts-3015` | 400 | No wire bank accounts found in Circle. Please register a bank account on Circle dashboard first. | Circle does not have any wire bank accounts registered for this workspace |
| `accounts-3016` | 400 | Multiple wire bank accounts found in Circle | Production requires exactly one bank account in Circle, but multiple were found |
| `accounts-3017` | 400 | Could not determine Circle bank ID | Failed to resolve the Circle bank ID needed for wire transfers |
| `accounts-3018` | 400 | Unsupported provider. Must be one of : CIRCLE_MINT, KRAKEN | The specified provider is not supported for this operation. Must be one of : CIRCLE_MINT, KRAKEN |
| `accounts-3019` | 400 | Account does not have a provider configured | The account metadata does not contain provider configuration |
| `accounts-3020` | 400 | Entity type must be 'counterparty' or 'tenant' | The referenced entity is not a valid type for account linking |
| `accounts-3100` | 400 | account_name is required and must be between 1-255 characters | User provides an account name that doesn't meet length requirements |
| `accounts-3101` | 400 | tenant_id must be a valid UUID | User provides a tenant_id that is not a valid UUID |
| `accounts-3102` | 400 | counterparty_id must be a valid UUID | User provides a counterparty_id that is not a valid UUID |
| `accounts-3103` | 400 | bank_name is required and must be between 1-255 characters | User provides a bank name that doesn't meet length requirements |
| `accounts-3104` | 400 | bank_code_type must be one of: SWIFT, BIC, IBAN, ROUTING | User provides a bank_code_type that is not in the allowed enum |
| `accounts-3105` | 400 | bank_identifier_code is required | User creates a bank account without providing the bank identifier code |
| `accounts-3106` | 400 | bank_account_number is required | User creates a bank account without providing the account number |
| `accounts-3107` | 400 | type must be one of: stablecoin_ethereum, stablecoin_solana, stablecoin_stellar | User provides a wallet type that is not in the allowed enum |
| `accounts-3108` | 400 | wallet_address must be a valid blockchain address for the specified network | User provides a wallet address that doesn't match the expected format for the network |
| `accounts-3109` | 400 | Wallet signature is malformed or invalid | User provides a signature that is not properly formatted or cannot be verified |
| `accounts-3110` | 400 | provider must be one of: CIRCLE_MINT, KRAKEN | User provides a provider value that is not in the allowed enum |
| `accounts-5000` | 502 | Failed to create wallet. Please try again or contact support if the issue persists. | Turnkey or other wallet provider failed during wallet creation |
| `accounts-5001` | 502 | Failed to create Circle external entity | Circle API call to create the external entity failed |
| `accounts-5002` | 502 | Unable to create virtual account number (VAN) for this ledger account. | Circle API call to create the virtual account number failed |
| `accounts-5003` | 502 | Failed to retrieve entity business fields from vault | Basis Theory vault call to retrieve entity fields failed |
| Error Code | HTTP Status | Error Message | Description |
|---|---|---|---|
| `counterparties-1000` | 404 | Counterparty not found | The specified counterparty ID does not exist |
| `counterparties-1001` | 404 | Tenant with id '{id}' not found. Cannot assign counterparty to non-existent tenant. | User tries to assign a counterparty to a tenant_id that doesn't exist |
| `counterparties-2000` | 403 | You do not have access to this counterparty | User tries to access a counterparty that belongs to a different workspace |
| `counterparties-3002` | 400 | classification must be 'individual' or 'business' | User provides a classification value that is not 'individual' or 'business' |
| `counterparties-3003` | 400 | business_legal_name is required for business counterparties and must be 1-255 characters | User creates a business counterparty with missing or improperly formatted business_legal_name |
| `counterparties-3004` | 400 | business_address_country is required for business counterparties and must be a valid ISO 3166-1 alpha-2 country code | User provides a business_address_country that is not a valid 2-letter country code (e.g., "US", "GB") |
| `counterparties-3005` | 400 | individual_first_name is required for individual counterparties and must be 1-255 characters | User creates an individual counterparty with missing or improperly formatted first name |
| `counterparties-3006` | 400 | individual_last_name is required for individual counterparties and must be 1-255 characters | User creates an individual counterparty with missing or improperly formatted last name |
| `counterparties-3007` | 400 | individual_address_country is required for individual counterparties and must be a valid ISO 3166-1 alpha-2 country code | User provides an individual_address_country that is not a valid 2-letter country code |
| `counterparties-3008` | 400 | individual_date_of_birth must be a valid date in YYYY-MM-DD format | User provides a date_of_birth that doesn't match the required format or is not a valid date |
| `counterparties-3009` | 400 | tenant_id must be a valid UUID | User provides a tenant_id that is not a validly formatted UUID |
| `counterparties-3010` | 400 | individual_street_address1 is required for individual counterparties | User creates an individual counterparty without providing the street address |
| `counterparties-3011` | 400 | individual_city is required for individual counterparties | User creates an individual counterparty without providing the city |
| `counterparties-3012` | 400 | individual_postal_code is required for individual counterparties | User creates an individual counterparty without providing the postal code |
| `counterparties-3013` | 400 | business_street_address1 is required for business counterparties | User creates a business counterparty without providing the street address |
| `counterparties-3014` | 400 | business_city is required for business counterparties | User creates a business counterparty without providing the city |
| `counterparties-3015` | 400 | business_postal_code is required for business counterparties | User creates a business counterparty without providing the postal code |
| Error Code | HTTP Status | Error Message | Description |
|---|---|---|---|
| `currencies-1000` | 404 | Currency not found | The specified currency code does not exist |
| `currencies-3000` | 400 | Invalid currency code format | User provides a currency code that is not a valid ISO 4217 format (e.g., USD, EUR, GBP) |
| `currencies-3001` | 400 | Currency is not supported for this operation | User attempts to use a currency that is valid but not supported for the requested operation |
| `currencies-3002` | 400 | Invalid currency pair for exchange | User attempts to exchange between currencies where the pair is not supported |
| Error Code | HTTP Status | Error Message | Description |
|---|---|---|---|
| `networks-1000` | 404 | Network not found | The specified network identifier does not exist |
| `networks-3000` | 400 | Invalid network identifier | User provides a network identifier that is not a valid format (e.g., ethereum, polygon, base) |
| `networks-3001` | 400 | Network is not supported for this operation | User attempts to use a network that is valid but not supported for the requested operation |
| `networks-3002` | 400 | Currency is not compatible with the specified network | User provides a currency/network combination that is not compatible (e.g., BTC on Ethereum network) |
| `networks-3003` | 400 | Network is currently unavailable or under maintenance | User attempts to use a network that is temporarily unavailable |
| `networks-5000` | 502 | Failed to connect to network RPC endpoint | Connection to the blockchain network RPC endpoint failed due to external service error |
| Error Code | HTTP Status | Error Message | Description |
|---|---|---|---|
| `payments-1000` | 404 | Payment not found | The specified payment ID does not exist |
| `payments-3000` | 400 | from_network must equal to_network | User provides different networks for from_network and to_network |
| `payments-3001` | 400 | invalid from_amount or to_amount | from_amount and to_amount should be positive and be valid numbers |
| `payments-3002` | 400 | Either from_amount or to_amount must be provided. Cannot create payment without an amount. | User does not provide either from_amount or to_amount |
| `payments-3003` | 400 | Only one of from_amount or to_amount should be provided. The other will be calculated using the exchange rate. | User provides both from_amount and to_amount when only one should be provided |
| `payments-3004` | 400 | from_network is required for crypto-to-crypto payments | User creates a payment with stablecoin from_currency but does not provide from_network |
| `payments-3005` | 400 | to_network is required for crypto-to-crypto payments | User creates a payment with stablecoin to_currency but does not provide to_network |
| `payments-3006` | 400 | Onramp (fiat-to-crypto) payments are not yet supported. Coming soon! | User attempts to create an onramp payment which is not supported yet |
| `payments-3007` | 400 | Invalid from_currency | User provides a from_currency that is not supported |
| `payments-3008` | 400 | Invalid to_currency | User provides a to_currency that is not supported |
| `payments-3009` | 400 | funding_account_id not found | User provides a funding_account_id that does not exist |
| `payments-3010` | 400 | to_account_id not found | User provides a to_account_id that does not exist |
| `payments-3011` | 400 | from_account_id not found | User provides a from_account_id that does not exist |
| `payments-3012` | 400 | Missing input parameter is_approved | User submits a payment review without the required is_approved parameter |
| `payments-3013` | 400 | signature is malformed or signed with incorrect key | User provides a signature that is malformed or not signed with the correct key |
| `payments-3014` | 400 | The signed transaction does not match the details of the payment | User provides a signature that does not match the payment details |
| `payments-3015` | 400 | The exchange rate quote has expired. Please create a new payment to get a fresh quote. | User attempts to execute a payment with an expired exchange rate quote (valid for 24 hours) |
| `payments-3016` | 400 | Payment quote expiration data is missing. Please create a new payment to get a fresh quote. | Payment has an exchange rate but is missing expiration data, indicating a data integrity issue |
| `payments-3017` | 400 | to_account has not yet been risk approved by custodian | Beneficiary account has a Circle recipient that is still pending verification or has not been registered yet |
| `payments-3018` | 400 | from_account_id and to_account_id should not both be managed accounts for payments. Use /v1/treasury/rebalances instead. | Transfers between two managed accounts are treasury operations. Use /v1/treasury/rebalances instead. |
| Error Code | HTTP Status | Error Message | Description |
|---|---|---|---|
| `tenants-1000` | 404 | Tenant not found | The specified tenant ID does not exist |
| `tenants-2000` | 403 | You do not have access to this tenant | User tries to access a tenant that belongs to a different workspace |
| `tenants-3000` | 400 | business_legal_name is required to create a tenant | User creates a tenant without providing the required business_legal_name field |
| `tenants-3001` | 400 | business_legal_name is required and must be 1-255 characters | User provides a business_legal_name that doesn't meet length requirements |
| `tenants-3002` | 400 | business_address_country must be a valid ISO 3166-1 alpha-2 country code | User provides a business_address_country that is not a valid 2-letter country code |
| `tenants-3003` | 400 | webhook_url must be a valid HTTPS URL | User provides a webhook_url that is not a properly formatted HTTPS URL |
| Error Code | HTTP Status | Error Message | Description |
|---|---|---|---|
| `treasury-1000` | 404 | Rebalance with id '{id}' not found | The specified rebalance ID does not exist |
| `treasury-1001` | 404 | Transfer step not found for rebalance with id '{id}' | The transfer step associated with the rebalance could not be found |
| `treasury-1002` | 404 | Account with id '{id}' not found | The specified account ID does not exist or does not belong to this workspace |
| `treasury-1100` | 404 | Deposit with id '{id}' not found | The specified deposit ID does not exist in this workspace |
| `treasury-1101` | 404 | Account with id '{id}' not found | The specified account ID does not exist or does not belong to this workspace |
| `treasury-1102` | 404 | Source account with id '{id}' not found | The source bank account for this deposit could not be found |
| `treasury-1103` | 404 | VAN account with id '{id}' not found | The virtual account number (VAN) account could not be found |
| `treasury-3000` | 400 | Only Circle Mint ledger-to-ledger rebalancing is currently supported | Rebalancing is only available between Circle Mint ledger accounts |
| `treasury-3001` | 400 | Network must not be specified for ledger accounts | Ledger-to-ledger rebalances operate without a blockchain network |
| `treasury-3002` | 400 | At least one of from_amount or to_amount must be provided | A rebalance requires at least one amount to determine the transfer size |
| `treasury-3003` | 400 | Invalid currency pair for rebalance | The specified from_currency and to_currency combination is not supported for Circle rebalancing |
| `treasury-3004` | 400 | from_amount and to_amount must be equal when currencies are the same | When both amounts are provided for same-currency rebalances, they must match |
| `treasury-3005` | 400 | Source or destination account is missing Circle wallet ID | The account does not have a Circle wallet ID configured, which is required for ledger transfers |
| `treasury-3006` | 400 | Transfer step is missing account asset IDs | The transfer step does not have the required from/to account asset references |
| `treasury-3100` | 400 | Account '{id}' is not a ledger account | Deposits can only be made to ledger accounts |
| `treasury-3101` | 400 | Account '{id}' is not configured for deposits. No supported provider found | The destination account does not have a supported deposit provider configured |
| `treasury-3102` | 400 | Ledger '{id}' is missing Circle Mint metadata | The ledger account does not have the required Circle Mint configuration |
| `treasury-3103` | 400 | Circle compliance not yet accepted for ledger. Cannot create deposit | Circle compliance must be accepted before deposits can be created |
| `treasury-3104` | 400 | Source account '{id}' does not match the configured source bank for this ledger | The provided source account does not match the bank account configured for this ledger |
| `treasury-3105` | 400 | Source bank account '{id}' not found or is not a fiat bank account | The source bank account could not be found or is not the correct account type |
| `treasury-3106` | 400 | Ledger account '{id}' does not have a '{currency}' asset | The destination ledger account does not hold the requested currency |
| `treasury-3107` | 400 | Invalid currency combination for Circle deposit: {fromCurrency} → {toCurrency} | The specified from_currency and to_currency combination is not supported for Circle deposits |
| `treasury-3108` | 400 | Deposit '{id}' is already finalized. Wire instructions are no longer available | The deposit has already been finalized and instructions cannot be retrieved |
| `treasury-3109` | 400 | Deposit '{id}' has no transfer step | The deposit does not have the expected transfer step |
| `treasury-3110` | 400 | Deposit '{id}' transfer step has no source account | The deposit transfer step is missing its source account reference |
| `treasury-3111` | 400 | Deposit '{id}' transfer step has no destination account | The deposit transfer step is missing its destination account reference |
| `treasury-3112` | 400 | Source account '{id}' is missing required bank details | The source account does not have all required bank details (bank name, code type, identifier code, or account number) |
| `treasury-3113` | 400 | VAN account '{id}' missing virtual_account_number metadata | The VAN account does not have the required virtual account number metadata |
| `treasury-3114` | 400 | VAN account '{id}' is missing required field: {field} | The VAN account is missing a required field for wire instructions (e.g., bank name, account number, SWIFT code, beneficiary name) |
| `treasury-3115` | 400 | Simulated deposits are not available in production | Deposit simulation is only available in sandbox environments |
| Error Code | HTTP Status | Error Message | Description |
|---|---|---|---|
| `vault-0001` | 500 | Failed to store sensitive data in vault | The vault provider failed to store the token. This may be due to a temporary outage or configuration issue. |
| `vault-0002` | 500 | Vault provider did not return a token ID | The vault provider accepted the data but did not return a token ID. This indicates an unexpected API response. |
| `vault-0003` | 400 | Unknown vault field | The specified field name is not configured for vault storage. Check the VaultFieldConfig for supported fields. |
| `vault-0004` | 400 | Invalid field type for operation | The operation does not match the field type. For example, trying to store text in a file-only field. |
| `vault-0010` | 404 | Vault token not found | The specified token does not exist in the vault. It may have been deleted or never created. |
| `vault-0011` | 500 | Failed to retrieve token from vault | The vault provider failed to retrieve the token. This may be due to a temporary outage or authentication issue. |
| `vault-0012` | 500 | Failed to reveal token value | The vault provider failed to reveal the token value. The API key may not have sufficient permissions. |
| `vault-0020` | 500 | Failed to delete token from vault | The vault provider failed to delete the token. This may be due to a temporary outage or authentication issue. |
| `vault-0030` | 502 | Vault proxy request failed | The vault proxy failed to forward the request to the destination. Check the destination URL and authentication. |
| `vault-0031` | 502 | Vault proxy destination returned an error | The vault proxy successfully forwarded the request, but the destination returned an error response. |
| `vault-0040` | 503 | Vault provider is not configured | The vault provider API key is not configured. Contact support to enable vault functionality. |
| `vault-0041` | 400 | Liquidation provider not found | The specified liquidation provider is not configured. Check the available providers. |
| `vault-0050` | 502 | Failed to forward vaulted data to provider | The vaulted data could not be forwarded to the liquidation provider. This may be due to a provider outage or misconfiguration. |
| `vault-0051` | 422 | Provider rejected the forwarded data | The liquidation provider rejected the forwarded data. Check the data format and provider requirements. |
| Error Code | HTTP Status | Error Message | Description |
|---|---|---|---|
| `circle-1000` | 404 | Circle API key not configured for organization | The organization does not have a Circle Mint API key configured in the vault |
| `circle-2000` | 401 | Circle API key authentication failed | The configured Circle Mint API key failed authentication with Circle API |
| `circle-4290` | 429 | Cannot complete request because rate limited by provider Circle Mint | The Circle Mint API returned a 429 rate limit response |
| `circle-5000` | 502 | Circle Mint service error | An error occurred while communicating with the Circle Mint API |
| `circle-5001` | 503 | Circle Mint service temporarily unavailable | The Circle Mint API is temporarily unavailable |
| Error Code | HTTP Status | Error Message | Description |
|---|---|---|---|
| `idempotency-0001` | 409 | A request with this idempotency key is currently being processed. Please wait and retry. | Another request with the same idempotency key is still in progress |
| `idempotency-0002` | 400 | Keys for idempotent requests can only be used with the same parameters they were first used with. | The idempotency key was previously used with a different request body. Use a different key for different requests. |
| *Belongs to:* | **Type: Bank account** | **Type: Wallet** | **Type: Ledger** |
|---|---|---|---|
| **Workspace** | n/a |
An omnibus wallet an organization uses to manage its treasury operations in an aggregated manner. (Managed) |
An omnibus wallet an organization uses to manage its treasury operations in an aggregated manner. (Managed) |
| **Tenant** | n/a |
A wallet designated for funds belonging to a tenant. (Managed) |
A wallet designated for funds belonging to a tenant. (Managed) |
| **Counterparty** |
A bank account that belongs to an originator or a beneficiary. (Unmanaged) For fiat payouts, bank account info as transmitted as part of Travel Rule compliance.
|
A wallet designated for an originator or beneficiary provisioned by Tesser. (Managed) A wallet provisioned for the originator or beneficiary by a non-Tesser provider. (Unmanaged) |
A wallet designated for an originator or beneficiary. (Managed) |
| **Status** | **Terminal** | **Webhook event type** | **Description** |
|---|---|---|---|
| `unchecked` | No |
Not sent. All payments at creation have a risk status of `unchecked` |
Beneficiary wallet identifier has not been supplied or risk check has not yet completed. |
| `awaiting_decision` | No | Risk.updated | Beneficiary wallet has been risk screened and requires manual review to determine whether to send the payout. |
| `auto_approved` | Yes | Risk.updated | Beneficiary wallet has been risk screened and automatically approved per your organization's policy. |
| `manually_approved` | Yes | Risk.updated | Beneficiary wallet has been risk screened and has been manually reviewed and approved. |
| `auto_rejected` | Yes | Risk.updated | Beneficiary wallet has been risk screened and automatically rejected per your organization's policy. |
| `manually_rejected` | Yes | Risk.updated | Beneficiary wallet has been risk screened and has been manually reviewed and rejected. |
| **Status** | **Terminal** | **Webhook event type** | **Description** |
|---|---|---|---|
| `unreserved` | No |
Not sent. All payments at creation have a balance status of `unreserved` |
Source wallet id has not been supplied or the reserve operation has not yet completed. |
| `awaiting_funds` | No | Balance.updated | The balance of the source wallet was checked and there are insufficient funds to process the payout. The payment is queued and awaiting funds from a deposit. |
| `reserved` | Yes | Balance.updated | The balance of the source wallet was checked and funds were reserved to process the payout. |
| **Status** | **Terminal** | **Webhook event type** | **Description** |
|---|---|---|---|
| `created` | No |
Not sent. All steps at creation have a status of `created` |
Tesser has created a record for this step. |
| `submitted` | No | step.updated | Tesser submitted the step information to the blockchain or fiat payment network |
| `confirmed` | No | step.updated | The step was accepted by the operator of the payment network |
| `finalized` | No | step.updated | For crypto transfer steps, the block containing the transfer step has been finalized. The transfer step is now permanent and irreversible. How long it takes to finalize a transfer depends on the blockchain. |
| `completed` | No | step.updated |
For fiat transfer steps, indicates the local payment network has delivered funds to the beneficiary. *Note, some fiat payment networks may not provide formal confirmation of funds delivery, in which case funds are assumed to be delivered unless a `failed` status is indicated |
| `failed` | Yes | step.updated | The transfer step was not successful; funds were not transferred from the `from_account` to the `to_account` |