Market data and account
The three public market data routes and the four behind your key, with measured times.
Three public routes cover the market. Four behind your key cover your own account and nothing else. Every measured time below was taken on devnet. The examples use jq to trim output, with these exported in your shell:
export BASE="https://api.beta.cardiv.xyz/api/trade/v1"
export KEY="usr_ak_..."Public
GET /pairs, under 0.05 s. Every pair this environment trades, with base, quote, minQuoteAmount, minOrderUsd and priceTick. Use the pair string verbatim in order bodies and URL-encode it in path parameters (CBTC%2FCC). minQuoteAmount is the smallest notional the book keeps: orders below it are refused, and a fill that would leave a smaller remainder cancels the remainder instead, so a large order can finish marginally short. priceTick is the price step the pair accepts, null when any price with up to 10 decimals is fine.
GET /orderbook/{pair}?depth=, 0.2 to 0.8 s. bids and asks as [price, quantity] string pairs, best price first, so bids[0] is the highest bid and asks[0] the lowest ask. depth caps each side at that many levels, 50 by default, and a pair with no resting orders returns two empty lists. It reads a cached view rather than the Canton Network directly, so polling faster than every 1 to 2 seconds buys you no extra freshness.
curl -s "$BASE/orderbook/CBTC%2FCC?depth=5" | jq '.data'GET /trades?pair=&limit=, 0.8 to 1.4 s. The public tape for the pair, newest first. Each entry carries tradeId, price, quantity and executedAt and nothing more: no party, no side, no attribution, for any caller.
Behind your key
GET /account, 0.4 to 0.8 s. Your tier, party, order id prefix and limits. Authentication lists the fields.
GET /orders?pair=&status=&side=&from=&to=&limit=&refreshCalden=, 0.8 to 1.2 s. Every order your party has resting in the order book, and the authority on your own fills: filled and status track execution.
curl -s "$BASE/orders?refreshCalden=false" -H "X-API-Key: $KEY" \
| jq -r '.data.orders[] | [.orderId, .pair, .side, .type, .price, .quantity, .filled, .status] | @tsv'status defaults to OPEN, which returns every resting state (OPEN, PARTIALLY_FILLED, PENDING_TRIGGER); ALL returns full history; any single status filters exactly. from and to bound creation time as ISO 8601 instants, side is BUY or SELL, pair narrows to one pair, and limit defaults to 100. Set refreshCalden=false in any polling loop: the default re-queries the wallet service on every call, measured at 34 seconds against 1 second for the same query.
Each order carries orderId, your clientOrderId and stable for the order's life; contractId, the current identifier on the Canton Network, which changes after a partial fill; pair, side, type, price, quantity, filled, status, stopPrice, createdAt and updatedAt; and correlationId, which goes in any support request.
GET /orders/{orderId}, under 1 s. Single-order lookup, and the recovery primitive after a failed, timed-out or lost submission. It reads directly and never triggers a wallet refresh. An orderId that does not exist and one belonging to somebody else both return 404 CONTRACT_NOT_FOUND, deliberately indistinguishable, so a 404 tells you only that the id is not yours.
GET /balances, 1 to 2 s warm. Your balances, with available free to commit to new orders and locked committed to resting ones, both decimal strings. It takes no parameters: one account is one party, and the key identifies it. Use it at startup and for periodic reconciliation, not in the quote loop; the first call against a cold cache can pass 10 seconds.
Need help
Write to support@wolfedgelabs.com and include your party ID.