CRISP partners

Orders, fills and portfolio

Build around durable commands and confirmed fills, not HTTP acceptance.

Discover and validate

Before you start: a ready, funded account with trading and portfolio access enabled. Configure the server client.

Display cash balance and available buying power using getFunding with details: 'trading'. Use data.availableToTrade.formatted, not the raw cash balance, for buying power.

Use /v1/events, /v1/markets, /v1/markets/{conditionId} and /v1/books/{tokenId} to select a real market/outcome. Read /v1/order-requirements and /v1/trading-status; retain tick size, minimum and service restrictions. Requirements needs tokenId and BUY/SELL side; type defaults to market. Optional amount, comma-separated amounts (up to six), price and size must be positive. Limit BUY requirements needs price between zero and one. Do not hardcode an outcome token, market ID or execution host from an example.

Submit an order

Save the exact order and a unique intent key before the first attempt. The following IDs/keys are illustrative; use real market data, an authorized user, and your persisted intent in production. HTTP tabs omit signing headers.

Market buy: spend cash

const result = await crisp.marketBuy('example:user-123', {
  marketId: 'actual-market-id',
  tokenId: '12345678901234567890',
  spendAmount: '2.00',
}, 'order-buy-intent-001');

Market sell: sell shares

const result = await crisp.marketSell('example:user-123', {
  marketId: 'actual-market-id',
  tokenId: '12345678901234567890',
  shares: '10',
}, 'order-sell-intent-001');

Limit order: price and shares

const result = await crisp.limitOrder('example:user-123', {
  marketId: 'actual-market-id',
  tokenId: '12345678901234567890',
  side: 'BUY',
  price: '0.62',
  shares: '10',
}, 'order-limit-intent-001');

The token above is illustrative. Common fields: marketId, tokenId, side (BUY/SELL), type (market/limit), amount, price, size, priceLimit, orderType, expiresInSeconds, outcomeIndex, tickSize, negRisk. Use valid combinations and market precision. Keep monetary input as decimal strings; do not round-trip token base units through JavaScript floating point.

Market BUY amount is a cash budget; configured fees affect executable notional. Market SELL amount is shares, not dollars. Limit price is cash per share and size is shares. CRISP validates current fees, exposure and funds at execution. An optional priceLimit caps/floors market execution; without it the executor derives a protected limit from a fresh book. This is not a fill guarantee.

Acceptance and recovery

202 returns data.command (id/state/failureCode) and data.order (including id when known, status and optional fill). Queued/running is pending. Succeeded means the command succeeded; an accepted limit order can still be open/unfilled. Failed and ambiguous responses require different treatment.

For pending commands, use the read-only account-scoped GET /v1/accounts/{externalUserId}/operations/{operationId}. If the response was lost, recover by operation kind and original intent key through /operations. See operation recovery. Same-path/key/body POST replay remains supported for existing integrations. Never create a replacement intent after an uncertain timeout. Use lifecycle events and resource reads for fills.

Optional POST /orders/prewarm accepts { "tokenIds": ["…"] } (one or two). The SDK's prepareTrading coalesces warmups and prepares the execution route in parallel; never block trading on it. High-level SDK order helpers use cached, server-only cell capabilities automatically and fall back to the standard API with the same intent when routing is unavailable. See SDK fast execution. Ordinary /orders remains supported; no integration is forced to use cell routing.

Portfolio and history

const result = await crisp.listPositions('example:user-123');
Endpoint suffix after /v1/accounts/{externalUserId}Purpose
/ordersOpen orders; not complete fill history
/orders/{orderId}/cancel (POST)Durable cancel, idempotency required
/positionsCurrent position data; closed, limit/offset supported
/sellable-shares?tokenId=…Returns tokenId, availableShares and asOf for a ready account
/tradesAccount wallet trade data
/trade-fillsCanonical fills for your users with fee-distribution metadata
/orders/{orderId}/trade-fillsOne order's individual confirmed fills

For /trade-fills, from and to ISO timestamps are required (ascending window up to 366 days). Default limit 50, maximum 100; persist cursor and use hasMore. For one order's fills, limit defaults to 100, maximum 200. Older history remains reachable through earlier windows; a window bound is not ledger expiry. Volume means confirmed USD fill notional, not shares. Do not sum accepted orders and confirmed fills together or confuse venue fees with referral allocations.

Redeem resolved positions

const result = await crisp.redeemPositions(
  'example:user-123',
  {
    positions: [
      {
        conditionId: 'actual-condition-id',
        size: 7.77,
        outcomeIndex: 0,
        negRisk: false,
      },
    ],
  },
  'redeem-intent-unique-001',
);

Use live position tuples, not the placeholder. 1–20 distinct condition IDs; eligibility/outcome/size are revalidated before signing. Show a confirmation: close losing positions for zero or claim winning payout. 202 is pending; update portfolio only after confirmation/reconciliation. Allowed in cancel-only mode, blocked when trading is disabled.

Cancel an open order

Use a venue order ID from your account's open orders, not a command ID. A cancellation races fills; refresh the order and fills after completion, rather than assuming all shares were canceled.

const result = await crisp.cancelOrder(
  'example:user-123',
  'actual-order-id',
  'cancel-intent-unique-001',
);

Next: follow or recover the command. Exact contracts: placeOrder, cancelOrder, redeemPositions.

CRISP Partner Documentation