{ "openapi": "3.1.0", "info": { "title": "Deposit Service API", "version": "1.0.0", "description": "Rhinestone Deposits API: accept deposits from any chain, asset or payment method, and settle them as one token on one chain." }, "servers": [ { "url": "https://v1.orchestrator.rhinestone.dev/deposit-processor" } ], "components": { "securitySchemes": { "complianceSessionBearer": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "Required 15-minute customer-scoped browser session from POST /compliance/sessions. Application keys are not accepted." }, "tenantApiKey": { "type": "apiKey", "in": "header", "name": "x-api-key", "description": "Integrator API key for tenant API requests." }, "internalProjectBearer": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "Project-scoped platform bearer for tenant API requests. This API does not issue platform tokens." }, "analyticsIngestBearer": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "Optional five-minute analytics ingest token. Omit it to store an unattributed session." } }, "schemas": { "AnalyticsEventsResponse": { "type": "object", "properties": { "accepted": { "type": "integer", "minimum": 1, "maximum": 50 } }, "required": [ "accepted" ] }, "ErrorResponse": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "description": "Machine-readable refusal code: a deposit error code (e.g. `TOKEN-3`) when the refusal is one a deposit would also receive, or a route-specific code (e.g. `WEBHOOK_ENROLLMENT_UNAVAILABLE`, `REGISTRATION_BUSY`, `REGISTRATION_IN_PROGRESS`, `USER_OWNED_ACCOUNTS_NOT_ENABLED`, `QUOTE_UNAVAILABLE`)." }, "details": { "type": "array", "items": { "type": "object", "properties": { "message": { "type": "string" }, "path": { "type": "array", "items": { "anyOf": [ { "type": "string" }, { "type": "number" } ] } }, "code": { "type": "string" } }, "required": [ "message" ] } } }, "required": [ "error" ] }, "AnalyticsConflictResponse": { "type": "object", "properties": { "error": { "type": "string", "enum": [ "Analytics event conflict" ] }, "code": { "type": "string", "enum": [ "SESSION_ATTRIBUTION_CONFLICT", "SESSION_ENVELOPE_CONFLICT", "EVENT_ID_CONFLICT", "SESSION_SEQUENCE_CONFLICT" ] } }, "required": [ "error", "code" ] }, "AnalyticsEventsRequest": { "type": "object", "properties": { "events": { "type": "array", "items": { "$ref": "#/components/schemas/AnalyticsEvent" }, "minItems": 1, "maxItems": 50 } }, "required": [ "events" ], "additionalProperties": false }, "AnalyticsEvent": { "oneOf": [ { "type": "object", "properties": { "event_id": { "type": "string", "format": "uuid" }, "session_id": { "type": "string", "format": "uuid" }, "sequence": { "type": "integer", "minimum": 0, "maximum": 2147483647 }, "type": { "type": "string", "minLength": 1, "maxLength": 128 }, "timestamp": { "type": "string", "format": "date-time" }, "widget_version": { "type": "string", "minLength": 1, "maxLength": 64 }, "proxy_origin": { "type": "string", "maxLength": 2048, "description": "Canonical HTTP(S) origin only (for example https://app.example.com), without credentials, path, query, fragment, or trailing slash.", "example": "https://app.example.com" }, "payload": { "type": "object", "additionalProperties": true, "description": "JSON object limited to 16 KiB serialized, 10 recursive levels, and 4096 characters per key or string value." }, "modal": { "type": "string", "enum": [ "deposit" ] }, "session_properties": { "type": "object", "properties": { "enabled_funding_methods": { "type": "array", "items": { "type": "string", "enum": [ "wallet", "transfer", "fiat_onramp", "exchange_connect", "asset_migration" ] }, "maxItems": 5 }, "wallet_integration": { "type": "string", "enum": [ "modal_connected", "host_supplied", "none" ] }, "fiat_methods": { "oneOf": [ { "type": "object", "properties": { "source": { "type": "string", "enum": [ "backend_resolved" ] } }, "required": [ "source" ], "additionalProperties": false }, { "type": "object", "properties": { "source": { "type": "string", "enum": [ "configured" ] }, "identifiers": { "type": "array", "items": { "type": "string", "maxLength": 4096 } } }, "required": [ "source", "identifiers" ], "additionalProperties": false } ] }, "asset_migration_providers": { "type": "array", "items": { "type": "string", "maxLength": 4096 } }, "initial_asset_migration": { "type": [ "string", "null" ], "maxLength": 4096 }, "gasless_wallet_flow_enabled": { "type": "boolean" }, "presentation": { "type": "string", "enum": [ "inline", "overlay" ] }, "overlay_close_enabled": { "type": "boolean" }, "target_chain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "target_token": { "type": "string", "maxLength": 64, "description": "On-chain token identity for the session target: an EVM or HyperEVM ERC-20 address, a HyperCore spot token id, a Solana mint, a Tron TRC-20 address, a Stellar Asset Contract, or a native-asset sentinel. Hex values are stored lower-cased; base58 and base32 are byte-exact.", "example": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" }, "prefills": { "type": "object", "properties": { "source_chain": { "type": "boolean" }, "source_token": { "type": "boolean" }, "amount": { "type": "boolean" }, "initial_asset_migration": { "type": "boolean" } }, "required": [ "source_chain", "source_token", "amount", "initial_asset_migration" ], "additionalProperties": false } }, "required": [ "enabled_funding_methods", "wallet_integration", "fiat_methods", "asset_migration_providers", "initial_asset_migration", "gasless_wallet_flow_enabled", "presentation", "overlay_close_enabled", "prefills" ], "additionalProperties": false }, "funding_method": { "type": [ "string", "null" ], "enum": [ "wallet", "transfer", "fiat_onramp", "exchange_connect", "asset_migration", null ] } }, "required": [ "event_id", "session_id", "sequence", "type", "timestamp", "widget_version", "proxy_origin", "payload", "modal", "session_properties", "funding_method" ], "additionalProperties": false }, { "type": "object", "properties": { "event_id": { "type": "string", "format": "uuid" }, "session_id": { "type": "string", "format": "uuid" }, "sequence": { "type": "integer", "minimum": 0, "maximum": 2147483647 }, "type": { "type": "string", "minLength": 1, "maxLength": 128 }, "timestamp": { "type": "string", "format": "date-time" }, "widget_version": { "type": "string", "minLength": 1, "maxLength": 64 }, "proxy_origin": { "type": "string", "maxLength": 2048, "description": "Canonical HTTP(S) origin only (for example https://app.example.com), without credentials, path, query, fragment, or trailing slash.", "example": "https://app.example.com" }, "payload": { "type": "object", "additionalProperties": true, "description": "JSON object limited to 16 KiB serialized, 10 recursive levels, and 4096 characters per key or string value." }, "modal": { "type": "string", "enum": [ "withdraw" ] }, "session_properties": { "type": "object", "properties": { "presentation": { "type": "string", "enum": [ "inline", "overlay" ] }, "overlay_close_enabled": { "type": "boolean" }, "target_chain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "target_token": { "type": "string", "maxLength": 64, "description": "On-chain token identity for the session target: an EVM or HyperEVM ERC-20 address, a HyperCore spot token id, a Solana mint, a Tron TRC-20 address, a Stellar Asset Contract, or a native-asset sentinel. Hex values are stored lower-cased; base58 and base32 are byte-exact.", "example": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" }, "prefills": { "type": "object", "properties": { "target_chain": { "type": "boolean" }, "target_token": { "type": "boolean" }, "recipient": { "type": "boolean" }, "amount": { "type": "boolean" } }, "required": [ "target_chain", "target_token", "recipient", "amount" ], "additionalProperties": false } }, "required": [ "presentation", "overlay_close_enabled", "prefills" ], "additionalProperties": false } }, "required": [ "event_id", "session_id", "sequence", "type", "timestamp", "widget_version", "proxy_origin", "payload", "modal", "session_properties" ], "additionalProperties": false }, { "type": "object", "properties": { "event_id": { "type": "string", "format": "uuid" }, "session_id": { "type": "string", "format": "uuid" }, "sequence": { "type": "integer", "minimum": 0, "maximum": 2147483647 }, "type": { "type": "string", "minLength": 1, "maxLength": 128 }, "timestamp": { "type": "string", "format": "date-time" }, "widget_version": { "type": "string", "minLength": 1, "maxLength": 64 }, "proxy_origin": { "type": "string", "maxLength": 2048, "description": "Canonical HTTP(S) origin only (for example https://app.example.com), without credentials, path, query, fragment, or trailing slash.", "example": "https://app.example.com" }, "payload": { "type": "object", "additionalProperties": true, "description": "JSON object limited to 16 KiB serialized, 10 recursive levels, and 4096 characters per key or string value." }, "modal": { "type": "string", "enum": [ "claim" ] }, "session_properties": { "type": "object", "properties": { "presentation": { "type": "string", "enum": [ "inline", "overlay" ] }, "overlay_close_enabled": { "type": "boolean" }, "prefills": { "type": "object", "properties": { "transaction_hash": { "type": "boolean" }, "refund_destination": { "type": "boolean" } }, "required": [ "transaction_hash", "refund_destination" ], "additionalProperties": false } }, "required": [ "presentation", "overlay_close_enabled", "prefills" ], "additionalProperties": false } }, "required": [ "event_id", "session_id", "sequence", "type", "timestamp", "widget_version", "proxy_origin", "payload", "modal", "session_properties" ], "additionalProperties": false } ] }, "AnalyticsIngestTokenResponse": { "type": "object", "properties": { "token": { "type": "string", "description": "Purpose-limited JWT authorizing analytics event ingest for five minutes", "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }, "expiresAt": { "type": "string", "format": "date-time", "description": "UTC expiry matching the JWT exp claim", "example": "2026-08-25T14:35:00.000Z" } }, "required": [ "token", "expiresAt" ] }, "AssetsResponse": { "type": "object", "properties": { "data": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/AssetItem" } } }, "required": [ "data" ] }, "AssetItem": { "type": "object", "properties": { "name": { "type": [ "string", "null" ] }, "symbol": { "type": [ "string", "null" ] }, "decimals": { "type": [ "number", "null" ] }, "logo": { "type": [ "string", "null" ] }, "price": { "type": [ "object", "null" ], "properties": { "usd": { "type": "string" }, "updatedAt": { "type": "string" } }, "required": [ "usd", "updatedAt" ] }, "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_id", "unsupported_chain", "not_found", "upstream_error" ] }, "message": { "type": "string" } }, "required": [ "code", "message" ] } }, "additionalProperties": {} }, "AssetsError": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } }, "required": [ "code", "message" ] } }, "required": [ "error" ] }, "AssetsAuthError": { "type": "object", "properties": { "error": { "type": "string" } }, "required": [ "error" ] }, "ChainsResponse": { "type": "object", "additionalProperties": { "type": "object", "properties": { "name": { "type": "string" }, "testnet": { "type": "boolean" }, "deposit": { "type": "boolean" }, "destination": { "type": "boolean" }, "refund": { "type": "boolean", "description": "Whether a failed deposit on this chain can be refunded via POST /deposits/{id}/refund. Chain-level only: a chain that advertises true still declines individual deposits for reasons belonging to the deposit or the account rather than the chain — a HyperCore deposit already credited to HyperEVM, a Solana Token-2022 mint or one with unsupported decimals, or a user-owned account with no session on the source chain. Not the same as POST /deposits/recover, the signature-authorized self-service path, which is EVM-only on both source and target chain.", "example": true }, "vmType": { "type": "string", "enum": [ "evm", "svm", "tvm", "stellar" ], "description": "Address format the chain uses: 'evm' is 20-byte hex, 'svm' base58, 'tvm' base58check, 'stellar' base32 strkey. Validate an address against this rather than inferring from the chain id. HyperCore is 'evm' — it is EVM-addressed without being an EVM execution chain. On 'stellar' the format alone is not enough to tell a recipient from a token: an account is a 'G' strkey and an asset its 'C' Soroban contract, distinguished by the version byte the two encode.", "example": "evm" }, "nativeToken": { "type": "object", "properties": { "symbol": { "type": "string" }, "address": { "type": "string" }, "decimals": { "type": "number" } }, "required": [ "symbol", "address", "decimals" ], "description": "The chain's gas asset, for rendering a native-value transfer that carries no token address." }, "explorer": { "type": [ "object", "null" ], "properties": { "url": { "type": "string" }, "addressPath": { "type": "string" }, "txPath": { "type": "string" }, "query": { "type": "string", "description": "URL query content without a leading question mark; preserve spelling and percent-encoded bytes without normalization.", "example": "cluster=devnet" } }, "required": [ "url", "addressPath", "txPath" ], "description": "Block explorer, or null (render plain text). `url` has no trailing slash; paths include their own. Compose links as `url + addressPath + value` or `url + txPath + value`, appending `?` + query only when present. Preserve path spelling and linked-value case. Fragment routes carry no query: Tronscan uses `/#/address/` and `/#/transaction/`.", "example": { "url": "https://etherscan.io", "addressPath": "/address/", "txPath": "/tx/" } }, "supportedTokens": { "anyOf": [ { "type": "string", "enum": [ "all" ] }, { "type": "array", "items": { "type": "object", "properties": { "symbol": { "type": "string" }, "address": { "type": "string" }, "decimals": { "type": "number" } }, "required": [ "symbol", "address", "decimals" ] } } ], "description": "What can be DELIVERED to this chain — the identity a `target.token` must use. Meaningful only when `destination` is true. `\"all\"` means any token on the chain." }, "depositTokens": { "anyOf": [ { "type": "string", "enum": [ "all" ] }, { "type": "array", "items": { "type": "object", "properties": { "symbol": { "type": "string" }, "address": { "type": "string" }, "decimals": { "type": "number" } }, "required": [ "symbol", "address", "decimals" ] } } ], "description": "What can be DEPOSITED from this chain — the identity a deposit whitelist is matched on, and the units its `minAmount`/`maxAmount` are in. Meaningful only when `deposit` is true; `\"all\"` means any token on the chain. Equal to `supportedTokens` everywhere except HyperCore, where a deposit is identified by its Core spot token id at `weiDecimals` and a delivery by the token's HyperEVM ERC20 at 6 — configure a whitelist from THIS field, never from `supportedTokens`." }, "publicRpcUrl": { "type": "string", "description": "The chain's PUBLIC, unauthenticated JSON-RPC endpoint. Build a viem `Chain` with `defineChain` from it — a browser client can derive every other argument from this entry but not this one, which is what makes a chain it was never compiled against usable. Deliberately not the rpc-proxy URL: this is served to a browser holding no credential. Absent for a chain that publishes none — treat that chain as display-only rather than as an error.", "example": "https://mainnet.base.org" }, "iconUrl": { "type": "string", "description": "The chain's mark, for rendering a chain the client was never compiled against and therefore holds no bundled asset for. Absent for a chain that publishes no icon — render a text or colour fallback, never an error. Served from Rhinestone's public CDN, so a host with an explicit `img-src` CSP must include `https://s3.rhinestone.dev` in it: without that the image fails SILENTLY, with no console error naming the policy.", "example": "https://s3.rhinestone.dev/chains/base.svg" } }, "required": [ "name", "testnet", "deposit", "destination", "refund", "vmType", "nativeToken", "explorer", "supportedTokens", "depositTokens" ] } }, "CheckResponse": { "type": "object", "properties": { "isRegistered": { "type": "boolean", "description": "Whether the EVM account is registered. EVM-scoped (legacy): a Solana/Tron-only account reads `false` here. Use `sources` for per-chain registration across all namespaces." }, "targetChain": { "type": "string" }, "targetToken": { "type": "string" }, "recipient": { "type": "string" }, "sourceChains": { "type": "array", "items": { "type": "string" } }, "outputTokenRules": { "type": "array", "items": { "$ref": "#/components/schemas/OutputTokenRule" } }, "rejectUnmapped": { "type": "boolean" }, "sources": { "type": "array", "items": { "type": "object", "properties": { "chain": { "type": "string" }, "depositAddress": { "type": "string" } }, "required": [ "chain", "depositAddress" ] }, "description": "Every chain this account can receive deposits from — CAIP-2 id + deposit address — uniform across EVM, Solana, and Tron. A chain is present iff the account is registered for it (the canonical per-source registration signal); absence means not registered. EVM chains share the account address; Solana/Tron carry their own. Always present (may be empty)." } }, "required": [ "isRegistered", "sources" ] }, "OutputTokenRule": { "type": "object", "properties": { "match": { "$ref": "#/components/schemas/OutputTokenRuleMatch" }, "outputToken": { "type": "string", "minLength": 1 } }, "required": [ "match", "outputToken" ], "description": "Destination token routing rule. Matches deposits by source token attributes and selects the target-chain output token.", "example": { "match": { "symbol": "USDC" }, "outputToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" } }, "OutputTokenRuleMatch": { "type": "object", "properties": { "chain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "token": { "type": "string", "minLength": 1 }, "symbol": { "type": "string" } }, "description": "Source-token match criteria. Rules may match by source chain, source token address, source symbol, or a combination.", "example": { "chain": "eip155:10", "symbol": "USDC" } }, "UnsupportedFactoryResponse": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "UNSUPPORTED_ACCOUNT_FACTORY" ] } }, "required": [ "error", "code" ] }, "SetupResponse": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] }, "SetupRequestBody": { "type": "object", "properties": { "params": { "$ref": "#/components/schemas/ClientInput" } }, "required": [ "params" ] }, "ClientInput": { "type": "object", "properties": { "webhookUrl": { "type": [ "string", "null" ], "format": "uri" }, "webhookSecret": { "type": [ "string", "null" ] }, "sponsorship": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/ChainSponsorship" } }, "depositWhitelist": { "$ref": "#/components/schemas/DepositWhitelist" }, "swapQuoters": { "$ref": "#/components/schemas/ProjectSwapQuoters" }, "maxPriceDeviationBps": { "type": [ "integer", "null" ], "minimum": 0, "maximum": 10000, "description": "Maximum amount, in basis points, by which a bridge quote may fall short of market prices, with itemised fees excluded. Applies to every EVM-origin deposit whose source token has no priceDeviationTokens entry. Defaults to 300 (3%) if not set.", "example": 200 }, "priceDeviationTokens": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "object", "properties": { "token": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "maxPriceDeviationBps": { "type": "integer", "minimum": 0, "maximum": 10000 } }, "required": [ "token", "maxPriceDeviationBps" ] } }, "description": "Per-source-token overrides of maxPriceDeviationBps, keyed by the EVM chain (CAIP-2, eip155 only) the deposit is bridged from; a HyperCore-origin deposit is bridged from HyperEVM, so key it \"eip155:999\". {} clears every override.", "example": { "eip155:8453": [ { "token": "0x4200000000000000000000000000000000000006", "maxPriceDeviationBps": 300 } ] } }, "minDepositUsd": { "type": [ "number", "null" ], "minimum": 0, "description": "Minimum deposit value in USD. Deposits priced below this are rejected and the client is notified via deposit-rejected. Applies to all tokens and chains.", "example": 1 }, "appFees": { "$ref": "#/components/schemas/AppFees" } } }, "ChainSponsorship": { "type": "object", "properties": { "gas": { "type": "string", "enum": [ "all", "none", "deployed" ], "description": "Gas sponsorship mode", "example": "all" }, "swap": { "type": "string", "enum": [ "all", "none" ], "description": "Fee sponsorship mode", "example": "all" }, "bridging": { "type": "string", "enum": [ "all", "none" ], "description": "Fee sponsorship mode", "example": "all" }, "protocolFee": { "type": "string", "enum": [ "all", "none" ], "description": "Ignored: the Rhinestone protocol fee is always paid from your sponsorship balance, never by the user.", "example": "all" }, "maxAmountUsd": { "type": "number", "exclusiveMinimum": 0, "description": "Largest deposit value in USD this entry sponsors. A deposit valued above it, or one that cannot be priced, settles without gas, bridge or swap sponsorship: the user pays those fees. Honoured only for organizations allowed to pass fees to their users.", "example": 30000 } }, "description": "Which deposit fees your sponsorship balance pays on a source chain. Unless your organization may pass fees to its users, gas and bridging are always sponsored; unless it may sponsor swaps, swaps never are." }, "DepositWhitelist": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "object", "properties": { "token": { "type": "string", "minLength": 1 }, "minAmount": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "maxAmount": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" } }, "required": [ "token" ] } }, "description": "Per-source-chain deposit allowlist keyed by CAIP-2 chain identifiers (for example \"eip155:8453\"). Each key maps to allowed source tokens and optional min/max amount limits in raw token units.", "example": { "eip155:8453": [ { "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "minAmount": "1000000", "maxAmount": "5000000000" } ] } }, "ProjectSwapQuoters": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "string", "enum": [ "1inch", "0x", "velora", "kyberswap", "fynd", "fynd-hosted", "bebop", "relay" ] } }, "description": "List of swap venues we may request quotes from, keyed by the EVM chain the swap is FUNDED FROM (CAIP-2, eip155 only). For every EVM deposit that is the chain it arrived on; a HyperCore-origin deposit swaps on HyperEVM, so key it \"eip155:999\". A routing preference applied when quoting, not a restriction on the account: it does not survive compromise of the executor key, and excluding a venue that would have priced better costs price. Omit a chain to leave it unconstrained. `quoters` applies per intent, so on a cross-chain route the funding chain's list bounds the whole route, and an entry for the destination chain does not constrain a route funded elsewhere.", "example": { "eip155:9745": [ "0x", "fynd" ] } }, "AppFees": { "type": [ "object", "null" ], "properties": { "feeBps": { "type": "integer", "minimum": 0, "maximum": 10000 }, "tokens": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "object", "properties": { "token": { "type": "string", "minLength": 1 }, "feeBps": { "type": "integer", "minimum": 0, "maximum": 10000 } }, "required": [ "token", "feeBps" ] } } } }, "description": "Project app-fee settings. An exact normalized source chain+token rate, including 0, overrides feeBps; unmatched source assets use feeBps or 0 when omitted. On update, feeBps 0 clears only the fallback when tokens is omitted; appFees null clears fallback and overrides.", "example": { "feeBps": 100, "tokens": { "eip155:8453": [ { "token": "0x4200000000000000000000000000000000000006", "feeBps": 200 } ] } } }, "GetSetupResponse": { "type": "object", "properties": { "webhookUrl": { "type": "string" }, "hasWebhookSecret": { "type": "boolean" }, "sponsorship": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/ChainSponsorship" } }, "depositWhitelist": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": { "type": "object", "properties": { "minAmount": { "type": "string" }, "maxAmount": { "type": "string" } } } }, "description": "Per-source-chain deposit allowlist keyed by CAIP-2 chain identifiers, each mapping allowed tokens to optional raw-unit min/max limits." }, "swapQuoters": { "allOf": [ { "$ref": "#/components/schemas/ProjectSwapQuoters" }, { "description": "Swap venues we may request quotes from, keyed by the EVM chain a swap is funded from, as stored. Absent means unconstrained everywhere." } ] }, "maxPriceDeviationBps": { "type": "number" }, "maxPriceDeviationBpsIsDefault": { "type": "boolean", "description": "True when the project stores no maxPriceDeviationBps, so the value above is the platform default and follows it if it changes. Send maxPriceDeviationBps: null to return to it." }, "priceDeviationTokens": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": { "type": "integer", "minimum": 0, "maximum": 10000 } }, "description": "Per-source-token price-deviation limits as stored, keyed by CAIP-2 chain and lowercased token address." }, "minDepositUsd": { "type": "number" }, "appFees": { "type": "object", "properties": { "feeBps": { "type": "integer", "minimum": 0, "maximum": 10000 }, "tokens": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": { "type": "integer", "minimum": 0, "maximum": 10000 } } } } } }, "required": [ "hasWebhookSecret", "maxPriceDeviationBps", "maxPriceDeviationBpsIsDefault" ] }, "RegisterResponse": { "type": "object", "properties": { "evmDepositAddress": { "type": "string" }, "solanaDepositAddress": { "type": "string" }, "tronDepositAddress": { "type": "string" } }, "required": [ "evmDepositAddress" ] }, "RegisterRequestBody": { "type": "object", "properties": { "account": { "$ref": "#/components/schemas/AccountInput" } }, "required": [ "account" ], "description": "A repeat registration preserves owner, kind and destination. Omitted scopes remain stored; explicitly supplied, signed scopes replace existing-chain scopes and signed sessions. Replacing stored material does not revoke older sessions enabled on-chain." }, "AccountInput": { "type": "object", "properties": { "address": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Smart account address to register. Must not be a placeholder, burn or chain system address: the zero address, an address of one repeated hex digit (0x1111…, incl. HyperCore HYPE 0x2222…), 0x…dEaD, or a HyperCore token system address (0x20 followed by zeros and the token index). Such values are rejected with 400.", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "accountParams": { "$ref": "#/components/schemas/AccountParams" }, "target": { "$ref": "#/components/schemas/Target" } }, "required": [ "address", "accountParams", "target" ], "description": "`target.recipient`, when an EVM address: Must not be a placeholder, burn or chain system address: the zero address, an address of one repeated hex digit (0x1111…, incl. HyperCore HYPE 0x2222…), 0x…dEaD, or a HyperCore token system address (0x20 followed by zeros and the token index). Such values are rejected with 400." }, "AccountParams": { "type": "object", "properties": { "factory": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "factoryData": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" }, "sessionDetails": { "$ref": "#/components/schemas/EnableSessionDetails" }, "sessionScopes": { "$ref": "#/components/schemas/SessionScopes" } }, "required": [ "factory", "factoryData", "sessionDetails" ] }, "EnableSessionDetails": { "type": "object", "properties": { "hashesAndChainIds": { "type": "array", "items": { "type": "object", "properties": { "chainId": { "type": "integer", "exclusiveMinimum": 0, "description": "Positive integer", "example": 1 }, "sessionDigest": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" } }, "required": [ "chainId", "sessionDigest" ] } }, "signature": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" } }, "required": [ "hashesAndChainIds", "signature" ] }, "SessionScopes": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/SessionScope" } }, "SessionScope": { "type": "object", "properties": { "sellToken": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Token the deposit arrives in.", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "buyToken": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Where value is allowed to end up — normally the account target token.", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "recipient": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Pinned output recipient, so a compromised signer cannot redirect the swap.", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "settler": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "The 0x Settler this scope pins. Resolved server-side from 0x's registry and echoed back inside `accountParams`; re-send it unchanged on `/register`, because it is an input to the digest you signed.", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "maxSpend": { "type": "string", "pattern": "^\\d+$", "description": "Optional cumulative ceiling on what may leave, in base units. The pinned Settler is what bounds the session, so a cap is only needed as a spend ceiling in its own right. It is a LIFETIME total for the signed session; an explicitly signed replacement can change the stored scope but does not revoke an older session already enabled on-chain.", "example": "1000000000000000000" } }, "required": [ "sellToken", "buyToken", "recipient" ] }, "Target": { "type": "object", "properties": { "recipient": { "type": "string" }, "chain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "token": { "type": "string", "minLength": 1 }, "outputTokenRules": { "type": "array", "items": { "$ref": "#/components/schemas/OutputTokenRule" } }, "rejectUnmapped": { "type": "boolean" }, "postBridgeActions": {} }, "required": [ "chain", "token" ], "description": "Destination target configuration. `chain` must be a CAIP-2 chain identifier such as \"eip155:8453\", \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\", \"tron:mainnet\" or \"hypercore:mainnet\" — see `destination` on `/chains`. `token` and `recipient` follow the chain's address format: 0x-hex for EVM and HyperCore, base58 for Solana, base58check (T-prefixed) for Tron. Tron and HyperCore destinations require an explicit `recipient`, since the EVM account address is not an address on those chains and cannot be defaulted to. Once registered, the destination chain, token, and effective recipient are immutable: use a new address (or managed-account salt) to change them. The owning project may update `outputTokenRules` and `rejectUnmapped`; they remain subject to existing session scopes.", "example": { "chain": "eip155:8453", "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "outputTokenRules": [ { "match": { "symbol": "USDC" }, "outputToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, { "match": { "chain": "eip155:10", "symbol": "ETH" }, "outputToken": "0x0000000000000000000000000000000000000000" } ], "rejectUnmapped": true } }, "DepositAddressesResponse": { "type": "object", "properties": { "evmDepositAddress": { "type": "string" }, "solanaDepositAddress": { "type": "string" }, "tronDepositAddress": { "type": "string" } }, "required": [ "evmDepositAddress" ] }, "SessionResponse": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] }, "SessionRequestBody": { "type": "object", "properties": { "sessionDetails": { "$ref": "#/components/schemas/EnableSessionDetails" } }, "required": [ "sessionDetails" ] }, "TokenAccountResponse": { "type": "object", "properties": { "ataAddress": { "type": "string" }, "created": { "type": "boolean" }, "txSignature": { "type": "string" } }, "required": [ "ataAddress", "created" ] }, "TokenAccountRequestBody": { "type": "object", "properties": { "mint": { "type": "string", "description": "Base58-encoded SPL token mint to create the Associated Token Account for", "example": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" } }, "required": [ "mint" ] }, "RetryDepositByIdResponse": { "type": "object", "properties": { "message": { "type": "string" }, "status": { "type": "string", "enum": [ "pending", "processing", "completed", "failed", "rejected", "ignored", "expecting_refund", "refunded", "delayed", "reconciliation_required" ] } }, "required": [ "message", "status" ] }, "RetryDepositByIdRequestBody": { "type": "object", "properties": { "settlementLayer": { "type": "string", "minLength": 1, "description": "Optional settlement-layer override for the re-drive (e.g. \"ACROSS\", \"RELAY\"). EVM deposits only; rejected for Solana. Omit to let the orchestrator pick.", "example": "RELAY" } } }, "RefundDepositResponse": { "type": "object", "properties": { "message": { "type": "string" }, "transactionHash": { "type": "string" }, "amount": { "type": "string" } }, "required": [ "message", "transactionHash", "amount" ] }, "RefundDepositByIdRequestBody": { "type": "object", "properties": { "recipient": { "type": "string", "minLength": 1, "description": "Address to receive the refunded tokens (EVM address or Solana public key). Must not be the address the deposit is already held at.", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" } }, "required": [ "recipient" ] }, "RecoverDepositErrorResponse": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "DEPOSIT_NOT_RECOVERABLE", "RECOVERY_UNSUPPORTED", "SIGNATURE_INVALID", "VERIFICATION_UNAVAILABLE", "REFUND_RECONCILIATION_REQUIRED", "SETTLEMENT_UNRESOLVED", "REFUND_UNAVAILABLE", "REFUND_FAILED" ] } }, "required": [ "error", "code" ] }, "RecoverDepositRequestBody": { "type": "object", "properties": { "depositId": { "type": "string", "pattern": "^\\d+$", "description": "Deposit id, as returned by `GET /deposits`. Identifies the row directly: one transaction can produce several deposits, so a {chain, txHash, account, token} tuple does not.", "example": "2551" }, "destination": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Address to receive the recovered tokens on the deposit's source chain. Covered by the signature, so the caller cannot redirect an authorized recovery.", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "signature": { "type": "string", "minLength": 132, "maxLength": 8194, "pattern": "^0x([a-fA-F0-9]{2})+$", "description": "Signature by the deposit recipient over the RecoverDeposit typed data, in whatever form that account verifies: raw ECDSA (EOA), ERC-1271 (deployed smart account), or ERC-6492-wrapped (undeployed).", "example": "0x1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" } }, "required": [ "depositId", "destination", "signature" ] }, "ListDepositsResponse": { "type": "object", "properties": { "deposits": { "type": "array", "items": { "$ref": "#/components/schemas/DepositListItem" } }, "nextCursor": { "type": [ "string", "null" ] } }, "required": [ "deposits", "nextCursor" ] }, "DepositListItem": { "type": "object", "properties": { "id": { "type": "string", "description": "Deposit id. Pass to GET /deposits/{id}/quotes.", "example": "12345" }, "chain": { "type": "string" }, "txHash": { "type": "string" }, "token": { "type": "string" }, "tokenSymbol": { "type": [ "string", "null" ], "description": "Display symbol for `token`, resolved at read time. Null when the token could not be resolved — render the raw address.", "example": "USDC" }, "tokenDecimals": { "type": [ "integer", "null" ], "description": "Decimals for `token`, i.e. what makes `amount` and `sourceAmount` renderable — both are raw base units. Null when unresolved; render the raw integer rather than guessing 18.", "example": 6 }, "targetTokenSymbol": { "type": [ "string", "null" ], "description": "Display symbol for `targetToken`. Null when unresolved.", "example": "USDC" }, "targetTokenDecimals": { "type": [ "integer", "null" ], "description": "Decimals for `targetToken`, applying to `destinationAmount`. Null when unresolved.", "example": 6 }, "amount": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "sender": { "type": "string" }, "recipient": { "type": "string", "description": "Destination-chain address that receives the funds. Falls back to the smart account for EVM/HyperCore/Tron when no distinct recipient is configured; for Solana it is the EVM recipient, never the internal swig." }, "depositAddress": { "type": "string", "description": "Source-chain address that received the deposit (EVM smart account, Solana wallet PDA, or Tron deposit address)." }, "targetChain": { "type": "string" }, "targetToken": { "type": "string" }, "status": { "type": "string", "enum": [ "pending", "processing", "completed", "failed", "rejected", "ignored", "expecting_refund", "refunded", "delayed", "reconciliation_required" ] }, "sourceTxHash": { "type": [ "string", "null" ] }, "destinationTxHash": { "type": [ "string", "null" ] }, "sourceAmount": { "type": [ "string", "null" ], "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "destinationAmount": { "type": [ "string", "null" ], "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "sponsoredGasUsd": { "type": "string", "description": "USD value of gas absorbed for the user. Absent when no sponsorship accounting exists; \"0\" means nothing was sponsored.", "example": "0.42" }, "sponsoredBridgeFeeUsd": { "type": "string", "description": "USD value of the bridge fee absorbed for the user. Excludes app fees and sponsor surcharges. Absent when no accounting exists; \"0\" means nothing was sponsored.", "example": "0.13" }, "createdAt": { "type": "string" }, "completedAt": { "type": [ "string", "null" ] }, "errorCode": { "type": [ "string", "null" ] }, "creditKind": { "type": "string", "enum": [ "deposit", "collector_return" ] }, "retryable": { "type": "boolean" }, "refundAttributions": { "type": "array", "items": { "type": "object", "properties": { "submissionKey": { "type": "string" }, "intentId": { "type": "string" }, "state": { "type": "string" }, "reason": { "type": [ "string", "null" ] }, "references": { "type": "array", "items": { "type": "object", "properties": { "chain": { "type": "string" }, "txHash": { "type": "string" }, "vm": { "type": "string" } }, "required": [ "chain", "txHash" ] } }, "credit": { "type": "object", "properties": { "chain": { "type": "string" }, "txHash": { "type": "string" }, "account": { "type": "string" }, "token": { "type": "string" }, "amount": { "type": "string" } }, "required": [ "chain", "txHash", "account", "token", "amount" ] }, "successorDepositId": { "type": "string" } }, "required": [ "submissionKey", "intentId", "state", "reason" ] } }, "refundOf": { "type": "array", "items": { "type": "object", "properties": { "depositId": { "type": "string" }, "submissionKey": { "type": "string" } }, "required": [ "depositId", "submissionKey" ] } }, "delivery": { "type": "object", "properties": { "outcome": { "type": "string", "enum": [ "pending", "delivered", "returned", "failed", "unresolved" ] }, "depositId": { "type": [ "string", "null" ] }, "reason": { "type": "string" }, "chain": { "type": "string" }, "token": { "type": "string" }, "recipient": { "type": "string" }, "amount": { "type": "string" }, "txHash": { "type": "string" }, "completedAt": { "type": "string" } }, "required": [ "outcome", "depositId" ] }, "isSpam": { "type": "boolean" }, "timing": { "$ref": "#/components/schemas/DepositTimingEstimate" } }, "required": [ "id", "chain", "txHash", "token", "tokenSymbol", "tokenDecimals", "targetTokenSymbol", "targetTokenDecimals", "amount", "sender", "recipient", "depositAddress", "targetChain", "targetToken", "status", "sourceTxHash", "destinationTxHash", "sourceAmount", "destinationAmount", "createdAt", "completedAt", "errorCode", "creditKind", "retryable", "isSpam" ] }, "DepositTimingEstimate": { "type": "object", "properties": { "expectedSeconds": { "type": "integer", "minimum": 0, "description": "How long the deposit is expected to take end to end, in seconds. Derived from qualifying recent completed deposits or the selected route’s indicative estimate; never a deadline or guarantee.", "example": 42 }, "softDelaySeconds": { "type": "integer", "minimum": 0, "description": "Seconds after which the deposit is running slower than usual and a client may reassure the user. Indicative only.", "example": 90 }, "escalatedDelaySeconds": { "type": "integer", "minimum": 0, "description": "Seconds after which the deposit is unusually slow and a client may offer support. Indicative only, not an SLA.", "example": 300 } }, "required": [ "expectedSeconds", "softDelaySeconds", "escalatedDelaySeconds" ], "description": "Indicative, non-contractual duration estimate derived from qualifying recent completed deposits on the corridor or chain pair, falling back to the selected route’s indicative estimate when aggregate data is unavailable. Always `expectedSeconds` <= `softDelaySeconds` <= `escalatedDelaySeconds`. On a deposit the seconds are measured from its `createdAt` and are served only while it is still in flight (`pending`, `processing`, `delayed`); on a quote preview they describe the quoted route. Resolved per request, so it may change between calls, and absent whenever no estimate is available. Never a deadline, an expiry or a guarantee." }, "DepositQuotesResponse": { "type": "object", "properties": { "count": { "type": "integer" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/DepositQuoteItem" } } }, "required": [ "count", "items" ] }, "DepositQuoteItem": { "type": "object", "properties": { "intentId": { "type": "string" }, "settlementLayer": { "type": "string" }, "bridgeProvider": { "type": [ "string", "null" ] }, "rank": { "type": "integer" }, "outcome": { "type": "string", "enum": [ "quoted", "attempted", "succeeded", "failed", "skipped" ] }, "quote": {}, "errorCode": { "type": [ "string", "null" ] }, "errorMessage": { "type": [ "string", "null" ] }, "attemptedAt": { "type": [ "string", "null" ] }, "completedAt": { "type": [ "string", "null" ] }, "createdAt": { "type": "string" } }, "required": [ "intentId", "settlementLayer", "bridgeProvider", "rank", "outcome", "errorCode", "errorMessage", "attemptedAt", "completedAt", "createdAt" ] }, "QuotePreviewResponse": { "type": "object", "properties": { "settlementLayer": { "type": "string" }, "expiresAt": { "type": "integer" }, "estimatedFillTimeSeconds": { "type": "integer", "minimum": 0, "description": "The orchestrator's estimate for the fill leg, in seconds. Covers bridging only; see `timing.expectedSeconds` for the end-to-end expectation.", "example": 7 }, "timing": { "$ref": "#/components/schemas/DepositTimingEstimate" }, "fees": { "type": "object", "properties": { "total": { "type": "object", "properties": { "usd": { "type": "number" } }, "required": [ "usd" ] }, "totalUsd": { "type": "number" }, "breakdown": { "type": "object", "properties": { "gas": { "$ref": "#/components/schemas/PreviewFeeLine" }, "bridge": { "$ref": "#/components/schemas/PreviewFeeLine" }, "swap": { "$ref": "#/components/schemas/PreviewFeeLine" }, "app": { "$ref": "#/components/schemas/PreviewFeeLine" }, "protocol": { "$ref": "#/components/schemas/PreviewFeeLine" }, "sponsorSurcharge": { "$ref": "#/components/schemas/PreviewFeeLine" } }, "required": [ "gas", "bridge", "swap", "app", "protocol", "sponsorSurcharge" ], "additionalProperties": { "$ref": "#/components/schemas/PreviewFeeLine" } } }, "required": [ "total", "breakdown" ] }, "input": { "type": "object", "properties": { "token": { "type": "string" }, "amount": { "type": "string" }, "symbol": { "type": [ "string", "null" ] }, "decimals": { "type": [ "integer", "null" ] } }, "required": [ "token", "amount", "symbol", "decimals" ] }, "output": { "type": "object", "properties": { "token": { "type": "string" }, "amount": { "type": "string" }, "symbol": { "type": [ "string", "null" ] }, "decimals": { "type": [ "integer", "null" ] } }, "required": [ "token", "amount", "symbol", "decimals" ] } }, "required": [ "settlementLayer", "expiresAt", "estimatedFillTimeSeconds", "fees", "input", "output" ] }, "PreviewFeeLine": { "type": "object", "properties": { "usd": { "type": "number" }, "sponsored": { "type": "boolean" }, "label": { "type": "string" }, "internal": { "type": "boolean" } }, "required": [ "usd", "sponsored" ] }, "QuotePreviewRequest": { "type": "object", "properties": { "account": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "sourceChainId": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "sourceToken": { "type": "string", "description": "Source token: a 0x address on an EVM source chain, or a base58 SPL mint on Solana.", "example": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" }, "direction": { "type": "string", "enum": [ "exactIn", "exactOut" ], "default": "exactIn", "description": "`exactIn` fixes the deposited `amount` and quotes what is delivered; `exactOut` fixes the delivered `amountOut` and quotes the deposit that produces it. Defaults to `exactIn`.", "example": "exactIn" }, "amount": { "type": "string", "pattern": "^\\d+$", "description": "Deposited amount in the source token's smallest unit. Required for (and only valid with) `direction: exactIn`.", "example": "1000000" }, "amountOut": { "type": "string", "pattern": "^\\d+$", "description": "Delivered amount in the destination token's smallest unit. Required for (and only valid with) `direction: exactOut`; the quote's `input.amount` is then the deposit that produces it.", "example": "1000000" } }, "required": [ "account", "sourceChainId", "sourceToken" ] }, "PermitDepositPrepareResponse": { "oneOf": [ { "type": "object", "properties": { "available": { "type": "boolean", "enum": [ true ] }, "authorization": { "anyOf": [ { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "erc3009" ] }, "typedData": { "$ref": "#/components/schemas/PermitTypedData" }, "nonce": { "type": "string", "pattern": "^0x[a-fA-F0-9]{64}$", "description": "ERC-3009 bytes32 authorization nonce", "example": "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" }, "validAfter": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "validBefore": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" } }, "required": [ "kind", "typedData", "nonce", "validAfter", "validBefore" ] }, { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "erc2612", "permit2" ] }, "typedData": { "$ref": "#/components/schemas/PermitTypedData" }, "nonce": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "deadline": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" } }, "required": [ "kind", "typedData", "nonce", "deadline" ] } ] } }, "required": [ "available", "authorization" ] }, { "type": "object", "properties": { "available": { "type": "boolean", "enum": [ false ] }, "reason": { "type": "string", "enum": [ "permit2-approval-required", "unsupported-token", "unsupported-owner" ] }, "approval": { "type": "object", "properties": { "token": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "spender": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "minimumAmount": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" } }, "required": [ "token", "spender", "minimumAmount" ] } }, "required": [ "available", "reason" ] } ] }, "PermitTypedData": { "type": "object", "properties": { "domain": {}, "types": {}, "primaryType": { "type": "string" }, "message": {} }, "required": [ "primaryType" ] }, "PermitDepositPrepareRequest": { "type": "object", "properties": { "account": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "sourceChain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "token": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "amount": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "owner": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "kind": { "type": "string", "enum": [ "auto", "erc3009", "erc2612", "permit2" ], "description": "Authorization scheme preference. Auto selects ERC-3009, then ERC-2612, then Permit2.", "example": "auto" } }, "required": [ "account", "sourceChain", "token", "amount", "owner" ] }, "PermitDepositSubmitResponse": { "type": "object", "properties": { "depositId": { "type": "string" }, "txHash": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" }, "status": { "type": "string", "enum": [ "processing" ] } }, "required": [ "depositId", "txHash", "status" ] }, "PermitDepositSubmitRequest": { "oneOf": [ { "type": "object", "properties": { "account": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "sourceChain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "token": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "amount": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "owner": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "signature": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" }, "kind": { "type": "string", "enum": [ "erc3009" ] }, "nonce": { "type": "string", "pattern": "^0x[a-fA-F0-9]{64}$", "description": "ERC-3009 bytes32 authorization nonce", "example": "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" }, "validAfter": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "validBefore": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" } }, "required": [ "account", "sourceChain", "token", "amount", "owner", "signature", "kind", "nonce", "validAfter", "validBefore" ] }, { "type": "object", "properties": { "account": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "sourceChain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "token": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "amount": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "owner": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "signature": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" }, "kind": { "type": "string", "enum": [ "erc2612" ] }, "nonce": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "deadline": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" } }, "required": [ "account", "sourceChain", "token", "amount", "owner", "signature", "kind", "nonce", "deadline" ] }, { "type": "object", "properties": { "account": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "sourceChain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "token": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "amount": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "owner": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "signature": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" }, "kind": { "type": "string", "enum": [ "permit2" ] }, "nonce": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "deadline": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" } }, "required": [ "account", "sourceChain", "token", "amount", "owner", "signature", "kind", "nonce", "deadline" ] } ] }, "DepositStatsResponse": { "type": "object", "properties": { "period": { "type": "string", "enum": [ "24h", "7d", "30d" ], "description": "Rolling time window for aggregated stats", "example": "7d" }, "totalDeposits": { "type": "integer", "minimum": 0 }, "uniqueUsers": { "type": "integer", "minimum": 0 }, "volumeUsd": { "type": "string" } }, "required": [ "period", "totalDeposits", "uniqueUsers", "volumeUsd" ] }, "ManagedRegisterResponse": { "type": "object", "properties": { "evmDepositAddress": { "type": "string" }, "solanaDepositAddress": { "type": "string" }, "tronDepositAddress": { "type": "string" } }, "required": [ "evmDepositAddress" ] }, "ManagedRegisterRequestBody": { "type": "object", "properties": { "account": { "$ref": "#/components/schemas/ManagedAccountInput" } }, "required": [ "account" ], "description": "A repeat using the same salt preserves the derived address, owner, account kind, and destination. Use a new salt to change destination." }, "ManagedAccountInput": { "type": "object", "properties": { "salt": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" }, "target": { "$ref": "#/components/schemas/ManagedTarget" } }, "required": [ "salt", "target" ], "description": "`target.recipient`, when an EVM address: Must not be a placeholder, burn or chain system address: the zero address, an address of one repeated hex digit (0x1111…, incl. HyperCore HYPE 0x2222…), 0x…dEaD, or a HyperCore token system address (0x20 followed by zeros and the token index). Such values are rejected with 400." }, "ManagedTarget": { "type": "object", "properties": { "recipient": { "type": "string", "minLength": 1 }, "chain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "token": { "type": "string", "minLength": 1 }, "outputTokenRules": { "type": "array", "items": { "$ref": "#/components/schemas/OutputTokenRule" } }, "rejectUnmapped": { "type": "boolean" }, "postBridgeActions": {} }, "required": [ "recipient", "chain", "token" ], "description": "Destination target configuration for managed accounts. `recipient` is required and specifies the address that receives the final tokens." }, "SetupAccountResponse": { "type": "object", "properties": { "smartAccount": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "isRegistered": { "type": "boolean" }, "targetChain": { "type": "string" }, "targetToken": { "type": "string" }, "needsRegistration": { "type": "boolean" }, "solanaDepositAddress": { "type": "string" }, "accountParams": { "type": "object", "properties": { "factory": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "factoryData": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" }, "sessionScopes": { "$ref": "#/components/schemas/SessionScopes" } }, "required": [ "factory", "factoryData" ] }, "sessionDetailsUnsigned": { "type": "object", "properties": { "hashesAndChainIds": { "type": "array", "items": { "type": "object", "properties": { "chainId": { "type": "string" }, "sessionDigest": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" } }, "required": [ "chainId", "sessionDigest" ] } }, "data": { "type": "object", "additionalProperties": {} } }, "required": [ "hashesAndChainIds", "data" ] } }, "required": [ "smartAccount", "isRegistered", "needsRegistration" ] }, "SetupAccountRequestBody": { "type": "object", "properties": { "ownerAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "sessionOwnerAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "targetToken": { "type": "string", "minLength": 1 }, "targetChain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "recipient": { "type": "string", "description": "Address that receives the final tokens. Must not be a placeholder, burn or chain system address: the zero address, an address of one repeated hex digit (0x1111…, incl. HyperCore HYPE 0x2222…), 0x…dEaD, or a HyperCore token system address (0x20 followed by zeros and the token index). Such values are rejected with 400." }, "outputTokenRules": { "type": "array", "items": { "$ref": "#/components/schemas/OutputTokenRule" } }, "rejectUnmapped": { "type": "boolean" }, "postBridgeActions": {}, "sessionScopes": { "$ref": "#/components/schemas/SessionScopes" }, "signerAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "sessionChainIds": { "type": "array", "items": { "type": "integer", "exclusiveMinimum": 0 } }, "forceRegister": { "type": "boolean" } }, "required": [ "ownerAddress", "sessionOwnerAddress", "targetToken", "targetChain" ], "description": "Preflight for registration. Address owner, kind and destination are immutable; destination changes require a new address. Explicitly supplied scopes on existing chains require a new signature and replace stored scopes; omission preserves them. Replacement does not revoke older on-chain sessions." }, "PortfolioResponse": { "type": "object", "properties": { "tokens": { "type": "array", "items": { "type": "object", "properties": { "chainId": { "anyOf": [ { "type": "number" }, { "type": "string" } ] }, "address": { "type": "string" }, "symbol": { "type": "string" }, "name": { "type": "string" }, "decimals": { "type": "number" }, "balance": { "type": "string" }, "balanceUsd": { "type": "number" } }, "required": [ "chainId", "symbol", "name", "decimals", "balance", "balanceUsd" ] } }, "totalUsd": { "type": "number" }, "truncated": { "type": "boolean" } }, "required": [ "tokens", "totalUsd" ] }, "PositionsResponse": { "type": "object", "properties": { "positions": { "type": "array", "items": { "type": "object", "properties": { "venue": { "type": "string", "enum": [ "aave" ] }, "kind": { "type": "string", "enum": [ "lending" ] }, "market": { "type": "object", "properties": { "address": { "type": "string" }, "name": { "type": "string" } }, "required": [ "address", "name" ], "description": "Positions are keyed by market, not chain — Ethereum alone hosts four Aave v3 markets with distinct pools and risk params." }, "chain": { "type": "string", "description": "CAIP-2 chain id", "example": "eip155:8453" }, "asset": { "type": "object", "properties": { "address": { "type": "string" }, "symbol": { "type": "string" }, "decimals": { "type": "number" } }, "required": [ "address", "symbol", "decimals" ] }, "amount": { "type": "string", "description": "Supplied balance in base units, accrued interest included" }, "usdValue": { "type": "number" }, "apy": { "type": "number" }, "isCollateral": { "type": "boolean" }, "maxWithdrawable": { "type": "string", "description": "Largest amount withdrawable right now, in base units. Capped so the withdraw cannot be rejected on-chain." }, "withdrawableUsd": { "type": "number", "description": "USD value of `maxWithdrawable` — what would actually reach the deposit address, as opposed to `usdValue`, which prices the whole holding. Display this next to an amount you offer: it is also the figure this project's deposit floor is judged against, and re-deriving it from `usdValue` needs the amount ratio taken in integer space to survive an 18-decimal balance.", "example": 40.02 }, "isFullExit": { "type": "boolean", "description": "True when the entire supplied balance can leave in one transaction" }, "constraints": { "type": "array", "items": { "type": "string", "enum": [ "health_factor", "frozen_reserve", "nothing_supplied", "paused_reserve", "ltv_validation", "available_liquidity", "below_deposit_floor", "deposit_not_whitelisted", "outside_session_scope" ], "description": "Why the position cannot be fully migrated. Venue reasons (`health_factor`, `paused_reserve`, `ltv_validation`, `available_liquidity`) cap `maxWithdrawable` itself. `frozen_reserve` is advisory — Aave still permits withdrawing from a frozen reserve. `below_deposit_floor`, `deposit_not_whitelisted` and `outside_session_scope` mean the venue would pay out but this project's deposit policy would then reject the proceeds, so they do not reduce `maxWithdrawable`. `outside_session_scope` additionally means the proceeds would strand: a scoped session has no refund action." } } }, "required": [ "venue", "kind", "market", "chain", "asset", "amount", "usdValue", "apy", "isCollateral", "maxWithdrawable", "withdrawableUsd", "isFullExit", "constraints" ] } }, "totalUsd": { "type": "number" }, "minDepositUsd": { "type": "number", "description": "The USD floor the withdrawn proceeds must clear for this project, resolved from the platform minimum and the project's own `minDepositUsd`. Proceeds below it are rejected on ingest after the withdrawal has already happened.", "example": 0.04 }, "failures": { "type": "array", "items": { "type": "object", "properties": { "venue": { "type": "string" }, "reason": { "type": "string" } }, "required": [ "venue", "reason" ] }, "description": "Present only when a venue could not be reached, so an empty `positions` list can be told apart from a failed lookup." } }, "required": [ "positions", "totalUsd", "minDepositUsd" ] }, "PrepareUnwindResponse": { "type": "object", "properties": { "transaction": { "type": "object", "properties": { "to": { "type": "string" }, "data": { "type": "string" }, "value": { "type": "string" }, "chainId": { "type": "number" } }, "required": [ "to", "data", "value", "chainId" ], "description": "Unsigned transaction for the holding EOA to sign and send. The backend never executes it — the EOA holds the aTokens, so only it can authorise the withdraw." }, "amount": { "type": "string", "description": "Base units the transaction will withdraw" }, "isFullExit": { "type": "boolean", "description": "True when the whole position is being withdrawn, in which case the calldata uses the max-uint sentinel so interest accrued before the transaction lands is swept too." }, "recipient": { "type": "string", "description": "The deposit address the proceeds are sent to, resolved from the registered account. Echoed so it is auditable." }, "constraints": { "type": "array", "items": { "type": "string" }, "description": "Why the amount is below the supplied balance, if it is. Empty for an unconstrained full exit." } }, "required": [ "transaction", "amount", "isFullExit", "recipient", "constraints" ] }, "PrepareUnwindRequestBody": { "type": "object", "properties": { "account": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "The registered deposit account the proceeds go to. The recipient is resolved from this server-side; it is never taken from the request directly." }, "market": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "The Aave market's Pool address, as returned in a position's `market.address`. Required rather than inferred, because a chain can host several markets." }, "chainId": { "type": "integer", "exclusiveMinimum": 0, "example": 8453 }, "asset": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "The supplied underlying token to withdraw" }, "amount": { "type": "string", "pattern": "^\\d+$", "description": "Base units to withdraw. Omit for the largest amount currently permitted. An amount above that maximum is rejected rather than silently reduced.", "example": "1000000000000000000" } }, "required": [ "account", "market", "chainId", "asset" ] }, "LiquidityResponse": { "type": "object", "properties": { "hasLiquidity": { "type": "boolean" }, "symbol": { "type": "string" }, "decimals": { "type": "number" }, "unlimited": { "type": "boolean" }, "maxAmount": { "type": [ "string", "null" ] } }, "required": [ "hasLiquidity", "symbol", "decimals", "unlimited", "maxAmount" ] }, "PricesResponse": { "type": "object", "properties": { "prices": { "type": "object", "additionalProperties": { "type": "number" }, "description": "USD unit price keyed by uppercased token symbol (for `symbols`) or by CAIP-2 token id (for `addresses`)", "example": { "SOL": 168.42 } } }, "required": [ "prices" ] }, "QrTokensResponse": { "type": "object", "properties": { "restricted": { "type": "boolean", "description": "True when the project has a deposit whitelist. `tokens` is then the complete accepted set: every chain is reported, a chain absent from `tokens` is not offered, and a token is listed exactly when a deposit of it would be accepted." }, "tokens": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "object", "properties": { "symbol": { "type": "string", "example": "USDC" }, "address": { "type": "string", "example": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" }, "decimals": { "type": "integer", "minimum": 0, "example": 6 }, "minAmount": { "type": "string", "description": "Configured whitelist minimum in raw token units (same decimals as `decimals`). Present only when `restricted` is true and the client set one.", "example": "1000000" }, "maxAmount": { "type": "string", "description": "Configured whitelist maximum in raw token units (same decimals as `decimals`). Present only when `restricted` is true and the client set one." } }, "required": [ "symbol", "address", "decimals" ] } }, "description": "Keyed by EVM chain id as a decimal string, plus \"solana\" and \"hypercore\". An empty array means the chain is not offered (paused, not depositable, or disallowed by the whitelist) and clients should hide it. When `restricted` is false this is a suggested shortlist, and an absent chain carries no opinion; when `restricted` is true it is exhaustive." } }, "required": [ "restricted", "tokens" ] }, "WithdrawResponse": { "type": "object", "properties": { "message": { "type": "string" }, "txHash": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" } }, "required": [ "message" ] }, "WithdrawRequestBody": { "type": "object", "properties": { "chainId": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "safeAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "safeTransaction": { "$ref": "#/components/schemas/SafeTransaction" }, "signature": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" } }, "required": [ "chainId", "safeAddress", "safeTransaction", "signature" ] }, "SafeTransaction": { "type": "object", "properties": { "to": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "value": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "data": { "type": "string", "pattern": "^0x([a-fA-F0-9]{2})*$", "description": "Hex-encoded calldata, byte-aligned. Empty (`0x`) for a plain native-value transfer.", "example": "0x" }, "operation": { "anyOf": [ { "type": "number", "enum": [ 0 ] }, { "type": "number", "enum": [ 1 ] } ] }, "safeTxGas": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "baseGas": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "gasPrice": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "gasToken": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "refundReceiver": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "nonce": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" } }, "required": [ "to", "value", "data", "operation", "safeTxGas", "baseGas", "gasPrice", "gasToken", "refundReceiver", "nonce" ] }, "PolymarketWithdrawResponse": { "type": "object", "properties": { "message": { "type": "string" }, "txHash": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" } }, "required": [ "message", "txHash" ] }, "PolymarketWithdrawRequestBody": { "type": "object", "properties": { "depositWallet": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "owner": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "nonce": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "deadline": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "calls": { "type": "array", "items": { "$ref": "#/components/schemas/PolymarketCall" }, "minItems": 1 }, "signature": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" } }, "required": [ "depositWallet", "owner", "nonce", "deadline", "calls", "signature" ] }, "PolymarketCall": { "type": "object", "properties": { "target": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "value": { "type": "string", "pattern": "^\\d+$", "description": "Numeric string representing a bigint value", "example": "1000000000000000000" }, "data": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$", "description": "Hex-encoded string (0x followed by hex characters)", "example": "0x1234abcd" } }, "required": [ "target", "value", "data" ] }, "ListWebhookEventsResponse": { "type": "object", "properties": { "events": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEvent" } }, "nextCursor": { "type": [ "string", "null" ] } }, "required": [ "events", "nextCursor" ] }, "WebhookEvent": { "type": "object", "properties": { "eventId": { "type": "string" }, "type": { "type": "string" }, "time": { "type": "string" }, "status": { "type": "string", "enum": [ "pending", "delivered", "failed" ] }, "attempts": { "type": "number" }, "payload": {}, "depositId": { "type": [ "string", "null" ] }, "deliveredAt": { "type": [ "string", "null" ] } }, "required": [ "eventId", "type", "time", "status", "attempts", "depositId", "deliveredAt" ] }, "ResendWebhookEventResponse": { "type": "object", "properties": { "message": { "type": "string" }, "eventId": { "type": "string" }, "status": { "type": "string", "enum": [ "pending", "delivered", "failed" ] }, "attempts": { "type": "number" } }, "required": [ "message", "eventId", "status", "attempts" ] }, "TestWebhookResponse": { "type": "object", "properties": { "message": { "type": "string" }, "eventId": { "type": "string" } }, "required": [ "message", "eventId" ] }, "TestWebhookRequestBody": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "deposit-received", "bridge-started", "bridge-delayed", "bridge-complete", "bridge-failed", "deposit-rejected", "deposit-delayed", "deposit-refunded", "onramp-order", "ramp-order" ], "description": "Which webhook type to simulate", "example": "bridge-started" } }, "required": [ "type" ] }, "ComplianceSessionResponse": { "type": "object", "properties": { "externalCustomerId": { "type": "string", "description": "The opaque external customer reference, returned only to the authenticated integrator backend." }, "token": { "type": "string", "description": "Short-lived scoped session bearer for the browser." }, "expiresAt": { "type": "string", "description": "ISO-8601 absolute expiry of the session token.", "example": "2026-08-13T12:15:00.000Z" } }, "required": [ "externalCustomerId", "token", "expiresAt" ] }, "ComplianceSessionNotFound": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "CUSTOMER_NOT_FOUND" ] } }, "required": [ "error", "code" ] }, "ComplianceSessionConflict": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "ACCOUNT_ALREADY_LINKED", "ACCOUNT_CHANGE_REQUIRES_MIGRATION" ], "description": "`ACCOUNT_ALREADY_LINKED`: another customer holds the account. `ACCOUNT_CHANGE_REQUIRES_MIGRATION`: the customer is bound to a different account, which cannot change yet" } }, "required": [ "error", "code" ] }, "ComplianceSessionRequestBody": { "type": "object", "properties": { "externalCustomerId": { "type": "string", "minLength": 1, "maxLength": 200, "description": "The integrator's stable, opaque end-user identifier. Must reveal no identity data (no email/name/wallet). Stored verbatim within the authenticated project.", "example": "usr_01J7H8Q4K67Y8E" }, "smartAccount": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "resumeOnly": { "type": "boolean", "description": "Read-only session: never creates a customer or binds an account. 404 `CUSTOMER_NOT_FOUND` unless the customer exists and is bound to `smartAccount` (or no account is given). Needs `deposits:read`. The bearer is read-only whatever the key may do: it reads status, options, accounts and orders, while `POST /compliance/verification`, `POST /onramp/accounts` and `POST /offramp/orders` answer 403 `READ_ONLY_SESSION`." } }, "required": [ "externalCustomerId" ] }, "ComplianceStatusResponse": { "type": "object", "properties": { "status": { "$ref": "#/components/schemas/ComplianceVerificationStatus" }, "updatedAt": { "type": "string", "description": "ISO-8601 timestamp of the last status change." }, "verification": { "type": "object", "properties": { "actionsRequired": { "type": "array", "items": { "type": "string" }, "description": "Outstanding customer actions; resume hosted verification to complete them." }, "entities": { "type": "array", "items": { "type": "object", "properties": { "entity": { "type": "string", "description": "Provider jurisdiction, e.g. Us, Lt." }, "status": { "type": "string", "enum": [ "Pending", "Approved", "Declined" ] }, "model": { "type": "string" }, "rejectType": { "type": "string", "enum": [ "Final", "Retry" ], "description": "Present on a declined entity; Retry means the customer can resubmit." } }, "required": [ "entity", "status", "model" ] } }, "agreements": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "version": { "type": "integer" }, "accepted": { "type": "boolean" } }, "required": [ "name", "version", "accepted" ] } } }, "required": [ "actionsRequired", "entities", "agreements" ] } }, "required": [ "status", "updatedAt" ] }, "ComplianceVerificationStatus": { "type": "string", "enum": [ "not_started", "pending", "approved", "declined" ] }, "ComplianceVerificationSession": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "status": { "type": "string", "enum": [ "pending", "completed", "failed" ], "description": "pending: present nextAction or await review; completed: already verified; failed: provider rejected. Interaction status only, never settlement." }, "expiresAt": { "type": "string", "format": "date-time" }, "nextAction": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "hosted" ] }, "url": { "type": "string", "format": "uri" }, "presentation": { "type": "string", "enum": [ "iframe" ] } }, "required": [ "type", "url", "presentation" ], "additionalProperties": false } }, "required": [ "id", "status", "expiresAt" ], "additionalProperties": false }, "ProviderError": { "type": "object", "properties": { "provider": { "type": "string" }, "status": { "type": [ "integer", "null" ], "description": "The provider’s HTTP status; null when it answered outside its contract" }, "type": { "type": [ "string", "null" ], "description": "The provider’s error category, e.g. `InvalidMessage`" }, "fields": { "type": "array", "items": { "type": "object", "properties": { "path": { "type": [ "string", "null" ], "description": "The provider’s request path, e.g. `Form.BankDetails.AccountNumber`; null when it names no field we send" }, "reason": { "type": [ "string", "null" ], "description": "e.g. `SchemaValidation`, `NotSupported`; null when unrecognised" } }, "required": [ "path", "reason" ], "additionalProperties": false }, "description": "Request fields the provider refused" }, "reference": { "type": [ "string", "null" ], "description": "The provider’s id for this failure: quote it to its support" } }, "required": [ "provider", "status", "type", "fields", "reference" ], "additionalProperties": false, "description": "PROVIDER_REJECTED and PROVIDER_FORBIDDEN: what the provider refused" }, "ComplianceVerificationRequestBody": { "type": "object", "properties": { "currency": { "type": "string", "enum": [ "EUR", "USD" ], "deprecated": true, "description": "Ignored. The customer is verified for both currencies; the residence they declare decides the account's (EUR inside SEPA, USD elsewhere)." } }, "additionalProperties": false }, "OnrampProviders": { "type": "object", "properties": { "providers": { "type": "array", "items": { "type": "object", "properties": { "provider": { "type": "string", "enum": [ "noah", "swapped" ] }, "auth": { "type": "string", "enum": [ "project", "customer" ], "description": "Which credential its routes take: the project key, or a customer session" }, "flow": { "type": "string", "enum": [ "hosted", "funding_account" ], "description": "`hosted`: a checkout per order (`POST /onramp/orders`); `funding_account`: reusable bank details (`POST /onramp/accounts`)" }, "kinds": { "type": "array", "items": { "type": "string", "enum": [ "fiat", "exchange" ] } } }, "required": [ "provider", "auth", "flow", "kinds" ], "additionalProperties": false } } }, "required": [ "providers" ], "additionalProperties": false }, "OnrampOrder": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "provider": { "type": "string", "enum": [ "noah", "swapped" ] }, "kind": { "type": "string", "enum": [ "fiat", "exchange" ] }, "status": { "type": "string", "enum": [ "pending", "processing", "completed", "failed", "refunded" ] }, "terminal": { "type": "boolean", "description": "No stage will change again" }, "stages": { "type": "object", "properties": { "receipt": { "$ref": "#/components/schemas/OnrampReceiptStage" }, "conversion": { "$ref": "#/components/schemas/OnrampConversionStage" }, "delivery": { "$ref": "#/components/schemas/OnrampDeliveryStage" }, "return": { "$ref": "#/components/schemas/OnrampReturnStage" } }, "required": [ "receipt", "conversion", "delivery", "return" ], "additionalProperties": false }, "rail": { "oneOf": [ { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "fiat" ] }, "method": { "type": "string" } }, "required": [ "kind", "method" ], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "exchange" ] }, "connection": { "type": "string" } }, "required": [ "kind", "connection" ], "additionalProperties": false } ], "description": "`provider_selected` / `unknown` when the provider did not say" }, "fiat": { "type": "object", "properties": { "charged": { "type": [ "object", "null" ], "properties": { "total": { "type": [ "string", "null" ], "description": "Including fees" }, "net": { "type": [ "string", "null" ], "description": "Before fees" }, "currency": { "type": "string" } }, "required": [ "total", "net", "currency" ], "additionalProperties": false, "description": "What the customer paid, in their own currency" }, "eur": { "type": [ "object", "null" ], "properties": { "total": { "type": [ "string", "null" ], "description": "Including fees" }, "net": { "type": [ "string", "null" ], "description": "Before fees" } }, "required": [ "total", "net" ], "additionalProperties": false, "description": "Comparable across every order" }, "usd": { "type": [ "object", "null" ], "properties": { "total": { "type": [ "string", "null" ], "description": "Including fees" }, "net": { "type": [ "string", "null" ], "description": "Before fees" } }, "required": [ "total", "net" ], "additionalProperties": false } }, "required": [ "charged", "eur", "usd" ], "additionalProperties": false, "description": "Each figure in a fixed currency; null when the provider did not state it" }, "crypto": { "type": [ "object", "null" ], "properties": { "asset": { "type": "string" }, "network": { "type": "string" }, "amount": { "type": "string" } }, "required": [ "asset", "network", "amount" ], "additionalProperties": false }, "account": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "deliveryAddress": { "type": [ "string", "null" ], "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "deliveryChain": { "type": [ "string", "null" ], "description": "CAIP-2 chain of the delivery, e.g. `eip155:8453`" }, "providerStatus": { "type": "string", "description": "The provider’s own status; informational" }, "createdAt": { "type": "string", "format": "date-time", "description": "When the provider says the order began" }, "updatedAt": { "type": "string", "format": "date-time" } }, "required": [ "id", "provider", "kind", "status", "terminal", "stages", "rail", "fiat", "crypto", "account", "deliveryAddress", "deliveryChain", "providerStatus", "createdAt", "updatedAt" ], "additionalProperties": false }, "OnrampReceiptStage": { "oneOf": [ { "type": "object", "properties": { "status": { "type": "string", "enum": [ "not_started" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "pending" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "on_hold" ] }, "reason": { "type": "string", "enum": [ "kyc_required", "rfi_open", "review" ] } }, "required": [ "status", "reason" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "processing" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "completed" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "failed" ] }, "reason": { "type": "string", "enum": [ "cancelled", "declined", "expired", "provider_error" ] } }, "required": [ "status", "reason" ], "additionalProperties": false } ] }, "OnrampConversionStage": { "oneOf": [ { "type": "object", "properties": { "status": { "type": "string", "enum": [ "not_started" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "processing" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "on_hold" ] }, "reason": { "type": "string", "enum": [ "rfi_open", "review" ] } }, "required": [ "status", "reason" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "completed" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "failed" ] }, "reason": { "type": "string", "enum": [ "sub_fee", "provider_error" ] } }, "required": [ "status", "reason" ], "additionalProperties": false } ] }, "OnrampDeliveryStage": { "oneOf": [ { "type": "object", "properties": { "status": { "type": "string", "enum": [ "not_started" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "pending" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "on_hold" ] }, "reason": { "type": "string", "enum": [ "rfi_open", "review" ] } }, "required": [ "status", "reason" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "submitted" ] }, "txHash": { "type": "string", "pattern": "^0x[0-9a-f]{64}$" } }, "required": [ "status", "txHash" ], "additionalProperties": false, "description": "The provider reported the transfer; not yet seen on chain" }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "completed" ] }, "txHash": { "type": "string", "pattern": "^0x[0-9a-f]{64}$" }, "depositId": { "type": "string", "description": "The deposit it landed as" } }, "required": [ "status", "txHash", "depositId" ], "additionalProperties": false, "description": "The transfer landed on chain as a deposit" }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "failed" ] }, "reason": { "type": "string", "enum": [ "sub_fee", "provider_error" ] } }, "required": [ "status", "reason" ], "additionalProperties": false } ] }, "OnrampReturnStage": { "oneOf": [ { "type": "object", "properties": { "status": { "type": "string", "enum": [ "none" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "pending" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "processing" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "completed" ] }, "outcome": { "type": "string", "enum": [ "full_refund", "adjustment", "unresolved" ] } }, "required": [ "status", "outcome" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "failed" ] } }, "required": [ "status" ], "additionalProperties": false } ] }, "OnrampOrderPage": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/OnrampOrder" } }, "nextCursor": { "type": [ "string", "null" ], "format": "uuid" } }, "required": [ "items", "nextCursor" ], "additionalProperties": false }, "OnrampOrderStarted": { "type": "object", "properties": { "orderId": { "type": "string", "format": "uuid" }, "nextAction": { "$ref": "#/components/schemas/HostedNextAction" }, "expiresAt": { "type": "string", "format": "date-time", "description": "Start the checkout before this" } }, "required": [ "orderId", "nextAction", "expiresAt" ], "additionalProperties": false }, "HostedNextAction": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "hosted" ] }, "url": { "type": "string" }, "presentation": { "type": "string", "enum": [ "iframe" ] } }, "required": [ "type", "url", "presentation" ], "additionalProperties": false }, "CreateOnrampOrderRequest": { "oneOf": [ { "$ref": "#/components/schemas/SwappedFiatOrderRequest" }, { "$ref": "#/components/schemas/SwappedExchangeOrderRequest" } ], "discriminator": { "propertyName": "kind", "mapping": { "fiat": "#/components/schemas/SwappedFiatOrderRequest", "exchange": "#/components/schemas/SwappedExchangeOrderRequest" } } }, "SwappedFiatOrderRequest": { "type": "object", "properties": { "provider": { "type": "string", "enum": [ "swapped" ] }, "account": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "The registered account to fund", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "kind": { "type": "string", "enum": [ "fiat" ] }, "email": { "type": "string" }, "baseCountry": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "ISO-3166-1 alpha-2 country code", "example": "US" }, "baseCurrencyCode": { "type": "string", "pattern": "^[A-Z]{3,4}$", "description": "ISO fiat currency code", "example": "USD" }, "baseCurrencyAmount": { "type": "number", "exclusiveMinimum": 0 }, "locale": { "type": "string" }, "method": { "type": "string", "description": "Optional. Preselects a Swapped payment method (a `payment_group`) in the widget — e.g. \"creditcard\", \"apple-pay\", \"bank-transfer\", \"skrill\", \"pix\", \"google-pay\". Any Swapped-supported value is accepted and forwarded as-is; omit it to let Swapped auto-select the best method for the user based on their location and other signals. See Swapped's Get Payment Methods endpoint for the full, per-region list.", "example": "apple-pay" }, "methodSelectionSource": { "type": "string", "enum": [ "personalized", "fallback", "configured" ], "description": "How the caller obtained `method`. Use `personalized` only for a method rendered from the regional payment-method response; with a trusted `x-user-country`, this opts into strict catalog validation. `fallback`, `configured`, and omission preserve the legacy exact-method pass-through behavior.", "example": "personalized" } }, "required": [ "provider", "account", "kind" ], "additionalProperties": false }, "SwappedExchangeOrderRequest": { "type": "object", "properties": { "provider": { "type": "string", "enum": [ "swapped" ] }, "account": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "The registered account to fund", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "kind": { "type": "string", "enum": [ "exchange" ] }, "baseCountry": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "ISO-3166-1 alpha-2 country code", "example": "US" }, "baseCurrencyCode": { "type": "string", "pattern": "^[A-Z]{3,4}$", "description": "ISO fiat currency code", "example": "USD" }, "locale": { "type": "string" }, "connection": { "type": "string" }, "connections": { "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 64 }, "minItems": 1, "maxItems": 26, "example": [ "coinbase", "kraken" ] }, "merchantName": { "type": "string", "maxLength": 64, "description": "Optional. Overrides the merchant name Swapped Connect shows on its confirm screen — both the \"To:\" row and its tooltip (\"Funds will be delivered to your wallet.\"). Omit it to inherit the Rhinestone default. Send it raw; the service URL-encodes it.", "example": "Superform" }, "merchantLogoUrl": { "type": "string", "maxLength": 2048, "format": "uri", "description": "Optional. Publicly accessible HTTPS URL of the merchant's logo, shown beside `merchantName` on the Swapped Connect confirm screen. PNG or SVG recommended. Send it raw; the service URL-encodes it.", "example": "https://cdn.example.com/logo.svg" } }, "required": [ "provider", "account", "kind" ], "additionalProperties": false }, "OnrampOptions": { "anyOf": [ { "type": "object", "properties": { "provider": { "type": "string", "enum": [ "swapped" ] }, "kind": { "type": "string", "enum": [ "fiat" ] }, "country": { "type": [ "string", "null" ], "pattern": "^[A-Z]{2}$", "description": "Null when the country or catalogue is unknown; fall back to your own defaults", "example": "US" }, "methods": { "type": "array", "items": { "type": "object", "properties": { "method": { "type": "string" }, "label": { "type": "string" }, "iconUrl": { "type": [ "string", "null" ] }, "iconUrlLight": { "type": [ "string", "null" ] }, "minAmount": { "type": [ "number", "null" ], "minimum": 0, "description": "Smallest order, in EUR whatever the customer pays in" }, "maxAmount": { "type": [ "number", "null" ], "minimum": 0, "description": "Largest order, in EUR whatever the customer pays in" }, "currencies": { "type": "array", "items": { "type": "string", "minLength": 3, "maxLength": 3 }, "description": "ISO 4217 fiat currencies the customer can pay this method in, in this country. Empty when Swapped states none", "example": [ "EUR", "USD", "GBP" ] }, "badge": { "type": [ "string", "null" ], "enum": [ "Popular" ] } }, "required": [ "method", "label", "iconUrl", "iconUrlLight", "minAmount", "maxAmount", "currencies", "badge" ] }, "description": "Curated: the deposit modal’s rows (regional Popular pick, card, bank transfer, Apple Pay)" }, "otherMethods": { "type": "array", "items": { "type": "object", "properties": { "method": { "type": "string" }, "label": { "type": "string" }, "iconUrl": { "type": [ "string", "null" ] }, "iconUrlLight": { "type": [ "string", "null" ] }, "minAmount": { "type": [ "number", "null" ], "minimum": 0, "description": "Smallest order, in EUR whatever the customer pays in" }, "maxAmount": { "type": [ "number", "null" ], "minimum": 0, "description": "Largest order, in EUR whatever the customer pays in" }, "currencies": { "type": "array", "items": { "type": "string", "minLength": 3, "maxLength": 3 }, "description": "ISO 4217 fiat currencies the customer can pay this method in, in this country. Empty when Swapped states none", "example": [ "EUR", "USD", "GBP" ] }, "badge": { "type": [ "string", "null" ], "enum": [ "Popular" ] } }, "required": [ "method", "label", "iconUrl", "iconUrlLight", "minAmount", "maxAmount", "currencies", "badge" ] }, "description": "Every other method Swapped offers in the country, in its order; pass any as `method` on `POST /onramp/orders`" }, "recommendedMethod": { "type": [ "string", "null" ] } }, "required": [ "provider", "kind", "country", "methods", "otherMethods", "recommendedMethod" ], "additionalProperties": false }, { "type": "object", "properties": { "provider": { "type": "string", "enum": [ "swapped" ] }, "kind": { "type": "string", "enum": [ "exchange" ] }, "connections": { "type": "array", "items": { "type": "object", "properties": { "connection": { "type": "string" }, "name": { "type": "string" }, "logoUrl": { "type": [ "string", "null" ], "description": "HTTPS image URL supplied by Swapped Connect. Prefers the dark icon, then the light icon, then logo variants. Null when Swapped supplies no usable image or its metadata is unavailable. Image format and URL lifetime are provider-controlled.", "example": "https://d25djvj7a3w11u.cloudfront.net/coinbase-icon.svg" }, "kind": { "type": "string", "enum": [ "exchange", "wallet" ], "example": "exchange" }, "appHandoff": { "type": "string", "enum": [ "none", "https_link", "custom_scheme" ], "example": "none" } }, "required": [ "connection", "name", "logoUrl", "kind", "appHandoff" ] } } }, "required": [ "provider", "kind", "connections" ], "additionalProperties": false }, { "type": "object", "properties": { "provider": { "type": "string", "enum": [ "noah" ] }, "options": { "type": "array", "items": { "type": "object", "properties": { "optionId": { "type": "string", "format": "uuid" }, "currency": { "type": "string", "enum": [ "EUR", "USD" ], "description": "Supported ISO 4217 fiat currency" } }, "required": [ "optionId", "currency" ], "additionalProperties": false } } }, "required": [ "provider", "options" ], "additionalProperties": false, "description": "Bank-transfer accounts the customer may set up; pass one to `POST /onramp/accounts`" } ] }, "OnrampAccountCreated": { "type": "object", "properties": { "account": { "$ref": "#/components/schemas/OnrampAccount" } }, "required": [ "account" ], "additionalProperties": false }, "OnrampAccount": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "currency": { "type": "string", "enum": [ "EUR", "USD" ], "description": "Supported ISO 4217 fiat currency" }, "status": { "type": "string", "enum": [ "pending", "active", "disabled" ] } }, "required": [ "id", "currency", "status" ], "additionalProperties": false }, "CreateOnrampAccountRequest": { "type": "object", "properties": { "provider": { "type": "string", "enum": [ "noah" ] }, "currency": { "type": "string", "enum": [ "EUR", "USD" ], "description": "Supported ISO 4217 fiat currency" }, "optionId": { "type": "string", "format": "uuid", "description": "From `GET /onramp/options?provider=noah`; any matching option without" } }, "required": [ "provider", "currency" ], "additionalProperties": false }, "OnrampAccountPage": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/OnrampAccount" } }, "nextCursor": { "type": [ "string", "null" ], "format": "uuid" } }, "required": [ "items", "nextCursor" ], "additionalProperties": false }, "OnrampAccountDetails": { "type": "object", "properties": { "bankDetails": { "type": "object", "properties": { "schemaVersion": { "type": "number", "enum": [ 1 ] }, "capturedAt": { "type": "string", "format": "date-time" }, "currency": { "type": "string", "enum": [ "USD", "EUR" ] }, "accountHolderName": { "type": "string", "minLength": 1 }, "bankName": { "type": "string", "minLength": 1 }, "bankAddress": { "type": "object", "properties": { "street": { "type": "string", "minLength": 1 }, "street2": { "type": "string", "minLength": 1 }, "city": { "type": "string", "minLength": 1 }, "postCode": { "type": "string", "minLength": 1 }, "state": { "type": "string", "minLength": 1 }, "country": { "type": "string", "pattern": "^[A-Z]{2}$" } }, "required": [ "street", "city", "postCode", "state", "country" ], "additionalProperties": false }, "reference": { "type": "string", "minLength": 1 }, "rails": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "BankAch", "BankFedwire", "BankSwift", "BankSepa" ] }, "accountNumber": { "type": "string", "minLength": 1 }, "bankCode": { "type": "string", "minLength": 1 }, "fee": { "type": "object", "properties": { "currency": { "type": "string", "enum": [ "USD", "EUR" ] }, "base": { "type": "string", "maxLength": 38, "pattern": "^\\+?(?:\\d+(?:\\.\\d*)?|\\.\\d+)$" }, "percent": { "type": "string", "maxLength": 38, "pattern": "^\\+?(?:\\d+(?:\\.\\d*)?|\\.\\d+)$" }, "minimum": { "type": "string", "maxLength": 38, "pattern": "^\\+?(?:\\d+(?:\\.\\d*)?|\\.\\d+)$" } }, "required": [ "currency", "base", "percent", "minimum" ], "additionalProperties": false } }, "required": [ "type", "accountNumber", "bankCode", "fee" ], "additionalProperties": false }, "minItems": 1 } }, "required": [ "schemaVersion", "capturedAt", "currency", "accountHolderName", "rails" ], "additionalProperties": false } }, "required": [ "bankDetails" ], "additionalProperties": false }, "OfframpOptions": { "type": "object", "properties": { "methods": { "type": "array", "items": { "$ref": "#/components/schemas/PayoutMethod" } } }, "required": [ "methods" ], "additionalProperties": false }, "PayoutMethod": { "type": "object", "properties": { "methodId": { "type": "string", "format": "uuid", "description": "Opaque; pass it back to open an order" }, "rail": { "type": "string", "enum": [ "ach", "wire", "sepa", "swift", "faster_payments", "pix" ] }, "accountType": { "type": "string", "enum": [ "us", "iban", "swift", "gb", "pix" ], "description": "Which beneficiary details this method needs" }, "currency": { "type": "string", "example": "USD" }, "country": { "type": [ "string", "null" ], "description": "ISO 3166-1 alpha-2 of the receiving bank; null for international", "example": "US" }, "limits": { "type": "object", "properties": { "min": { "type": [ "string", "null" ] }, "max": { "type": [ "string", "null" ] } }, "required": [ "min", "max" ] }, "etaSeconds": { "type": [ "integer", "null" ], "description": "Typical time to the bank, in seconds" } }, "required": [ "methodId", "rail", "accountType", "currency", "country", "limits", "etaSeconds" ], "additionalProperties": false }, "OfframpOrderCreated": { "type": "object", "properties": { "order": { "$ref": "#/components/schemas/OfframpOrder" }, "estimate": { "type": "object", "properties": { "fiatAmount": { "type": [ "string", "null" ], "description": "What the bank receives, after every fee" }, "currency": { "type": "string" }, "totalFee": { "type": [ "string", "null" ] }, "rate": { "type": [ "string", "null" ] } }, "required": [ "fiatAmount", "currency", "totalFee", "rate" ], "additionalProperties": false, "description": "Priced on the requested amount" } }, "required": [ "order", "estimate" ], "additionalProperties": false }, "OfframpOrder": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "provider": { "type": "string", "enum": [ "noah", "swapped" ] }, "status": { "type": "string", "enum": [ "pending", "processing", "completed", "failed", "refunded" ] }, "terminal": { "type": "boolean", "description": "No stage will change again" }, "stages": { "type": "object", "properties": { "receipt": { "$ref": "#/components/schemas/OnrampReceiptStage" }, "conversion": { "$ref": "#/components/schemas/OnrampConversionStage" }, "delivery": { "$ref": "#/components/schemas/OfframpPayoutStage" }, "return": { "$ref": "#/components/schemas/OnrampReturnStage" } }, "required": [ "receipt", "conversion", "delivery", "return" ], "additionalProperties": false }, "rail": { "oneOf": [ { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "fiat" ] }, "method": { "type": "string" } }, "required": [ "kind", "method" ], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "exchange" ] }, "connection": { "type": "string" } }, "required": [ "kind", "connection" ], "additionalProperties": false } ], "description": "`provider_selected` / `unknown` when the provider did not say" }, "fiat": { "type": "object", "properties": { "charged": { "type": [ "object", "null" ], "properties": { "total": { "type": [ "string", "null" ], "description": "The sale, fees included; null when not stated" }, "net": { "type": [ "string", "null" ], "description": "What the bank receives, after fees" }, "currency": { "type": "string" } }, "required": [ "total", "net", "currency" ], "additionalProperties": false, "description": "The payout, in the currency the bank receives" }, "eur": { "type": [ "object", "null" ], "properties": { "total": { "type": [ "string", "null" ], "description": "The sale, fees included; null when not stated" }, "net": { "type": [ "string", "null" ], "description": "What the bank receives, after fees" } }, "required": [ "total", "net" ], "additionalProperties": false }, "usd": { "type": [ "object", "null" ], "properties": { "total": { "type": [ "string", "null" ], "description": "The sale, fees included; null when not stated" }, "net": { "type": [ "string", "null" ], "description": "What the bank receives, after fees" } }, "required": [ "total", "net" ], "additionalProperties": false } }, "required": [ "charged", "eur", "usd" ], "additionalProperties": false, "description": "What the bank receives, after fees; null until the provider states it" }, "crypto": { "type": [ "object", "null" ], "properties": { "asset": { "type": "string" }, "network": { "type": "string" }, "amount": { "type": "string" } }, "required": [ "asset", "network", "amount" ], "additionalProperties": false }, "providerStatus": { "type": "string", "description": "The provider’s own status of its latest leg, else ours (`reserved`, `opened`, `refused`, `unknown`, `expired`); informational" }, "createdAt": { "type": "string", "format": "date-time", "description": "When the provider says the order began" }, "updatedAt": { "type": "string", "format": "date-time" }, "sender": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "The address the provider takes the crypto from: `source.address`, or the withdrawal account it pays into", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "payment": { "anyOf": [ { "$ref": "#/components/schemas/OfframpPayment" }, { "type": "null" } ], "description": "Null until the provider’s rule exists: while it is being created, or when the rule was refused or its outcome is unknown; through a withdrawal account, also until its funding is configured. A `direct` payment is still served after `expiresAt`, until the order expires 30 minutes later and reads `failed` (`expired`), not terminal: the provider may still match a late transfer. A `withdrawal_account` payment is null again once a transfer can no longer fund the order: one already did, the order moved past `pending`, or 30 minutes passed after `expiresAt`." }, "expiresAt": { "type": "string", "format": "date-time", "description": "Send the payment before this" } }, "required": [ "id", "provider", "status", "terminal", "stages", "rail", "fiat", "crypto", "providerStatus", "createdAt", "updatedAt", "sender", "payment", "expiresAt" ], "additionalProperties": false }, "OfframpPayoutStage": { "oneOf": [ { "type": "object", "properties": { "status": { "type": "string", "enum": [ "not_started" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "pending" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "on_hold" ] }, "reason": { "type": "string", "enum": [ "rfi_open", "review" ] } }, "required": [ "status", "reason" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "processing" ] } }, "required": [ "status" ], "additionalProperties": false }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "submitted" ] } }, "required": [ "status" ], "additionalProperties": false, "description": "The provider sent the payment to the bank" }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "completed" ] } }, "required": [ "status" ], "additionalProperties": false, "description": "The bank accepted the payment" }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "failed" ] }, "reason": { "type": "string", "enum": [ "sub_fee", "provider_error" ], "description": "`sub_fee`: the fees took the whole amount" } }, "required": [ "status", "reason" ], "additionalProperties": false } ], "description": "The fiat payout to the bank" }, "OfframpPayment": { "oneOf": [ { "$ref": "#/components/schemas/OfframpDirectPayment" }, { "$ref": "#/components/schemas/OfframpWithdrawalAccountPayment" } ], "discriminator": { "propertyName": "kind", "mapping": { "direct": "#/components/schemas/OfframpDirectPayment", "withdrawal_account": "#/components/schemas/OfframpWithdrawalAccountPayment" } }, "description": "How to pay the order, by `kind`: `direct` from a source on the provider’s chain and token, `withdrawal_account` from any other" }, "OfframpDirectPayment": { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "direct" ] }, "from": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "The sender: an EOA, or the smart account executing the transfer", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "to": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "chain": { "type": "string", "description": "CAIP-2" }, "token": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "amount": { "type": "string", "pattern": "^\\d+$", "description": "Exact, in base units of `token`: the value of the ERC-20 transfer", "example": "100000000" } }, "required": [ "kind", "from", "to", "chain", "token", "amount" ], "additionalProperties": false, "description": "Send exactly `amount` of `token` on `chain` from `from` to `to`, as a direct ERC-20 transfer whose sender is `from` (an EOA, or the smart account executing it). A different amount or sender is not matched and stays with the provider until recovery." }, "OfframpWithdrawalAccountPayment": { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "withdrawal_account" ] }, "from": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "`source.address`: an EOA, or the smart account executing the transfer", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "to": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "The customer’s withdrawal account", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "chain": { "type": "string", "description": "CAIP-2: `source.chain`" }, "token": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "`source.token`", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "amount": { "type": "string", "pattern": "^\\d+$", "description": "Exact, in base units of `token`: the value of the transfer. Quoted to deliver the order’s amount of the provider’s token on the cheapest route, plus a margin for the fees the customer pays (or, for another asset, 1% for its price); may be a few base units higher when another open withdrawal from this source holds it", "example": "100000000" } }, "required": [ "kind", "from", "to", "chain", "token", "amount" ], "additionalProperties": false, "description": "Send exactly `amount` of `token` on `chain` from `from` to `to`, the customer’s withdrawal account, after the order opens and before `expiresAt`; we pay the provider from it, and what the payment does not spend stays there for an operator. A different amount or sender, or a transfer mined more than 30 minutes after `expiresAt`, is not matched: it stays on the account until an operator refunds it." }, "OfframpError": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION", "UNKNOWN_METHOD", "AMOUNT_TOO_SMALL", "INVALID_BENEFICIARY", "SOURCE_NOT_SUPPORTED", "NO_ROUTE", "QUOTE_UNAVAILABLE", "TOO_MANY_OPEN_WITHDRAWALS", "OUTCOME_UNKNOWN", "FUNDING_NOT_CONFIGURED" ] }, "providerError": { "$ref": "#/components/schemas/ProviderError" }, "orderId": { "type": "string", "format": "uuid", "description": "Set once the order exists, whatever failed after: read it at GET /offramp/orders/{id}" }, "fields": { "type": "array", "items": { "type": "string" }, "description": "INVALID_BENEFICIARY: our beneficiary paths, e.g. `account.iban`" }, "estimate": { "type": "object", "properties": { "totalFee": { "type": [ "string", "null" ] }, "currency": { "type": "string" } }, "required": [ "totalFee", "currency" ], "description": "AMOUNT_TOO_SMALL: the fees that exceed the amount" } }, "required": [ "error" ] }, "CreateOfframpOrder": { "type": "object", "properties": { "methodId": { "type": "string", "format": "uuid", "description": "From GET /offramp/options" }, "beneficiary": { "$ref": "#/components/schemas/Beneficiary" }, "amount": { "type": "string", "pattern": "^\\d+$", "description": "In base units of the token the provider takes: what the payout is priced on and the provider receives, exactly. From `source.token` itself, the ERC-20 transfer’s value; from any other source, `order.payment.amount` is quoted from it", "example": "100000000" }, "source": { "type": "object", "properties": { "address": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Sends the transfer: an EOA, or the smart account executing it", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "chain": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "token": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" } }, "required": [ "address", "chain", "token" ], "additionalProperties": false, "description": "Where the crypto comes from" } }, "required": [ "methodId", "beneficiary", "amount", "source" ], "additionalProperties": false }, "Beneficiary": { "type": "object", "properties": { "holder": { "oneOf": [ { "type": "object", "properties": { "type": { "type": "string", "enum": [ "individual" ] }, "firstName": { "type": "string", "minLength": 1, "maxLength": 100 }, "lastName": { "type": "string", "minLength": 1, "maxLength": 100 } }, "required": [ "type", "firstName", "lastName" ], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": [ "business" ] }, "name": { "type": "string", "minLength": 1, "maxLength": 200 } }, "required": [ "type", "name" ], "additionalProperties": false } ] }, "address": { "type": "object", "properties": { "line1": { "type": "string", "minLength": 1, "maxLength": 200 }, "city": { "type": "string", "minLength": 1, "maxLength": 100 }, "state": { "type": "string", "minLength": 1, "maxLength": 100 }, "postalCode": { "type": "string", "minLength": 1, "maxLength": 20 }, "country": { "type": "string", "pattern": "^[A-Z]{2}$" } }, "required": [ "line1", "city", "state", "postalCode", "country" ], "additionalProperties": false, "description": "Required by US and SWIFT accounts" }, "account": { "oneOf": [ { "type": "object", "properties": { "type": { "type": "string", "enum": [ "us" ] }, "routingNumber": { "type": "string", "pattern": "^\\d{9}$" }, "accountNumber": { "type": "string", "minLength": 1, "maxLength": 34 }, "accountType": { "type": "string", "enum": [ "checking", "savings" ] } }, "required": [ "type", "routingNumber", "accountNumber", "accountType" ], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": [ "iban" ] }, "iban": { "type": "string", "minLength": 1, "maxLength": 34 } }, "required": [ "type", "iban" ], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": [ "swift" ] }, "swiftCode": { "type": "string", "pattern": "^[A-Z0-9]{8}([A-Z0-9]{3})?$" }, "accountNumber": { "type": "string", "minLength": 1, "maxLength": 34 }, "accountType": { "type": "string", "enum": [ "checking", "savings" ] } }, "required": [ "type", "swiftCode", "accountNumber", "accountType" ], "additionalProperties": false } ] }, "reference": { "type": "string", "minLength": 1, "maxLength": 140, "description": "Shown on the bank statement; defaults to \"Withdrawal\"" } }, "required": [ "holder", "account" ], "additionalProperties": false, "description": "The bank account to pay. Passed to the provider only: never stored or logged." }, "OfframpOrderPage": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/OfframpOrder" } }, "nextCursor": { "type": [ "string", "null" ], "format": "uuid" } }, "required": [ "items", "nextCursor" ], "additionalProperties": false } }, "parameters": {} }, "paths": { "/analytics/events": { "post": { "tags": [ "Analytics" ], "summary": "Record analytics events", "description": "Stores a batch of browser analytics events.", "security": [ { "analyticsIngestBearer": [] }, {} ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AnalyticsEventsRequest" } } } }, "responses": { "200": { "description": "The complete batch is durably represented", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AnalyticsEventsResponse" } } } }, "400": { "description": "Malformed or invalid batch", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "A presented credential is invalid or not permitted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Session attribution, envelope, event ID, or sequence conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AnalyticsConflictResponse" } } } }, "503": { "description": "Analytics persistence is temporarily unavailable", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/analytics/ingest-token": { "post": { "tags": [ "Analytics" ], "summary": "Create an analytics token", "description": "Creates a token for submitting analytics events, valid for five minutes.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "responses": { "200": { "description": "Analytics ingest token and its expiry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AnalyticsIngestTokenResponse" } } } }, "401": { "description": "Missing or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "The authenticated project is not permitted or is not billable.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/assets": { "get": { "tags": [ "Utilities" ], "summary": "Get asset metadata", "description": "Authenticated asset lookup. GET accepts required ids and fields as comma-separated or repeated query parameters; at most 100 IDs before deduplication. Supported fields: name, symbol, decimals, price, logo. QUERY /assets is also supported (not representable as an OpenAPI 3.1 operation): send application/json {\"ids\":[\"eip155:1:native\"],\"fields\":[\"symbol\",\"price\"]}, at most 100 IDs and a 64 KiB body. Both methods return exact submitted ID keys, omit unrequested fields and use null for unresolved requested fields; item errors remain HTTP 200. An invalid request returns 400 with {\"error\":{\"code\":\"invalid_request\",\"message\":\"...\"}}.", "parameters": [ { "schema": { "type": "string", "description": "Required comma-separated asset IDs (or repeated ids); at most 100 submitted IDs", "example": "eip155:1:native" }, "required": true, "description": "Required comma-separated asset IDs (or repeated ids); at most 100 submitted IDs", "name": "ids", "in": "query" }, { "schema": { "type": "string", "description": "Required comma-separated fields (or repeated fields): name,symbol,decimals,price,logo", "example": "symbol,price" }, "required": true, "description": "Required comma-separated fields (or repeated fields): name,symbol,decimals,price,logo", "name": "fields", "in": "query" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "responses": { "200": { "description": "Requested asset fields keyed by exact submitted ID", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AssetsResponse" } } } }, "400": { "description": "Invalid asset request (or invalid API key)", "content": { "application/json": { "schema": { "anyOf": [ { "$ref": "#/components/schemas/AssetsError" }, { "$ref": "#/components/schemas/AssetsAuthError" } ] } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Organization is not billable", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AssetsAuthError" } } } }, "502": { "description": "Asset upstream unavailable", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AssetsError" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/chains": { "get": { "tags": [ "Utilities" ], "summary": "List supported chains and tokens", "description": "Returns supported chains and tokens with their deposit and destination availability.", "responses": { "200": { "description": "Supported chains with their tokens", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChainsResponse" } } } } } } }, "/check/{address}": { "get": { "tags": [ "Accounts" ], "summary": "Check account registration", "description": "Returns whether an account is registered and its target chain and token.", "parameters": [ { "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "required": true, "description": "Ethereum address (0x followed by 40 hex characters)", "name": "address", "in": "path" } ], "responses": { "200": { "description": "Account registration status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckResponse" } } } }, "400": { "description": "Invalid address format", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "422": { "description": "Account was registered with a factory the service does not support", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UnsupportedFactoryResponse" } } } } } } }, "/setup": { "post": { "tags": [ "Clients" ], "summary": "Update client settings", "description": "Updates client configuration for the authenticated project. Requires the deposits:admin API key scope.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetupRequestBody" } } } }, "responses": { "200": { "description": "Client updated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetupResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required, or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks the required deposits:admin scope, or the organization can't be billed (no card or approved contract, or suspended)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Client configuration could not be persisted, or the organization's fee configuration could not be read; retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] }, "get": { "tags": [ "Clients" ], "summary": "Get client settings", "description": "Returns the stored client configuration for the authenticated project.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "responses": { "200": { "description": "Client configuration", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetSetupResponse" } } } }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/register": { "post": { "tags": [ "Accounts" ], "summary": "Register an account", "description": "Registers a smart account for deposits. Registration is idempotent for the registered project and destination: an existing address cannot be reassigned to another project, account kind, chain, token, or recipient. To change destination, derive and register a new address. User-owned registration is limited to enabled organizations; others register managed accounts with `POST /register-managed`.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegisterRequestBody" } } } }, "responses": { "200": { "description": "Account registered successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegisterResponse" } } } }, "400": { "description": "Invalid account data or unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope, the organization can't be billed, or user-owned accounts are not enabled for the organization (`USER_OWNED_ACCOUNTS_NOT_ENABLED`; use `POST /register-managed`)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "The address is already registered to a different project, account kind, or destination. Use a new address for a new destination.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "429": { "description": "Retryable refusal; retry after the Retry-After delay. Registration is idempotent, so a retry reuses whatever was already stored. `WEBHOOK_ENROLLMENT_UNAVAILABLE`: no webhook provider could enroll the deposit address. `REGISTRATION_BUSY`: too many registrations are in flight; the request waited briefly for a slot and none freed. `REGISTRATION_IN_PROGRESS`: another request is registering the same account or salt.", "headers": { "Retry-After": { "description": "Seconds to wait before retrying", "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "The session scope could not be verified; nothing was stored. Retry after the number of seconds in the Retry-After header.", "headers": { "Retry-After": { "description": "Seconds to wait before retrying the registration", "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/account/{address}/deposit-addresses": { "post": { "tags": [ "Accounts" ], "summary": "Provision deposit addresses", "description": "Returns deposit addresses for a registered account, creating missing addresses as needed. It never changes the account owner or destination.", "parameters": [ { "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "required": true, "description": "Ethereum address (0x followed by 40 hex characters)", "name": "address", "in": "path" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "responses": { "200": { "description": "Deposit addresses for the account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DepositAddressesResponse" } } } }, "400": { "description": "Invalid API key or address", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Unauthorized - API key does not belong to the client that registered the account, or the organization can't be billed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Account not registered", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "The account and its existing deposit-address mapping disagree on owner or destination. Use a new address; this endpoint will not repair or overwrite the mapping.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "429": { "description": "Retryable refusal; retry after the Retry-After delay. Registration is idempotent, so a retry reuses whatever was already stored. `WEBHOOK_ENROLLMENT_UNAVAILABLE`: no webhook provider could enroll the deposit address. `REGISTRATION_BUSY`: too many registrations are in flight; the request waited briefly for a slot and none freed. `REGISTRATION_IN_PROGRESS`: another request is registering the same account or salt.", "headers": { "Retry-After": { "description": "Seconds to wait before retrying", "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/account/{address}/session": { "post": { "tags": [ "Accounts" ], "summary": "Add session details to account", "description": "Add session details (chain IDs, session digests, and signature) to an existing account", "parameters": [ { "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "required": true, "description": "Ethereum address (0x followed by 40 hex characters)", "name": "address", "in": "path" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SessionRequestBody" } } } }, "responses": { "200": { "description": "Session added successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SessionResponse" } } } }, "400": { "description": "Invalid request or account not registered", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Unauthorized - API key does not belong to the client that registered the account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "429": { "description": "Retryable refusal; nothing was stored. Retry after the Retry-After delay. `REGISTRATION_BUSY`: too many registrations are in flight; the request waited briefly for a slot and none freed. `REGISTRATION_IN_PROGRESS`: another request is registering the same account or salt.", "headers": { "Retry-After": { "description": "Seconds to wait before retrying", "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "For a scoped account, the submitted digests could not be verified against the stored scope right now. Nothing was stored; retry.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/account/{address}/token-accounts": { "post": { "tags": [ "Accounts" ], "summary": "Provision a Solana token account", "description": "Creates a token account for a registered account’s Solana deposit address, or returns the existing one.", "parameters": [ { "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "required": true, "description": "Ethereum address (0x followed by 40 hex characters)", "name": "address", "in": "path" }, { "schema": { "type": "string", "enum": [ "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1" ], "description": "Solana source network; defaults to mainnet when omitted", "example": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1" }, "required": false, "description": "Solana source network; defaults to mainnet when omitted", "name": "chain", "in": "query" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TokenAccountRequestBody" } } } }, "responses": { "200": { "description": "Token account exists (created now or previously)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TokenAccountResponse" } } } }, "400": { "description": "Invalid mint (bad base58, unsupported token, or SOL/WSOL)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Missing or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Organization not in the allowlist, lacks deposits:write scope, or the account is owned by a different project", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "No Solana account registered for this address", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "502": { "description": "Solana RPC or transaction submission failure", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/deposits/{id}/retry": { "post": { "tags": [ "Processing" ], "summary": "Retry a deposit", "description": "Retries a failed or rejected deposit.", "parameters": [ { "schema": { "type": "string", "pattern": "^\\d+$", "description": "Deposit id. Returned by GET /deposits.", "example": "12345" }, "required": true, "description": "Deposit id. Returned by GET /deposits.", "name": "id", "in": "path" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RetryDepositByIdRequestBody" } } } }, "responses": { "200": { "description": "Deposit retry initiated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RetryDepositByIdResponse" } } } }, "400": { "description": "Deposit not in a retryable state, a Tron deposit, settlement-layer override given for a non-EVM deposit, or the Solana deposit has no output-token route", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or invalid", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Unauthorized - API key lacks write scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Deposit not found or not owned by the caller", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "HyperCore leg 1 already completed (Core funds swept to HyperEVM) — a leg-2 refund/fill concern, not a leg-1 retry; or an earlier EVM intent of this deposit may still be settling or already moved its funds (reconcile instead)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Settlement evidence is temporarily unreadable; retry later (see Retry-After)", "headers": { "Retry-After": { "description": "Seconds to wait before retrying", "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/deposits/{id}/refund": { "post": { "tags": [ "Processing" ], "summary": "Refund a deposit", "description": "Returns deposit funds to a specified address on the source chain.", "parameters": [ { "schema": { "type": "string", "pattern": "^\\d+$", "description": "Deposit id. Returned by GET /deposits.", "example": "12345" }, "required": true, "description": "Deposit id. Returned by GET /deposits.", "name": "id", "in": "path" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RefundDepositByIdRequestBody" } } } }, "responses": { "200": { "description": "Deposit refunded successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RefundDepositResponse" } } } }, "400": { "description": "Invalid deposit id or recipient, or deposit not eligible for refund", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or invalid", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Unauthorized - credential does not belong to the client that registered the account, or API key lacks write scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Deposit not found or not owned by the caller", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "An earlier Solana or EVM submission of this deposit may still be settling or already moved its funds; refund refused until reconciled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Refund transfer failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Settlement evidence for a Solana or EVM deposit is unavailable; retry later (see Retry-After)", "headers": { "Retry-After": { "description": "Seconds to wait before retrying", "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/deposits/recover": { "post": { "tags": [ "Processing" ], "summary": "Recover a deposit", "description": "Returns funds from a failed or rejected deposit.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RecoverDepositRequestBody" } } } }, "responses": { "200": { "description": "Deposit recovered; funds returned on the source chain", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RefundDepositResponse" } } } }, "400": { "description": "Deposit not recoverable (DEPOSIT_NOT_RECOVERABLE) or unsupported for signed recovery (RECOVERY_UNSUPPORTED)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RecoverDepositErrorResponse" } } } }, "401": { "description": "Authentication required or invalid", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks the deposits:write scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "The refund may have been submitted and is held for reconciliation (REFUND_RECONCILIATION_REQUIRED), or an earlier bridge intent of this deposit may still be settling or already moved its funds (SETTLEMENT_UNRESOLVED); reconcile instead of re-signing", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RecoverDepositErrorResponse" } } } }, "422": { "description": "The signature does not authorize this recovery (SIGNATURE_INVALID)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RecoverDepositErrorResponse" } } } }, "500": { "description": "Recovery transfer failed (REFUND_FAILED)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RecoverDepositErrorResponse" } } } }, "503": { "description": "Smart-account signature verification is temporarily unavailable (VERIFICATION_UNAVAILABLE), or settlement evidence is unreadable (REFUND_UNAVAILABLE); retry the same signature (see Retry-After)", "headers": { "Retry-After": { "description": "Seconds to wait before retrying", "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RecoverDepositErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/deposits": { "get": { "tags": [ "Utilities" ], "summary": "List deposits", "description": "Returns deposits for the authenticated project, newest first. Filters narrow the list on the server before pagination: different parameters combine with AND, values within one parameter with OR, and an exclusion (`excludeStatus`, `excludeChain`, `excludeAsset`, `excludeSender`) wins over a matching inclusion.", "parameters": [ { "schema": { "type": "string", "description": "EVM address (0x...) or Solana base58 public key", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "required": false, "description": "EVM address (0x...) or Solana base58 public key", "name": "account", "in": "query" }, { "schema": { "type": "string", "description": "Filter by the account's recipient address. Aggregates deposits across every smart account that resolves to the same recipient (typically the integrator's user wallet).", "example": "0x2ca6f15be9580c4f332656bedc11c35bf820d08d" }, "required": false, "description": "Filter by the account's recipient address. Aggregates deposits across every smart account that resolves to the same recipient (typically the integrator's user wallet).", "name": "recipient", "in": "query" }, { "schema": { "type": "string", "description": "Filter by the source-chain deposit address or target-chain recipient.", "example": "0x2ca6f15be9580c4f332656bedc11c35bf820d08d" }, "required": false, "description": "Filter by the source-chain deposit address or target-chain recipient.", "name": "address", "in": "query" }, { "schema": { "type": "array", "items": { "type": "string", "enum": [ "pending", "processing", "completed", "failed", "rejected", "ignored", "expecting_refund", "refunded", "delayed", "reconciliation_required" ] }, "minItems": 1, "maxItems": 20, "description": "Include only deposits in these statuses. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "example": [ "failed", "rejected" ] }, "required": false, "description": "Include only deposits in these statuses. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "name": "status", "in": "query" }, { "schema": { "type": "array", "items": { "type": "string", "enum": [ "pending", "processing", "completed", "failed", "rejected", "ignored", "expecting_refund", "refunded", "delayed", "reconciliation_required" ] }, "minItems": 1, "maxItems": 20, "description": "Exclude deposits in these statuses. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "example": [ "failed", "rejected" ] }, "required": false, "description": "Exclude deposits in these statuses. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "name": "excludeStatus", "in": "query" }, { "schema": { "type": "array", "items": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "minItems": 1, "maxItems": 20, "description": "Include only deposits from these source chains. Canonical CAIP-2 source chain ids (e.g. \"eip155:8453\"). The two HyperCore origin spellings (`hypercore:mainnet`, `hypercore:spot`) match as one chain. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "example": [ "eip155:8453", "eip155:9745" ] }, "required": false, "description": "Include only deposits from these source chains. Canonical CAIP-2 source chain ids (e.g. \"eip155:8453\"). The two HyperCore origin spellings (`hypercore:mainnet`, `hypercore:spot`) match as one chain. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "name": "chain", "in": "query" }, { "schema": { "type": "array", "items": { "type": "string", "pattern": "^[a-z0-9]+:[a-zA-Z0-9]+$", "description": "CAIP-2 chain identifier (e.g. \"eip155:8453\")", "example": "eip155:8453" }, "minItems": 1, "maxItems": 20, "description": "Exclude deposits from these source chains. Canonical CAIP-2 source chain ids (e.g. \"eip155:8453\"). The two HyperCore origin spellings (`hypercore:mainnet`, `hypercore:spot`) match as one chain. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "example": [ "eip155:8453", "eip155:9745" ] }, "required": false, "description": "Exclude deposits from these source chains. Canonical CAIP-2 source chain ids (e.g. \"eip155:8453\"). The two HyperCore origin spellings (`hypercore:mainnet`, `hypercore:spot`) match as one chain. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "name": "excludeChain", "in": "query" }, { "schema": { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 20, "description": "Include only deposits of these source assets. Source assets as `:`, using the `chain` and `token` a list row reports (the token address, or the chain's native-asset identifier: the zero address on EVM and for TRX, `11111111111111111111111111111111` on Solana). Symbols are never matched. Hex tokens (EVM, HyperCore, the TRX sentinel) match case-insensitively; base58 tokens (Solana, Tron) match exactly. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "example": [ "eip155:8453:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" ] }, "required": false, "description": "Include only deposits of these source assets. Source assets as `:`, using the `chain` and `token` a list row reports (the token address, or the chain's native-asset identifier: the zero address on EVM and for TRX, `11111111111111111111111111111111` on Solana). Symbols are never matched. Hex tokens (EVM, HyperCore, the TRX sentinel) match case-insensitively; base58 tokens (Solana, Tron) match exactly. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "name": "asset", "in": "query" }, { "schema": { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 20, "description": "Exclude deposits of these source assets. Source assets as `:`, using the `chain` and `token` a list row reports (the token address, or the chain's native-asset identifier: the zero address on EVM and for TRX, `11111111111111111111111111111111` on Solana). Symbols are never matched. Hex tokens (EVM, HyperCore, the TRX sentinel) match case-insensitively; base58 tokens (Solana, Tron) match exactly. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "example": [ "eip155:8453:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" ] }, "required": false, "description": "Exclude deposits of these source assets. Source assets as `:`, using the `chain` and `token` a list row reports (the token address, or the chain's native-asset identifier: the zero address on EVM and for TRX, `11111111111111111111111111111111` on Solana). Symbols are never matched. Hex tokens (EVM, HyperCore, the TRX sentinel) match case-insensitively; base58 tokens (Solana, Tron) match exactly. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "name": "excludeAsset", "in": "query" }, { "schema": { "type": "array", "items": { "type": "string", "description": "Address on any supported chain (EVM, Solana, Tron, or Stellar)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "minItems": 1, "maxItems": 20, "description": "Include only deposits from these senders. Recorded transfer senders, matched on any chain. Never the deposit address, account or recipient. EVM addresses match case-insensitively; base58 addresses match exactly. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "example": [ "0x742d35cc6634c0532925a3b844bc9e7595f5be91" ] }, "required": false, "description": "Include only deposits from these senders. Recorded transfer senders, matched on any chain. Never the deposit address, account or recipient. EVM addresses match case-insensitively; base58 addresses match exactly. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "name": "sender", "in": "query" }, { "schema": { "type": "array", "items": { "type": "string", "description": "Address on any supported chain (EVM, Solana, Tron, or Stellar)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "minItems": 1, "maxItems": 20, "description": "Exclude deposits from these senders. Recorded transfer senders, matched on any chain. Never the deposit address, account or recipient. EVM addresses match case-insensitively; base58 addresses match exactly. A deposit with an unknown or different sender stays visible. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "example": [ "0x742d35cc6634c0532925a3b844bc9e7595f5be91" ] }, "required": false, "description": "Exclude deposits from these senders. Recorded transfer senders, matched on any chain. Never the deposit address, account or recipient. EVM addresses match case-insensitively; base58 addresses match exactly. A deposit with an unknown or different sender stays visible. Repeat the parameter or comma-separate values, at most 20. Values within one parameter combine with OR, parameters combine with AND, and an exclusion wins over a matching inclusion. Applied before pagination; spam visibility is still governed by `includeSpam`.", "name": "excludeSender", "in": "query" }, { "schema": { "type": "string", "description": "Filter by source transaction hash (EVM 0x... or Solana base58 signature)", "example": "0xabc123..." }, "required": false, "description": "Filter by source transaction hash (EVM 0x... or Solana base58 signature)", "name": "txHash", "in": "query" }, { "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20, "description": "Maximum number of deposits to return", "example": 20 }, "required": false, "description": "Maximum number of deposits to return", "name": "limit", "in": "query" }, { "schema": { "type": "string", "pattern": "^\\d+$", "description": "Pagination cursor. Use the `nextCursor` returned by the previous page.", "example": "123" }, "required": false, "description": "Pagination cursor. Use the `nextCursor` returned by the previous page.", "name": "cursor", "in": "query" }, { "schema": { "type": "boolean", "description": "When true, include spam-flagged deposits (tokens with no known price). Defaults to false.", "example": false }, "required": false, "description": "When true, include spam-flagged deposits (tokens with no known price). Defaults to false.", "name": "includeSpam", "in": "query" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "responses": { "200": { "description": "Client deposits", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListDepositsResponse" } } } }, "400": { "description": "Invalid query or API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Missing or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/deposits/{id}": { "get": { "tags": [ "Utilities" ], "summary": "Get a deposit", "description": "Returns a deposit for the authenticated project.", "parameters": [ { "schema": { "type": "string", "pattern": "^\\d+$", "description": "Deposit id. Returned by GET /deposits.", "example": "12345" }, "required": true, "description": "Deposit id. Returned by GET /deposits.", "name": "id", "in": "path" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "responses": { "200": { "description": "The deposit", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DepositListItem" } } } }, "400": { "description": "Invalid deposit id", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required, or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Deposit not found or not owned by the caller", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/deposits/{id}/quotes": { "get": { "tags": [ "Utilities" ], "summary": "List deposit quotes", "description": "Returns quotes considered for a deposit and their outcomes.", "parameters": [ { "schema": { "type": "string", "pattern": "^\\d+$", "description": "Deposit id. Returned by GET /deposits.", "example": "12345" }, "required": true, "description": "Deposit id. Returned by GET /deposits.", "name": "id", "in": "path" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "responses": { "200": { "description": "Quotes considered for the deposit", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DepositQuotesResponse" } } } }, "400": { "description": "Invalid deposit id or API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Deposit not found or not owned by the caller", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/quotes/preview": { "post": { "tags": [ "Processing" ], "summary": "Get a deposit quote", "description": "Estimates fees, output, and completion time for a deposit.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QuotePreviewRequest" } } } }, "responses": { "200": { "description": "Indicative quote for the requested route", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QuotePreviewResponse" } } } }, "400": { "description": "Malformed request body or unsupported source chain", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Missing or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Account not found or not owned by the caller", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "422": { "description": "Route cannot be priced (the account's output-token rules map the source token to nothing, no available routes, no session to build a binding quote with on a route only the binding quote can price, or exact-out asked of such a route). A quote does not mean a deposit would be accepted: the client whitelist, session coverage and token policy are applied when the deposit arrives. Only ever a refusal, never an outage: a dependency failure answers 503.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "`QUOTE_UNAVAILABLE`: a dependency needed to price the route is unavailable; retry after the Retry-After delay. Never a route refusal.", "headers": { "Retry-After": { "description": "Seconds to wait before retrying", "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/deposits/permit/prepare": { "post": { "tags": [ "Processing" ], "summary": "Prepare a gasless deposit", "description": "Prepares a token authorization for the user to sign. Experimental.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PermitDepositPrepareRequest" } } } }, "responses": { "200": { "description": "Typed data to sign, with the server-chosen nonce and deadline", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PermitDepositPrepareResponse" } } } }, "400": { "description": "Malformed request, unsupported source chain, same-chain route, or owner funding insufficient (code PERMIT-4)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Missing or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks the deposits write scope, or permit deposits are disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Account not found or not owned by the caller", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "422": { "description": "Permit refused; no deposit is created (deposits paused `PLATFORM-1`, below the USD minimum `BALANCE-4`, whitelist violation, unsupported token route, or no session for the source chain)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/deposits/permit": { "post": { "tags": [ "Processing" ], "summary": "Submit a gasless deposit", "description": "Starts a deposit using a signed token authorization. Experimental.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PermitDepositSubmitRequest" } } } }, "responses": { "202": { "description": "Deposit accepted and processing started", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PermitDepositSubmitResponse" } } } }, "400": { "description": "Invalid signature (PERMIT-1), deadline outside the acceptance window (PERMIT-2), nonce already used (PERMIT-3), owner funding insufficient (PERMIT-4), or ineligible token/route (PERMIT-5)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Missing or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks the deposits write scope, or permit deposits are disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Account not found or not owned by the caller", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "A deposit for this permit already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "422": { "description": "Permit refused; no deposit is created (deposits paused `PLATFORM-1`, below the USD minimum `BALANCE-4`, whitelist violation, unsupported token route, or no session for the source chain)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/deposits/stats": { "get": { "tags": [ "Utilities" ], "summary": "Get deposit statistics", "description": "Returns completed deposit counts, unique depositors, and USD volume for the requested period.", "parameters": [ { "schema": { "type": "string", "enum": [ "24h", "7d", "30d" ], "description": "Rolling time window for aggregated stats", "example": "7d" }, "required": true, "description": "Rolling time window for aggregated stats", "name": "period", "in": "query" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "responses": { "200": { "description": "Deposit statistics for the requested period", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DepositStatsResponse" } } } }, "400": { "description": "Invalid query or API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Missing or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/register-managed": { "post": { "tags": [ "Accounts" ], "summary": "Register a managed account", "description": "Registers a smart account controlled by the server. Reusing a salt is idempotent only for the registered project and destination; use a new salt to change destination.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ManagedRegisterRequestBody" } } } }, "responses": { "200": { "description": "Managed account registered successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ManagedRegisterResponse" } } } }, "400": { "description": "Invalid parameters or unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope, or the organization can't be billed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "The derived address is already registered to a different project, account kind, or destination. Use a new salt for a new destination.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "429": { "description": "Retryable refusal; retry after the Retry-After delay. Registration is idempotent, so a retry reuses whatever was already stored. `WEBHOOK_ENROLLMENT_UNAVAILABLE`: no webhook provider could enroll the deposit address. `REGISTRATION_BUSY`: too many registrations are in flight; the request waited briefly for a slot and none freed. `REGISTRATION_IN_PROGRESS`: another request is registering the same account or salt.", "headers": { "Retry-After": { "description": "Seconds to wait before retrying", "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/setup-account": { "post": { "tags": [ "Accounts" ], "summary": "Prepare account registration", "description": "Returns a deposit address or the details needed to register the account. Existing account ownership, kind, and destination are immutable; a conflicting request is refused before session details are created.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetupAccountRequestBody" } } } }, "responses": { "200": { "description": "Account setup result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetupAccountResponse" } } } }, "400": { "description": "Invalid request or unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope, or user-owned accounts are not enabled for the organization (`USER_OWNED_ACCOUNTS_NOT_ENABLED`; use `POST /register-managed`)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "The derived address is already registered to a different project, account kind, or destination. Use a new address for a new destination.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Failed to derive account or build sessions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Could not verify the existing mapping; retry shortly", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/portfolio/{address}": { "get": { "tags": [ "Utilities" ], "summary": "Get a wallet portfolio", "description": "Returns the wallet's balances this project can take as a deposit: tokens on chains currently accepting deposits and, when the project has a deposit whitelist, only whitelisted tokens. `totalUsd` sums the returned tokens.", "parameters": [ { "schema": { "type": "string", "description": "EVM address or Solana base58 public key", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "required": true, "description": "EVM address or Solana base58 public key", "name": "address", "in": "path" }, { "schema": { "type": "string", "description": "Comma-separated chain IDs to filter the portfolio", "example": "1,8453,42161" }, "required": false, "description": "Comma-separated chain IDs to filter the portfolio", "name": "chainIds", "in": "query" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "responses": { "200": { "description": "Wallet portfolio", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PortfolioResponse" } } } }, "400": { "description": "Invalid request or unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "The authenticated project is not permitted or is not billable.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Client configuration could not be read", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "502": { "description": "Invalid upstream response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/positions/{address}": { "get": { "tags": [ "Utilities" ], "summary": "List withdrawable positions", "description": "Returns DeFi positions and the amounts currently available to withdraw.", "parameters": [ { "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "EVM address holding the DeFi positions", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "required": true, "description": "EVM address holding the DeFi positions", "name": "address", "in": "path" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "responses": { "200": { "description": "Normalised DeFi positions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PositionsResponse" } } } }, "400": { "description": "Invalid request, unauthorized, or the project is not configured for deposits", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks the required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "The account could not be read, so migratable positions cannot be determined. Retry.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/positions/{address}/unwind": { "post": { "tags": [ "Utilities" ], "summary": "Prepare an Aave withdrawal", "description": "Prepares an unsigned transaction to withdraw an Aave position to a deposit address.", "parameters": [ { "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "The EOA holding the position. It signs and sends the returned transaction.", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "required": true, "description": "The EOA holding the position. It signs and sends the returned transaction.", "name": "address", "in": "path" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PrepareUnwindRequestBody" } } } }, "responses": { "200": { "description": "Unsigned withdraw transaction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PrepareUnwindResponse" } } } }, "400": { "description": "Invalid request, unauthorized, no such position, an amount above the withdrawable maximum, or proceeds the deposit policy would reject", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks the required deposits scope, or the account belongs to another project", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/portfolio/solana/{address}": { "get": { "tags": [ "Utilities" ], "summary": "Get a Solana wallet portfolio", "description": "Returns the Solana wallet's balances this project can take as a deposit: nothing while Solana is not accepting deposits and, when the project has a deposit whitelist, only whitelisted tokens (native SOL under the system-program id). `totalUsd` sums the returned tokens.", "parameters": [ { "schema": { "type": "string", "description": "Solana base58 public key", "example": "So11111111111111111111111111111111111111112" }, "required": true, "description": "Solana base58 public key", "name": "address", "in": "path" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "responses": { "200": { "description": "Solana wallet portfolio", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PortfolioResponse" } } } }, "400": { "description": "Invalid Solana address or unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "The authenticated project is not permitted or is not billable.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Client configuration could not be read", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "502": { "description": "Helius upstream error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/liquidity": { "get": { "tags": [ "Utilities" ], "summary": "Check route liquidity", "description": "Checks whether a route can fulfil the requested amount.", "parameters": [ { "schema": { "type": "string", "description": "Chain ID as CAIP-2, or a bare EVM chain id (legacy)", "example": "eip155:8453" }, "required": true, "description": "Chain ID as CAIP-2, or a bare EVM chain id (legacy)", "name": "sourceChainId", "in": "query" }, { "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Source token address", "example": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" }, "required": true, "description": "Source token address", "name": "sourceToken", "in": "query" }, { "schema": { "type": "string", "description": "Chain ID as CAIP-2, or a bare EVM chain id (legacy)", "example": "eip155:8453" }, "required": true, "description": "Chain ID as CAIP-2, or a bare EVM chain id (legacy)", "name": "destinationChainId", "in": "query" }, { "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Destination token address", "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, "required": true, "description": "Destination token address", "name": "destinationToken", "in": "query" }, { "schema": { "type": "string", "pattern": "^\\d+$", "description": "Deposit amount in raw source-token units (integer string)", "example": "1000000" }, "required": true, "description": "Deposit amount in raw source-token units (integer string)", "name": "amount", "in": "query" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "responses": { "200": { "description": "Liquidity information for the requested route", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LiquidityResponse" } } } }, "400": { "description": "Invalid request parameters or unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "The authenticated project is not permitted or is not billable.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "502": { "description": "Invalid liquidity response from orchestrator", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/prices": { "get": { "tags": [ "Utilities" ], "summary": "Get token prices", "description": "Returns token prices in USD by symbol.", "parameters": [ { "schema": { "type": "string", "minLength": 1, "description": "Comma-separated token symbols to price (e.g. \"SOL,ETH\"). Prefer `addresses` for arbitrary tokens — symbol pricing collides across tokens that share a ticker (a spam token can inherit a real token's price). Exactly one of `symbols` or `addresses` must be provided.", "example": "SOL" }, "required": false, "description": "Comma-separated token symbols to price (e.g. \"SOL,ETH\"). Prefer `addresses` for arbitrary tokens — symbol pricing collides across tokens that share a ticker (a spam token can inherit a real token's price). Exactly one of `symbols` or `addresses` must be provided.", "name": "symbols", "in": "query" }, { "schema": { "type": "string", "minLength": 1, "description": "Comma-separated CAIP-2 token ids to price by exact on-chain contract (e.g. \"eip155:8453:0x833589...\"). Collision-free; preferred over `symbols`. Exactly one of `symbols` or `addresses` must be provided.", "example": "eip155:8453:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" }, "required": false, "description": "Comma-separated CAIP-2 token ids to price by exact on-chain contract (e.g. \"eip155:8453:0x833589...\"). Collision-free; preferred over `symbols`. Exactly one of `symbols` or `addresses` must be provided.", "name": "addresses", "in": "query" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "responses": { "200": { "description": "USD unit prices for the requested symbols", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PricesResponse" } } } }, "400": { "description": "Invalid request parameters or unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "The authenticated project is not permitted or is not billable.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/qr/tokens": { "get": { "tags": [ "Utilities" ], "summary": "List suggested deposit tokens", "description": "Returns suggested tokens for QR and manual-transfer deposits.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "responses": { "200": { "description": "Token shortlist per chain", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QrTokensResponse" } } } }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/safe/withdraw": { "post": { "tags": [ "Processing" ], "summary": "Relay a Safe withdrawal", "description": "Submits a signed Safe withdrawal with sponsored gas.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WithdrawRequestBody" } } } }, "responses": { "200": { "description": "Withdrawal relayed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WithdrawResponse" } } } }, "400": { "description": "Invalid request or unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Relay failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/polymarket/withdraw": { "post": { "tags": [ "Processing" ], "summary": "Relay a Polymarket withdrawal", "description": "Submits a signed withdrawal from a Polymarket deposit wallet.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PolymarketWithdrawRequestBody" } } } }, "responses": { "200": { "description": "Withdrawal relayed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PolymarketWithdrawResponse" } } } }, "400": { "description": "Invalid request, disallowed call, or unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "502": { "description": "Polymarket relayer rejected or failed the batch", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Polymarket builder credentials not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/webhooks/events": { "get": { "tags": [ "Webhooks" ], "summary": "List webhook events", "description": "Returns webhook events for the authenticated project, newest first.", "parameters": [ { "schema": { "type": "string", "format": "date-time", "description": "Return events created at or after this ISO timestamp" }, "required": false, "description": "Return events created at or after this ISO timestamp", "name": "since", "in": "query" }, { "schema": { "type": "string", "minLength": 1, "description": "Filter by webhook type (e.g. \"bridge-started\")" }, "required": false, "description": "Filter by webhook type (e.g. \"bridge-started\")", "name": "type", "in": "query" }, { "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50, "description": "Max events to return (1-200, default 50)", "example": 50 }, "required": false, "description": "Max events to return (1-200, default 50)", "name": "limit", "in": "query" }, { "schema": { "type": "string", "minLength": 1, "description": "Opaque cursor from a previous page. Returned events are id-desc; pass the lowest id from the previous page." }, "required": false, "description": "Opaque cursor from a previous page. Returned events are id-desc; pass the lowest id from the previous page.", "name": "cursor", "in": "query" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "responses": { "200": { "description": "Webhook events list", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListWebhookEventsResponse" } } } }, "400": { "description": "Invalid API key or malformed query", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/webhooks/events/{id}/resend": { "post": { "tags": [ "Webhooks" ], "summary": "Resend a webhook", "description": "Resends a webhook event to the configured URL.", "parameters": [ { "schema": { "type": "string", "pattern": "^\\d+$" }, "required": true, "name": "id", "in": "path" }, { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "responses": { "200": { "description": "Resend attempted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResendWebhookEventResponse" } } } }, "400": { "description": "Invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Event does not belong to caller's client", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Event not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/webhooks/test": { "post": { "tags": [ "Webhooks" ], "summary": "Send a test webhook", "description": "Sends a webhook with test data to the configured URL.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}\\.[a-z0-9]+$", "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "example": "2026-04.amazon" }, "required": false, "description": "API version identifier (e.g. \"2026-04.amazon\"). Optional today, will become required in a future release.", "name": "x-api-version", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TestWebhookRequestBody" } } } }, "responses": { "200": { "description": "Test webhook dispatched", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TestWebhookResponse" } } } }, "400": { "description": "Invalid request, unknown type, or client has no webhook URL configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or the presented credential is invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks required deposits scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/compliance/sessions": { "post": { "tags": [ "Compliance" ], "summary": "Create or resume a compliance customer and mint a scoped session", "description": "Called by the integrator backend. Creates or resumes the provider-neutral compliance customer for the given opaque external customer id, optionally binds a registered smart account, and returns a short-lived browser session bearer. The project API key must never be forwarded to the browser — hand the returned token to the modal instead.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ComplianceSessionRequestBody" } } } }, "responses": { "200": { "description": "Scoped session token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ComplianceSessionResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required or invalid credential", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "API key lacks the required deposits scope, or the smart account is not registered to the calling project", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "`resumeOnly`: no customer exists for this id, or it is not bound to the requested account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ComplianceSessionNotFound" } } } }, "409": { "description": "The requested smart account is already bound to another customer in this project, or the customer is already bound to a different account and changing it requires an explicit migration", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ComplianceSessionConflict" } } } }, "500": { "description": "Failed to create the compliance session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Compliance sessions are paused", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/compliance/status": { "get": { "tags": [ "Compliance" ], "summary": "Read the canonical verification state for the session customer", "description": "Browser route. Returns the normalized verification state for the compliance customer named by the session bearer. Scoped to that one customer — a token can never read another customer, project, or bound account.", "parameters": [ { "schema": { "type": "string", "description": "Bearer ", "example": "Bearer eyJhbGciOi..." }, "required": true, "description": "Bearer ", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "Normalized verification state", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ComplianceStatusResponse" } } } }, "401": { "description": "Missing, malformed, or expired session token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Session does not match the resolved customer", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Failed to read compliance status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/compliance/verification": { "post": { "tags": [ "Compliance" ], "summary": "Create or resume hosted verification for the session customer", "description": "Browser route. Starts or resumes the provider-hosted verification flow for the compliance customer named by the session bearer. A `pending` result with `nextAction` must be presented in an iframe; `pending` without it means the provider is reviewing and status updates arrive via webhook. The hosted URL is short-lived and is never stored — call again to mint a fresh one.", "security": [ { "complianceSessionBearer": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ComplianceVerificationRequestBody" } } } }, "responses": { "200": { "description": "Hosted verification session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ComplianceVerificationSession" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Missing, malformed, or expired session token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Session does not match the resolved customer, READ_ONLY_SESSION: the bearer came from a `resumeOnly` session, or PROVIDER_FORBIDDEN: the provider refuses verification for this customer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "404": { "description": "Bank transfer by virtual account is not provisioned for this project", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Failed to create the verification session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "502": { "description": "PROVIDER_UNAVAILABLE: the verification provider did not answer; or PROVIDER_REJECTED: it refused the request (`providerError`)", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "Verification provider not configured, or sessions paused", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/onramp/providers": { "get": { "tags": [ "Onramp" ], "summary": "List onramp providers", "description": "The onramps provisioned for this organization, and the credential each takes. Ask `GET /onramp/options` what each one offers.", "parameters": [ { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "The providers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OnrampProviders" } } } }, "401": { "description": "Missing or invalid API key or bearer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "API key lacks deposits:read, the bearer no longer matches its customer, or this provider takes the other credential", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "Could not resolve organization provisioning", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] }, { "complianceSessionBearer": [] } ] } }, "/onramp/orders/{id}": { "get": { "tags": [ "Onramp" ], "summary": "Get an onramp order", "description": "Accepts any id the caller holds: the order `id`, the provider’s order id (e.g. the `orderId` of the legacy `onramp-order` webhook), the `orderId` returned when the checkout was started (when retries share it, the newest order), or the `externalCustomerId` signed into the checkout (`:`). 404 until the provider first reports the order. A customer bearer reads that customer’s orders and every order on its bound account.", "parameters": [ { "schema": { "type": "string", "pattern": "^[A-Za-z0-9._:-]{1,128}$", "description": "Order id, provider order id, checkout reference, or `:`" }, "required": true, "description": "Order id, provider order id, checkout reference, or `:`", "name": "id", "in": "path" }, { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "The order", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OnrampOrder" } } } }, "401": { "description": "Missing or invalid API key or bearer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "API key lacks deposits:read, the bearer no longer matches its customer, or this provider takes the other credential", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "404": { "description": "No such order for this project yet", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] }, { "complianceSessionBearer": [] } ] } }, "/onramp/orders": { "get": { "tags": [ "Onramp" ], "summary": "List onramp orders", "description": "Newest first by when each order began: the project’s with an API key; with a bearer, the customer’s and those on its bound account (card and exchange orders carry no customer).", "parameters": [ { "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Ethereum address (0x followed by 40 hex characters)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f5bE91" }, "required": false, "description": "Ethereum address (0x followed by 40 hex characters)", "name": "account", "in": "query" }, { "schema": { "type": "string", "enum": [ "noah", "swapped" ], "description": "Only this provider’s orders, applied before `limit`" }, "required": false, "description": "Only this provider’s orders, applied before `limit`", "name": "provider", "in": "query" }, { "schema": { "type": "string", "format": "uuid", "description": "`nextCursor` of the previous page" }, "required": false, "description": "`nextCursor` of the previous page", "name": "cursor", "in": "query" }, { "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 }, "required": false, "name": "limit", "in": "query" }, { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "A page of orders", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OnrampOrderPage" } } } }, "401": { "description": "Missing or invalid API key or bearer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "API key lacks deposits:read, the bearer no longer matches its customer, or this provider takes the other credential", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "Tenant billing verification is temporarily unavailable; retry after 5 seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] }, { "complianceSessionBearer": [] } ] }, "post": { "tags": [ "Onramp" ], "summary": "Start an onramp order", "description": "Signs a hosted checkout for the account. The order is visible at `GET /onramp/orders/{orderId}` once the provider first reports it.", "parameters": [ { "schema": { "type": "string", "description": "API key for authentication", "example": "your-api-key" }, "required": false, "description": "API key for authentication", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "Trusted edge-resolved ISO country. When present it overrides body.baseCountry and x-client-ip, and enables country-specific payment-method validation.", "example": "PH" }, "required": false, "description": "Trusted edge-resolved ISO country. When present it overrides body.baseCountry and x-client-ip, and enables country-specific payment-method validation.", "name": "x-user-country", "in": "header" }, { "schema": { "type": "string", "description": "The end user's IP address as observed by the edge, for edges that can name the IP but cannot resolve a country themselves (no local GeoIP database). Used only when x-user-country is absent, and ignored unless it is a publicly-routable address. Prefer x-user-country when your edge already has a country — for example Cloudflare's cf-ipcountry — since it needs no lookup here.", "example": "203.0.113.7" }, "required": false, "description": "The end user's IP address as observed by the edge, for edges that can name the IP but cannot resolve a country themselves (no local GeoIP database). Used only when x-user-country is absent, and ignored unless it is a publicly-routable address. Prefer x-user-country when your edge already has a country — for example Cloudflare's cf-ipcountry — since it needs no lookup here.", "name": "x-client-ip", "in": "header" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateOnrampOrderRequest" } } } }, "responses": { "202": { "description": "Hosted checkout ready", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OnrampOrderStarted" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid API key or bearer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "API key lacks deposits:read, or the account is not yours", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "Onramp not configured, or a dependency is unavailable", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] } ] } }, "/onramp/options": { "get": { "tags": [ "Onramp" ], "summary": "List onramp options", "description": "What a checkout of this `kind` can offer: fiat payment methods for the caller’s country, or exchange connections.", "parameters": [ { "schema": { "type": "string", "enum": [ "swapped", "noah" ] }, "required": true, "name": "provider", "in": "query" }, { "schema": { "type": "string", "enum": [ "fiat", "exchange" ], "description": "`swapped` only, required there" }, "required": false, "description": "`swapped` only, required there", "name": "kind", "in": "query" }, { "schema": { "type": "string", "enum": [ "EUR", "USD" ], "description": "`noah` only. One option for this currency; both without" }, "required": false, "description": "`noah` only. One option for this currency; both without", "name": "currency", "in": "query" }, { "schema": { "type": "string", "maxLength": 1024, "description": "`swapped` exchange only. Comma-separated allowlist, served in catalogue order; an unknown slug is a 400" }, "required": false, "description": "`swapped` exchange only. Comma-separated allowlist, served in catalogue order; an unknown slug is a 400", "name": "connections", "in": "query" }, { "schema": { "type": "string", "enum": [ "exchange", "wallet", "all" ], "description": "`swapped` exchange only, ignored with `connections`" }, "required": false, "description": "`swapped` exchange only, ignored with `connections`", "name": "connectionKind", "in": "query" }, { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "Trusted edge-resolved ISO country. When present it overrides body.baseCountry and x-client-ip, and enables country-specific payment-method validation.", "example": "PH" }, "required": false, "description": "Trusted edge-resolved ISO country. When present it overrides body.baseCountry and x-client-ip, and enables country-specific payment-method validation.", "name": "x-user-country", "in": "header" }, { "schema": { "type": "string", "description": "The end user's IP address as observed by the edge, for edges that can name the IP but cannot resolve a country themselves (no local GeoIP database). Used only when x-user-country is absent, and ignored unless it is a publicly-routable address. Prefer x-user-country when your edge already has a country — for example Cloudflare's cf-ipcountry — since it needs no lookup here.", "example": "203.0.113.7" }, "required": false, "description": "The end user's IP address as observed by the edge, for edges that can name the IP but cannot resolve a country themselves (no local GeoIP database). Used only when x-user-country is absent, and ignored unless it is a publicly-routable address. Prefer x-user-country when your edge already has a country — for example Cloudflare's cf-ipcountry — since it needs no lookup here.", "name": "x-client-ip", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "The options", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OnrampOptions" } } } }, "400": { "description": "Invalid query", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid API key or bearer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "API key lacks deposits:read, the bearer no longer matches its customer, or this provider takes the other credential", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "404": { "description": "`noah`: virtual accounts are not provisioned, or no account currency is available for the supplied country", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "502": { "description": "PROVIDER_UNAVAILABLE: the provider did not answer; or PROVIDER_REJECTED: it refused the request (`providerError`)", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "Onramp not configured", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] }, { "complianceSessionBearer": [] } ] } }, "/onramp/accounts": { "post": { "tags": [ "Onramp" ], "summary": "Set up a funding account", "description": "Configures a bank account whose transfers deliver to the customer’s bound smart account. Bank transfers into it appear as orders at `GET /onramp/orders`.", "parameters": [ { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateOnrampAccountRequest" } } } }, "responses": { "201": { "description": "The configured account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OnrampAccountCreated" } } } }, "400": { "description": "Unknown option for this currency", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid bearer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "Not a customer bearer, the bearer no longer matches its customer, READ_ONLY_SESSION: the bearer came from a `resumeOnly` session, or PROVIDER_FORBIDDEN: the provider refuses the customer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "404": { "description": "No such account for this customer, or bank transfer by virtual account is not provisioned for this project", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "409": { "description": "No bound smart account, the project is not configured for deposits, its whitelist or session coverage rejects the delivery route, the bound account is an offramp account, or `VERIFICATION_REQUIRED`: the customer must resume verification for this currency", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "502": { "description": "PROVIDER_UNAVAILABLE: the provider did not answer; or PROVIDER_REJECTED: it refused the request (`providerError`)", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "Onramp is not configured", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } } }, "security": [ { "complianceSessionBearer": [] } ] }, "get": { "tags": [ "Onramp" ], "summary": "List funding accounts", "parameters": [ { "schema": { "type": "string", "format": "uuid" }, "required": false, "name": "cursor", "in": "query" }, { "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 }, "required": false, "name": "limit", "in": "query" }, { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "A page of the customer’s accounts", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OnrampAccountPage" } } } }, "401": { "description": "Missing or invalid bearer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "Not a customer bearer, the bearer no longer matches its customer, or PROVIDER_FORBIDDEN: the provider refuses the customer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "404": { "description": "No such account for this customer, or bank transfer by virtual account is not provisioned for this project", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "502": { "description": "PROVIDER_UNAVAILABLE: the provider did not answer; or PROVIDER_REJECTED: it refused the request (`providerError`)", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "Onramp is not configured", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } } }, "security": [ { "complianceSessionBearer": [] } ] } }, "/onramp/accounts/{id}": { "get": { "tags": [ "Onramp" ], "summary": "Get a funding account", "parameters": [ { "schema": { "type": "string", "format": "uuid" }, "required": true, "name": "id", "in": "path" }, { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "The account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OnrampAccount" } } } }, "401": { "description": "Missing or invalid bearer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "Not a customer bearer, the bearer no longer matches its customer, or PROVIDER_FORBIDDEN: the provider refuses the customer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "404": { "description": "No such account for this customer, or bank transfer by virtual account is not provisioned for this project", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "502": { "description": "PROVIDER_UNAVAILABLE: the provider did not answer; or PROVIDER_REJECTED: it refused the request (`providerError`)", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "Onramp is not configured", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } } }, "security": [ { "complianceSessionBearer": [] } ] } }, "/onramp/accounts/{id}/details": { "get": { "tags": [ "Onramp" ], "summary": "Get bank details for a funding account", "description": "The coordinates to send the transfer to, captured when the account was configured. Served `Cache-Control: no-store`.", "parameters": [ { "schema": { "type": "string", "format": "uuid" }, "required": true, "name": "id", "in": "path" }, { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "Bank instructions for transfers into this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OnrampAccountDetails" } } } }, "401": { "description": "Missing or invalid bearer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "Not a customer bearer, the bearer no longer matches its customer, or PROVIDER_FORBIDDEN: the provider refuses the customer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "404": { "description": "No such account for this customer, or bank transfer by virtual account is not provisioned for this project", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "409": { "description": "Bank instructions are unavailable for this account", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "502": { "description": "PROVIDER_UNAVAILABLE: the provider did not answer; or PROVIDER_REJECTED: it refused the request (`providerError`)", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "Onramp is not configured", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } } }, "security": [ { "complianceSessionBearer": [] } ] } }, "/offramp/options": { "get": { "tags": [ "Offramp" ], "summary": "List payout methods", "description": "The ways the customer can be paid out to a bank account. The provider decides them per customer.", "parameters": [ { "schema": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "Receiving bank country" }, "required": false, "description": "Receiving bank country", "name": "country", "in": "query" }, { "schema": { "type": "string", "pattern": "^[A-Z]{3}$", "description": "ISO 4217 payout currency" }, "required": false, "description": "ISO 4217 payout currency", "name": "currency", "in": "query" }, { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "The payout methods", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpOptions" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid credentials", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "The bearer no longer matches its customer, or an API key was sent: payout rails are per customer", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "404": { "description": "Payouts are not enabled for this project", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "502": { "description": "PROVIDER_UNAVAILABLE: the provider did not answer; or PROVIDER_REJECTED: it refused the request (`providerError`)", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "No payout provider is configured, or the customer could not be read; retry", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } } }, "security": [ { "complianceSessionBearer": [] } ] } }, "/offramp/orders": { "post": { "tags": [ "Offramp" ], "summary": "Start a withdrawal to a bank account", "description": "Prepares the payout with the provider and opens it for one exact amount: the requested amount, or slightly less (one base unit at a time) when another open withdrawal holds it. Then send `order.payment` exactly. A source holding the token the provider takes, on its chain, pays the provider directly; any other source on a chain that takes deposits pays into the customer’s withdrawal account an amount quoted to deliver it (`SOURCE_NOT_SUPPORTED`, `NO_ROUTE` or `QUOTE_UNAVAILABLE` otherwise, holding nothing). Once the order exists, every error names it (`orderId`).", "parameters": [ { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateOfframpOrder" } } } }, "responses": { "201": { "description": "The order, the payment to send, and the estimate", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpOrderCreated" } } } }, "400": { "description": "Invalid request; AMOUNT_TOO_SMALL; or INVALID_BENEFICIARY", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpError" } } } }, "401": { "description": "Missing or invalid credentials", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "The bearer no longer matches its customer, an API key was sent (payout rails are per customer), READ_ONLY_SESSION: the bearer came from a `resumeOnly` session, or PROVIDER_FORBIDDEN: the provider refuses this customer", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpError" } } } }, "404": { "description": "Payouts are not enabled for this project", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpError" } } } }, "409": { "description": "VERIFICATION_REQUIRED; UNKNOWN_METHOD: list the methods again; SOURCE_NOT_SUPPORTED; NO_ROUTE: nothing converts this source into the provider’s token for this amount; or TOO_MANY_OPEN_WITHDRAWALS from this address near this amount", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpError" } } } }, "500": { "description": "Internal failure serving the request; or FUNDING_NOT_CONFIGURED: the order (`orderId`) holds its amount but serves no payment. Send nothing for it; open another to retry.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpError" } } } }, "502": { "description": "PROVIDER_UNAVAILABLE: the provider did not answer; PROVIDER_REJECTED: it refused the request (`providerError`); or OUTCOME_UNKNOWN: it never confirmed the payout, so the order (`orderId`) keeps its amount and serves no payment. Send nothing for it; open another order to retry.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpError" } } } }, "503": { "description": "Offramp is unavailable: no payout provider is configured, QUOTE_UNAVAILABLE (the amount to send could not be quoted), the customer’s withdrawal account could not be set up (`Retry-After`), or the customer or the project’s fee configuration could not be read; retry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpError" } } } } }, "security": [ { "complianceSessionBearer": [] } ] }, "get": { "tags": [ "Offramp" ], "summary": "List offramp orders", "description": "Newest first by when each order was opened. A customer bearer lists that customer's orders; an API key with `deposits:read`, the project's.", "parameters": [ { "schema": { "type": "string", "format": "uuid", "description": "`nextCursor` of the previous page" }, "required": false, "description": "`nextCursor` of the previous page", "name": "cursor", "in": "query" }, { "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 }, "required": false, "name": "limit", "in": "query" }, { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "A page of orders", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpOrderPage" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid credentials", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "The bearer no longer matches its customer, or the API key lacks `deposits:read`", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "The customer could not be read; retry", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] }, { "complianceSessionBearer": [] } ] } }, "/offramp/orders/{id}": { "get": { "tags": [ "Offramp" ], "summary": "Get an offramp order", "description": "By the order `id`. A customer bearer reads that customer's orders; an API key with `deposits:read`, the project's.", "parameters": [ { "schema": { "type": "string", "format": "uuid" }, "required": true, "name": "id", "in": "path" }, { "schema": { "type": "string", "description": "Integrator API key: the project’s orders" }, "required": false, "description": "Integrator API key: the project’s orders", "name": "x-api-key", "in": "header" }, { "schema": { "type": "string", "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "example": "Bearer eyJhbGciOi..." }, "required": false, "description": "Customer bearer from `POST /compliance/sessions`, or a project-scoped platform bearer where the route permits tenant access", "name": "authorization", "in": "header" } ], "responses": { "200": { "description": "The order", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OfframpOrder" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid credentials", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "403": { "description": "The bearer no longer matches its customer, or the API key lacks `deposits:read`", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "404": { "description": "No such order", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "500": { "description": "Internal failure serving the request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } }, "503": { "description": "The customer could not be read; retry", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "code": { "type": "string", "enum": [ "VERIFICATION_REQUIRED", "PROVIDER_UNAVAILABLE", "PROVIDER_REJECTED", "PROVIDER_FORBIDDEN", "READ_ONLY_SESSION" ], "description": "VERIFICATION_REQUIRED: the customer must resume hosted verification for this currency, then retry. PROVIDER_UNAVAILABLE (502): the provider did not answer; retry. PROVIDER_REJECTED (502): the provider refused the request; `providerError` says what, and retrying it unchanged fails again. PROVIDER_FORBIDDEN (403): the provider will not serve this customer. READ_ONLY_SESSION (403): the customer bearer came from a `resumeOnly` session, which can only read; mint a session without `resumeOnly` to make changes" }, "providerError": { "$ref": "#/components/schemas/ProviderError" } }, "required": [ "error" ] } } } } }, "security": [ { "tenantApiKey": [] }, { "internalProjectBearer": [] }, { "complianceSessionBearer": [] } ] } } }, "webhooks": {} }