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 oneside, 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
nextPageTokencomes back there is more to cancel. Call again with?pageToken=, keeping the same scope you started with, until no token comes back.
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 frametype, 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.
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
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 handles429. 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.polymarketandclient.kalshi, discovery and authentication at the top level. - A separate
@parlayx/sdk/streamexport for the market data stream.
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=1with a key that carries thetradecapability.
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.outcomeIdalone is rejected. Asubscribeframe 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
errorframe withcode: "INTERNAL"andmessage: "invalid client frame", carrying yourrequestIdbut nomarket, since there is no valid market to echo. It does not name the offending field, so if you see that pair while migrating, check foroutcomeIdon apolymarketentry first. - Sending both keys is accepted during a migration:
tokenIdis read andoutcomeIdis ignored.
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
sideaccepts"yes"only. A subscribe naming"no"returnsUNKNOWN_MARKET.
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/positionsreturns one row per outcome token, ordered bytokenId. PasstokenId=to filter.
Kalshi
GET /v1/kalshi/positionsreturns one row per market ticker and side, ordered bytickerthenside. Passticker=to filter.
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/whoamiverifies your key and returns the calling identity.GET /v1/timereturns 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.