Skip to main content
Action required

Polymarket position averagePrice excludes fees

averagePrice on a Polymarket position is the weighted-average entry price excluding fees, matching Kalshi positions. unrealizedPnlUsd is unchanged and is still net of the fees paid on the open holding. If you treated averagePrice as a fee-inclusive cost basis, use unrealizedPnlUsd for profit and loss instead.See the Polymarket guide.
Action required

Kalshi order events route removed

/v1/kalshi/orders/{orderId}/events no longer accepts GET requests. Integrations using this route should read order status through GET /v1/kalshi/orders/{orderId} and executions through GET /v1/kalshi/orders/{orderId}/fills.See the Kalshi guide.
New

Fill-or-kill orders in a ProphetX batch

POST /v1/prophetx/orders/batch accepts timeInForce: { "type": "FOK" } on any order, beside GTC orders in the same request.See the ProphetX guide.
Action required

Polymarket batch takes one idempotency key

POST /v1/polymarket/orders/batch takes one Idempotency-Key header for the batch and a list of bare orders, with no per-entry idempotencyKey. It returns orders, one result per entry in request order, in place of results. Each entry uses success in place of outcome; inspect error.code when success is false. Update the request and response handling.See the Polymarket guide.
Action required

ProphetX batch submit takes one idempotency key

POST /v1/prophetx/orders/batch now takes one Idempotency-Key header for the whole batch and a body of bare orders, and returns succeededOrders and failedOrders in place of results. Choose one key for the entire batch, send it in the Idempotency-Key header, remove all per-entry keys, and read the two lists. A failed entry’s order id is its orderId; its error carries code and message only.See the ProphetX guide.
Action required

Kalshi batch takes one Idempotency-Key and returns positional results

POST /v1/kalshi/orders/batch now takes one Idempotency-Key header for the batch and { orders: [order, ...] } with no per-entry idempotencyKey. It returns orders, one element per entry in request order, in place of results. Each element is a flat record: orderId, status, filledCount, remainingCount, averagePrice and error, with error null when the entry was accepted. Send the header, drop the per-entry keys, and read orders.See the Kalshi guide.
Action required

ProphetX limits require an exact ladder price

POST /v1/prophetx/orders rejects off-ladder prices with 400 INVALID_REQUEST. Choose an exact price from GET /v1/prophetx/ladder before submitting. Existing orders and identical idempotent retries retain their accepted limits.Check integrations that submit arbitrary decimal limits or reuse fill prices.Pricing rules are in the ProphetX guide.
Action required

Kalshi orders and positions use the venue’s own vocabulary

A Kalshi order now carries one side, either BID or ASK, with count and price as decimal strings in place of the whole-number count and whole-cent priceCents, and a position is one signed row per ticker rather than a row per side.Order, fill and position reads follow the same vocabulary, and the ParlayX MCP server carries it from @parlayx/mcp 0.3.2.The field-by-field mapping, including how to translate an existing integration, is in the Kalshi guide.
Action required

Kalshi order labels must be unique account-wide

clientOrderId on POST /v1/kalshi/orders is sent to Kalshi as the order’s own identifier.A label must be unique across everything trading under the same Kalshi account, not only across your own orders. Each value is spent at first use and is never freed, including after the order carrying it is filled or cancelled, so an order under a label already used is rejected with 400 INVALID_REQUEST.Check any integration that labels Kalshi orders. Where several traders share an account, give each one its own prefix, or use a generated id. Retrying an unresolved order with the same Idempotency-Key and the same body still replays.Field rules are in the Kalshi guide.
New

ProphetX batch submit

POST /v1/prophetx/orders/batch submits up to 20 GTC orders in one request, under one idempotency key, each with its own outcome. FOK and GTD are supported on the single order endpoint only. The next @parlayx/sdk and parlayx releases add it.See the API reference and the ProphetX guide.
New

Polymarket batch submit

POST /v1/polymarket/orders/batch places up to 15 orders in one request, instead of one call per order. Both sides of a quote go out under a single signature, so they reach the venue together rather than seconds apart.The batch carries one Idempotency-Key, and each order gets its own outcome, so one bad entry does not discard the rest. The response lists one result per entry in request order, and each result says whether that entry was accepted.See the API reference and the Polymarket guide.
New

Kalshi batch submission

POST /v1/kalshi/orders/batch places up to 20 orders in one request under one Idempotency-Key header. Each entry gets its own outcome, so one refused entry does not fail the others.See the Kalshi guide.
New

Kalshi queue positions

GET /v1/kalshi/orders/queue-positions returns the contracts ahead of each of your resting orders in price-time priority, a page at a time. The single order read carries the same figure as queuePosition.See the Kalshi guide.
Action required

Polymarket market buys use dollar amounts

POST /v1/polymarket/orders accepts amount in dollars for a market BUY and no longer accepts size on a market order. maxFillPrice remains an optional per-share ceiling.For a limit BUY, continue to send size in outcome shares with price. For a market SELL, continue to send amount, which is measured in outcome shares.Check integrations that submit a Polymarket market order with size and move the intended maximum spend to amount before upgrading either SDK.See the Polymarket order reference.
New

ProphetX bulk cancel

DELETE /v1/prophetx/orders cancels your resting ProphetX orders in a single request, instead of one call per order. @parlayx/sdk and Python parlayx carry it.
  • Send it with no scope to sweep the orders you have resting, up to 100 per request.
  • ?strikeId= narrows the sweep to one strike.
  • When nextPageToken comes back there is more to cancel. Call again with ?pageToken=, keeping the same scope you started with, until no token comes back.
A sweep covers one pod, and within it only the trader whose key signs the request. Orders placed by another trader on the same pod are never touched, and neither are orders on your other pods. It also works from the book as it stood when you started, so an order you place part way through a paged sweep is not one of its candidates.A partial outcome is normal and still returns 200. Orders confirmed cancelled come back in cancelled. The rest come back in notCancelled with a code. STILL_SUBMITTING and ALREADY_COMPLETED describe an order the request reached, while UNCONFIRMED also covers one it did not reach, which a following page will take. Either way an order in notCancelled may still be resting at the venue, so page to the end and read it before treating that exposure as closed.See the API reference.
New

Amend and decrease resting Kalshi orders

POST /v1/kalshi/orders/{orderId}/amend reprices or resizes a resting Kalshi order in place. Send the terms you want the order to hold: count is the order’s already filled count plus the resting count you want after the amend, not the resting count on its own.POST /v1/kalshi/orders/{orderId}/decrease reduces a resting order to an absolute remaining count. remainingCount is the size to leave resting.An amend to the terms the order already holds answers 200 with the order unchanged. A decrease naming more contracts than the order has resting answers 400.Request and response fields are in the amend and decrease references.
Action required

An immediate order reports SUBMITTED, not OPEN

An order placed with an immediate-or-cancel time in force (FOK or FAK on Polymarket and Limitless, IOC or FOK on Kalshi) reports status SUBMITTED while it is live at the venue. It reported OPEN before. Such an order has no remainder that can rest, so it is not cancellable, and OPEN now means resting and cancellable on every order feed and every order detail read.Check anywhere you branch on OPEN. If you use it to detect that the venue has the order, use SUBMITTED as well, or read venueOrderId, which is set either way.The status query parameter on the order list routes is unchanged: it matches the order’s state at the venue, so an immediate order still live there matches OPEN while reporting SUBMITTED.The status values are listed on the order list reference.
Action required

The Kalshi cancel names its refusals

DELETE /v1/kalshi/orders/{orderId} answers 409 with code ORDER_NOT_CANCELLABLE when the order cannot be cancelled from its current state. Most often the cancel arrives while the order is still being placed, so there is no venue order to address yet. Read the order and retry once it reports a venue id.A cancel that does not complete answers 503. Bound any retry rather than repeating indefinitely.Check your handling of this route: if you retry on 500, move that to 503 and give it a limit, and treat 409 as terminal for the attempt. The 503 carries code INTERNAL_ERROR, the same code a 500 carries, so branch on the status rather than the code.See the API reference.
Action required

Limitless position size is bounded by the on-chain balance

size on GET /v1/limitless/positions never exceeds the pod’s on-chain balance for the token, so it can no longer overstate what the pod holds. That bound is pod-wide and spans the pod’s wallets, so where several keys trade one token it is not on its own a guarantee that a sell of that size fills. Expect size, valueUsd and unrealizedPnlUsd on an existing position to move down.A position is listed only while that balance can be read, so a row may be absent for a position you still hold. Treat a position that disappears from this view as unknown, not as closed, and confirm a close through the order that made it.See the API reference.
New

ProphetX trading

Order reads and both cancellations are scoped to the trader whose key signs the request, and manage individual orders and that trader’s resting orders on one strike.timeInForce: { type: "FOK" } requests the venue’s fill-or-kill, which cancels an unmatched order at the venue after about two seconds. postOnly: true is accepted with GTC and GTD, and refused with FOK.Orders are staked in dollars and priced in dollars per share. Address an outcome by the strikeId that GET /v1/sports/events/{eventId}/markets already returns. These endpoints answer 404 for an account that does not have ProphetX available. Contact support if you need access.@parlayx/sdk and Python parlayx expose these operations through client.prophetx.See the ProphetX reference and Venues.
New

Kalshi bulk cancellation

DELETE /v1/kalshi/orders cancels your resting Kalshi orders in one request. Pass ticker to narrow the request to one market. The response lists confirmed cancellations in cancelled and orders that remain live in notCancelled.When nextPageToken is present, send it back with the same ticker to continue through the remaining orders. @parlayx/sdk and Python parlayx expose the operation through client.kalshi.See the API reference.
Action required

Stream values are uppercase

Every value on the market data stream is uppercase, matching the REST surface: the frame type, channels, venue, book level side, takerSide, market status, the goodbye reason, a Limitless kind and the Kalshi side. A market you subscribe to carries POLYMARKET rather than polymarket.Update any subscribe frame that sends a value in the old spelling. A frame carrying one fails validation, so the whole frame is refused with an error carrying the code INTERNAL and the message invalid client frame, and none of the markets in that batch are subscribed. The subscribed, unsubscribed and error frames echo the market back in uppercase, so update any code that matches on the echoed value.@parlayx/sdk and Python parlayx follow the same rule, including the SDK’s event names and its subscription types.The values are listed per frame in Message types, and market shapes are in Subscriptions & markets.
New

Limitless trading

@parlayx/sdk and Python parlayx expose these operations through client.limitless.Sizing rules, fill-price bounds, self-trade prevention and position semantics are in the Limitless guide.
New

Polymarket bulk cancel

DELETE /v1/polymarket/orders cancels your resting Polymarket orders in a single request, instead of one call per order.
  • Send it with no scope to cancel everything you have resting.
  • ?tokenId= narrows it to one outcome.
  • ?conditionId= narrows it to one market, covering both outcomes in the same call so the book is never left one-sided between two requests.
The cancel is scoped to the trader whose key signs it. Orders placed by another trader on the same pod are never touched.A partial outcome is normal and still returns 200. Orders that were cancelled come back in cancelled, and every order still live comes back in notCancelled with a code: STILL_SUBMITTING, ALREADY_COMPLETED, VENUE_DECLINED, MARKET_UNRESOLVED or UNCONFIRMED.See the API reference.
New

Kalshi order controls

POST /v1/kalshi/orders accepts these controls:Each is optional, and an order that sets none behaves exactly as before.Field semantics are in the API reference.
New

Python SDK

parlayx is a Python client for the ParlayX API, covering the same surface as the TypeScript SDK:The SDK docs now carry Python alongside TypeScript.
Action required

Request rate limits

The REST API enforces a request budget per organization: 10 requests per second with a burst of 20, shared by every API key your organization holds. Ask us if you need more.Check that your integration handles 429. A request beyond your budget returns 429 with the code RATE_LIMITED and a Retry-After header in seconds; a client that treats any non-2xx as fatal, or that retries without honoring Retry-After, needs updating.Every authenticated response also carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset, so you can slow down before being refused.Details in Rate limits.
New

TypeScript SDK and MCP server

Two ways to call the API without writing signed HTTP yourself. Both are MIT licensed and sign requests with your Ed25519 key.

TypeScript SDK

@parlayx/sdk covers the whole current surface, with typed requests and responses generated from the API contract:
  • npm install @parlayx/sdk
  • Venue-scoped methods under client.polymarket and client.kalshi, discovery and authentication at the top level.
  • A separate @parlayx/sdk/stream export for the market data stream.
See the SDK docs.

MCP server

@parlayx/mcp gives an MCP client such as Claude Code or Codex read access to your account and the markets:
  • npx -y @parlayx/mcp
  • Seventeen read tools for identity, discovery, orders, fills, positions and balances.
  • Four trading tools that stay unregistered until you set PARLAYX_MCP_ALLOW_TRADING=1 with a key that carries the trade capability.
It runs on your own machine and reads your key from your client’s env block.See the MCP docs.
Action required

Polymarket orderbook subscriptions move to tokenId

A Polymarket market on the /v1/orderbook stream is now addressed by tokenId rather than outcomeId. It is the same ERC-1155 token id; only the field name changes, so it matches what the Markets API already returns as the listing’s tokenId.
  • outcomeId alone is rejected. A subscribe frame carrying it fails validation, and because a frame is validated as a whole, the other markets in that batch are rejected with it.
  • The rejection arrives as an error frame with code: "INTERNAL" and message: "invalid client frame", carrying your requestId but no market, since there is no valid market to echo. It does not name the offending field, so if you see that pair while migrating, check for outcomeId on a polymarket entry first.
  • Sending both keys is accepted during a migration: tokenId is read and outcomeId is ignored.
Market shapes are in Subscriptions & markets.
New

Kalshi on the market data stream

Kalshi markets are subscribable on the /v1/orderbook stream, on both the book and trade channels.
  • Address a market by its ticker: { "venue": "kalshi", "ticker": "KXNBA-25-LAL" }.
  • The book and trade tape are YES-priced. There is no separately subscribable NO book; you derive it from the YES book.
  • The optional side accepts "yes" only. A subscribe naming "no" returns UNKNOWN_MARKET.
Addressing, the NO derivation with a worked example, and the trade tape fields are in Subscriptions & markets and Trades channel.
Action required

Balance available excludes cash on resting orders

GET /v1/polymarket/balance and GET /v1/kalshi/balance report available net of the cash committed to your resting buy orders.available is now the amount you can commit beyond the orders you already have resting.On GET /v1/polymarket/balance, total keeps its previous value. Because of that, available, unconverted and claimable no longer add up to total: the difference is the committed collateral, which the endpoint does not publish as its own field.What to check: any order sizing that reads available on either endpoint (it now leaves your resting orders funded, so a size derived from it will be smaller), and any reconciliation that adds the Polymarket components and compares the result to total.Field semantics and units are in the API reference for Polymarket and Kalshi.
New

Positions

Your open positions are now readable per venue. Each row carries your weighted-average entry price, an indicative mark, current value, and unrealized P&L.

Polymarket

  • GET /v1/polymarket/positions returns one row per outcome token, ordered by tokenId. Pass tokenId= to filter.

Kalshi

  • GET /v1/kalshi/positions returns one row per market ticker and side, ordered by ticker then side. Pass ticker= to filter.
See the API reference for Polymarket and Kalshi.
New

Public API baseline

The baseline of everything documented on this site today: REST trading and discovery endpoints, and the real-time market data stream.

Authentication

Signed-request authentication for every endpoint, plus two utility routes:
  • GET /v1/whoami verifies your key and returns the calling identity.
  • GET /v1/time returns the server time for request signing.

Discovery

Browse the cross-venue market catalog:

Polymarket trading

Venue-explicit order management and balance:

Kalshi trading

The same order lifecycle, in Kalshi’s own vocabulary (ticker, side, action, count, priceCents):

WebSocket market data

The /v1/orderbook stream delivers order book snapshots, incremental deltas, and trades, with subscription management over a single authenticated connection.See the streaming overview to get started.