Repository navigation
Closed
Labels
enhancementNew feature or requestNew feature or requestperpsPerps / margin (perpetual futures) APIPerps / margin (perpetual futures) API
Milestone
Description
Perps (margin) API — full SDK implementation
Implements the Kalshi Perps API (perpetual futures / margin) in the SDK, mirroring the conventions of the existing prediction (event-contract) API. Source docs: https://docs.kalshi.com/margin
Surface (3 separate specs + FIX)
| Spec | Vendored to | Host | Auth | Ops |
|---|---|---|---|---|
perps_openapi.yaml (REST) |
specs/perps_openapi.yaml |
external-api.kalshi.com/trade-api/v2 (demo external-api.demo.kalshi.co) |
RSA-PSS (same signer) | 34 |
perps_asyncapi.yaml (WS) |
specs/perps_asyncapi.yaml |
external-api-margin-ws.kalshi.com/trade-api/ws/v2/margin |
RSA-PSS apiKey | 6 channels |
perps_scm_openapi.yaml (Self-Clearing-Member "Klear") |
specs/perps_scm_openapi.yaml |
api.klear.kalshi.com/klear-api/v1 (demo demo-api.kalshi.co/klear-api/v1) |
session cookie + MFA (POST /log_in) |
9 |
| FIX | — | margin-fix-api.fix.elections.kalshi.com etc. |
FIX session | deferred |
Locked architecture decisions
- Standalone
PerpsClient/AsyncPerpsClient(not a namespace onKalshiClient). Own base URL, ownPerpsConfig, separate env-var credentials. ReuseKalshiAuth(RSA-PSS) +SyncTransport/AsyncTransport+ retry/error machinery unchanged. (Rationale: different host + Kalshi recommends separate API keys;KalshiConfighard-fails on hosts outside its known set.) - New package layout
kalshi/perps/{client,async_client}.py,kalshi/perps/models/<area>.py,kalshi/perps/resources/<area>.py,kalshi/perps/ws/…— mirroring the top-level layout. Exports flowkalshi/perps/__init__.py→kalshi/__init__.py. - Reuse
DollarDecimal+FixedPointCountfromkalshi/types.py: perpsFixedPointDollars(string, ≤6 dp) andFixedPointCount(string "fp", 2 dp) have identical semantics. Prices/counts use them withvalidation_alias=AliasChoices(...)for API↔Python name mapping. - Timestamps: REST = RFC3339
date-time; WebSocket = Unix epoch milliseconds with_mssuffix (ts_ms,created_ts_ms) — a real parsing difference from the event-contract WS. - Request bodies = Pydantic models with
model_config = {"extra": "forbid"}, serialized viamodel_dump(exclude_none=True, by_alias=True, mode="json");serialization_aliasfor wire mismatches. POST/PUT/DELETE never retried. - Contract tests parameterized per-spec: perps REST validates against
specs/perps_openapi.yaml, SCM againstspecs/perps_scm_openapi.yaml. Weekly spec-sync extended to fetch all three perps specs.
Shared-primitive ownership (avoid duplicate Pydantic defs)
The shared enums/value-objects — BookSide, SelfTradePreventionType, LastUpdateReason, OrderSource, MarginMarketStatus, ExchangeIndex, ExchangeInstance, PriceLevelDollarsCountFp, EmptyResponse, ErrorResponse — are defined once by the foundation issue in kalshi/perps/models/common.py. All resource issues import them and must not redefine. (Note: perps order side is bid/ask, not the prediction API's yes/no.)
Dependency graph
graph TD
F[#388 foundation] --> EX[#389 exchange]
F --> MK[#390 markets]
F --> OR[#391 orders]
F --> OG[#392 order groups]
F --> PF[#393 positions/fills/trades]
F --> BR[#394 balance/risk/fees]
F --> FN[#395 funding]
F --> TR[#396 transfers/subaccounts]
F --> WF[#397 ws foundation]
WF --> WC[#398 ws channels]
F --> SA[#399 scm auth]
SA --> SE[#400 scm endpoints]
EX --> DOC[#401 docs/release]
MK --> DOC
OR --> DOC
OG --> DOC
PF --> DOC
BR --> DOC
FN --> DOC
TR --> DOC
WC --> DOC
SE --> DOC
Implementation checklist
Foundation (do first)
- perps: client foundation — PerpsClient/AsyncPerpsClient, PerpsConfig, spec sync & contract-test harness #388 — client foundation:
PerpsClient/AsyncPerpsClient,PerpsConfig, spec vendoring, contract-test harness parameterization,common.py
REST resources (depend on #388, parallelizable)
- perps: exchange status, enabled flag & risk parameters resource #389 — exchange status, enabled, risk parameters
- perps: markets resource — list/get, orderbook, candlesticks #390 — markets: list/get, orderbook, candlesticks
- perps: orders resource — create/get/list/cancel/decrease/amend + FCM orders #391 — orders: create/get/list/cancel/decrease/amend + FCM orders
- perps: order groups resource — create/get/list/delete/reset/trigger/update-limit #392 — order groups: create/get/list/delete/reset/trigger/update-limit
- perps: portfolio reads — positions, fills, trades #393 — portfolio reads: positions, fills, trades
- perps: balance, risk, notional risk limit & fee tiers resource #394 — balance, risk, notional risk limit, fee tiers
- perps: funding resource — rate estimate, historical rates, payment history #395 — funding: rate estimate, historical rates, payment history
- perps: transfers & subaccounts resource — intra-exchange-instance transfer, create/transfer margin subaccount #396 — transfers & subaccounts: intra-exchange-instance transfer, create/transfer subaccount
WebSocket (after REST foundation)
- perps: WebSocket foundation — connection, client, subscribe/dispatch framing, sequence/orderbook reuse #397 — WS foundation: connection, client, subscribe/dispatch framing, sequence/orderbook reuse
- perps: WebSocket channels & payload models — orderbook_delta, ticker(+funding), trade, fill, user_orders, order_group_updates #398 — WS channels & payload models: orderbook_delta, ticker(+funding), trade, fill, user_orders, order_group_updates
SCM / Klear (new session+MFA auth)
- perps: SCM/Klear auth foundation — KlearClient with session-cookie + MFA login #399 — KlearClient auth foundation: session-cookie + MFA login
- perps: SCM/Klear margin endpoints — settlement balances, obligations, margin reports #400 — SCM endpoints: settlement balances, obligations, margin reports
Closeout
- perps: docs, examples, README/CHANGELOG, demo integration tests & release closeout #401 — docs, examples, README/CHANGELOG, demo integration tests & release
Out of scope (this milestone)
- FIX API → tracked separately in perps: [EPIC] FIX API support (prediction + perps) — future #402 (covers both prediction and perps FIX gateways; large, orthogonal effort).
- Perps WS channels unavailable upstream (
market_positions,market_lifecycle_v2,multivariate*,communications) — documented, not implemented. - Batch order ops, RFQs/quotes, events/series/milestones on the margin exchange (not offered by the perps API).
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestperpsPerps / margin (perpetual futures) APIPerps / margin (perpetual futures) API
Activity
perps: address PR #403 code-review findings
Merge pull request #403 from TexasCoding/feat/perps-api
TexasCoding commentedon Jun 5, 2026
✅ Complete — shipped in v3.2.0 (published to PyPI + GitHub Release).
The full Perps (margin) API surface landed across #388–401 and was hardened through the post-review follow-ups:
PerpsClient/AsyncPerpsClient+PerpsConfig—exchange,markets,orders,order_groups,portfolio,margin,funding,transfers.PerpsWebSocketwith six typed channels (epoch-ms timestamps, sequence-gap + orderbook + backpressure machinery).KlearClient/AsyncKlearClient— cookie-session + MFA settlement API.Post-merge hardening from the multi-LLM review (closed: #404–413, plus #405 by-design): MultiplierDecimal ratio fields, NullableList null-tolerance, typed list-response envelopes (perps + prediction), config/auth hardening (
ws_base_url/passwordkwargs, host-allowlist split), Klear strict date validation, order-size guards, and WebSocket correctness fixes (stale-sid gate,_stopexception retrieval, error-ack raising, reconnect persistence). Docs + CHANGELOG finalized in #421.Closing as done. #402 remains for future API work.