Skip to main content
A trade is executed from the smart account of the user who owns the API key. Trades work on both API versions. On 2026-08-19 the trade resource also carries chainRef, and txHash is returned for every chain; on a pinned 2026-04-29 a Solana trade’s txHash is null.

The trade resource

Status lifecycle: pending → validating → executing → completed, ending in failed or rejected instead when something stops it. A high-value trade starts in pending_confirmation.

POST /v1/trades

Responses:
  • 201 Created: the trade entered the pipeline. Body { trade, data, _meta } where _meta.idempotent is false.
  • 200 OK: a repeat of an earlier request with the same clientRequestId and the same body. The existing trade is returned with _meta.idempotent: true.
  • 202 Accepted: the amount reached your key’s high-value threshold. The trade is held in pending_confirmation and the body adds confirmation: { token, expiresAt }. The token expires 60 seconds after issue. Release the trade with POST /v1/trades/{id}/confirm.
Before anything is written, the request is checked in this order of concern: the market (404 MARKET_NOT_FOUND, 409 MARKET_NOT_TRADEABLE, 400 CHAIN_NOT_SUPPORTED, 400 OUTCOME_INDEX_INVALID), the amount (400 AMOUNT_TOO_LARGE), your account (409 SMART_ACCOUNT_NOT_PROVISIONED, 409 WALLET_DELEGATION_NOT_ENABLED), the key’s per-trade cap (409 SPENDING_LIMIT_EXCEEDED), and admission control (429 TRADE_IN_FLIGHT_LIMIT_EXCEEDED when the account already has its tier’s maximum of unfinished trades, 503 TRADE_ADMISSION_BUSY while the pipeline works through a backlog; both carry Retry-After). A reused clientRequestId with a different body is 409 CLIENT_REQUEST_ID_CONFLICT. API trading can be temporarily unavailable (503 API_TRADE_PROCESSING_HALTED, with Retry-After). Some checks run after the trade is accepted. The key’s daily spending cap, the smart account’s USDC balance and other risk rules are evaluated in the pipeline. A trade that fails them moves to rejected (with a trade.rejected webhook) rather than being refused synchronously.

POST /v1/trades/{id}/confirm

Releases a trade in pending_confirmation into the pipeline. Response 200: { trade, data, _meta } with the trade in pending. Errors: 404 RESOURCE_NOT_FOUND, 409 TRADE_NOT_AWAITING_CONFIRMATION, 409 CONFIRMATION_TOKEN_INVALID, 409 CONFIRMATION_TOKEN_USED (single-use), 409 CONFIRMATION_EXPIRED. Release goes through the same admission control as create (429 TRADE_IN_FLIGHT_LIMIT_EXCEEDED, 503 TRADE_ADMISSION_BUSY); a refused confirm writes nothing, so the token stays valid for a retry until it expires.

GET /v1/trades

Your trades, newest first, cursor-paginated. Response 200: { data: Trade[], pagination, _meta }.

GET /v1/trades/{id}

Response 200: { trade, data, _meta }. A trade that does not exist, or that belongs to another user, is 404 RESOURCE_NOT_FOUND.