Skip to content

perps: [EPIC] Perps (margin) API — full SDK implementation tracker #387

Description

@TexasCoding

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 on KalshiClient). Own base URL, own PerpsConfig, separate env-var credentials. Reuse KalshiAuth (RSA-PSS) + SyncTransport/AsyncTransport + retry/error machinery unchanged. (Rationale: different host + Kalshi recommends separate API keys; KalshiConfig hard-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 flow kalshi/perps/__init__.pykalshi/__init__.py.
  • Reuse DollarDecimal + FixedPointCount from kalshi/types.py: perps FixedPointDollars (string, ≤6 dp) and FixedPointCount (string "fp", 2 dp) have identical semantics. Prices/counts use them with validation_alias=AliasChoices(...) for API↔Python name mapping.
  • Timestamps: REST = RFC3339 date-time; WebSocket = Unix epoch milliseconds with _ms suffix (ts_ms, created_ts_ms) — a real parsing difference from the event-contract WS.
  • Request bodies = Pydantic models with model_config = {"extra": "forbid"}, serialized via model_dump(exclude_none=True, by_alias=True, mode="json"); serialization_alias for wire mismatches. POST/PUT/DELETE never retried.
  • Contract tests parameterized per-spec: perps REST validates against specs/perps_openapi.yaml, SCM against specs/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
Loading

Implementation checklist

Foundation (do first)

REST resources (depend on #388, parallelizable)

WebSocket (after REST foundation)

SCM / Klear (new session+MFA auth)

Closeout

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

No one assigned

    Labels

    enhancementNew feature or requestperpsPerps / margin (perpetual futures) API

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions