Orders

Market and limit orders, time in force, resting orders, cancellation, idempotency, and slippage capture.

POST /api/v2/portfolio/orders

FieldTypeRequiredDescription
tickerstringyesKalshi ticker, or Polymarket slug / condition id / token id.
actionstringyesbuy or sell.
yes_nostringyesyes or no — the side you are buying or selling.
countintegeryesContracts. Polymarket markets enforce a minimum of 5.
typestringnomarket (default), limit, stop, take_profit, or bracket.
limit_pricenumberlimit onlyDollars in (0, 1) on the market's tick grid (Kalshi 0.01; Polymarket 0.01 or 0.001).
time_in_forcestringnoGTC (default), IOC, or FOK. Limit orders only.
expires_atISO-8601noAuto-cancel time for GTC limit and conditional orders.
trigger_pricenumberstop/TP onlyTrigger level for stop / take_profit.
stop_price / take_profit_pricenumberbracket onlyThe two legs of a bracket.
client_order_idstringno1–64 chars [A-Za-z0-9_-]. Idempotency key — see below.
strategystringnoFree-form tag (≤64 chars) used by P&L attribution.
venuestringnokalshi or polymarket. Auto-detected from the identifier when omitted.
dry_runbooleannoPreview without writing anything (alias: preview).

Market orders

A market buy walks the ask side of the live book from the best price up, accumulating a VWAP; a market sell walks the bids down. Fills are all-or-nothing against displayed depth: if the visible book cannot absorb your full count, the order is rejected with an insufficient-liquidity error rather than silently part-filling. Kalshi books are fetched at depth 20; Polymarket books are fetched in full.

Limit orders

A limit order executes its marketable portion immediately (every displayed level at or better than your limit, as a taker) and then, under GTC, rests the remainder. IOC cancels the remainder instead; FOK rejects the whole order unless it can fill completely at or better than the limit.

  • Resting buys place a cash hold: limit_price × remaining + worst-case taker fee, released as the order fills, cancels, or expires. Held cash is not spendable (reserved_balance on responses).
  • Resting sells place a contract hold (reservedContracts on the position) so the same contracts cannot be sold twice.
  • Resting orders fill as MAKERS at your limit price when the displayed opposite side crosses it — checked by a matching loop that runs about once a minute. See Simulation vs. Reality for exactly what this does and does not model.
  • Each maker fill creates a normal executed-order record (resting_order_id links it back); the resting order tracks remaining_count, filled_count, and child_order_ids.
  • Open resting orders are capped per tier (Free 5 / Starter 25 / Pro 100 / Enterprise 1000).

Order statuses

StatusMeaning
executedFully filled immediately (market, or fully marketable limit).
partially_filledLimit order: part filled as taker, remainder resting.
restingResting on the book (or waiting on a trigger), nothing filled yet.
filledResting order completely filled by maker executions.
cancelled / expiredRemoved before completion; terminal_reason says why (user_cancelled, order_expired, market_closed, oco_sibling_filled, position_closed, ...).

Cancel and inspect

# Inspect any order (executed or resting)
curl https://predarena.org/api/v2/portfolio/orders/ORDER_ID \
  -H "Authorization: Bearer $PREDARENA_API_KEY"

# Cancel a resting order (releases its cash/contract holds atomically)
curl -X DELETE https://predarena.org/api/v2/portfolio/orders/ORDER_ID \
  -H "Authorization: Bearer $PREDARENA_API_KEY"

Cancelling an already-executed order returns 410 Gone. Listing GET /api/v2/portfolio/orders returns executed orders, individual fills, and open resting_orders; pass ?status=resting for just the open book.

Idempotency with client_order_id

If an order with the same client_order_id already exists on the account (executed or resting), the API returns that original order with idempotent_replay: true instead of executing again — checked inside the same transaction that writes the order, so a retried request can never double-fill. Always set it from bots: network timeouts make retries inevitable.

Slippage capture

Every immediate execution records mid_price_at_execution (midpoint of best displayed bid/ask at fill time), slippage_per_contract (signed: positive = worse than mid), and slippage_cost. This is your ground truth for execution quality — the analytics endpoint aggregates it by order-size bucket so you can see exactly where size starts costing you.