Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 0 additions & 61 deletions .github/workflows/claude-code-review.yml

This file was deleted.

54 changes: 0 additions & 54 deletions .github/workflows/claude.yml

This file was deleted.

39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,45 @@

All notable changes to kalshi-sdk will be documented in this file.

## 7.2.0 — 2026-07-22

Reconciles upstream OpenAPI/perps OpenAPI drift under version string **3.25.0**
(Closes #481, #482). Soft-deprecation + defensive model relaxations only — no
breaking public-API removals.

### Deprecated

- **`PerpsClient.orders.list_fcm()` / `list_all_fcm()`** (sync + async) now emit
a `DeprecationWarning`. Kalshi removed `GET /margin/fcm/orders` from the
perps OpenAPI, so the live endpoint may 404. Methods are **retained**
(soft-deprecated) pending confirmation the removal is permanent — same
pattern as `exchange.announcements()` after 3.24.0.

### Changed

- **`SubaccountTransfer` is cash-only on the wire.** Upstream dropped
`transfer_type` (was required) and the position-only fields
(`market_ticker`, `side`, `count`, `price`) from
`GET /portfolio/subaccounts/transfers`. Position moves remain on
`POST /portfolio/subaccounts/positions/transfer`
(`transfer_position()`). Dropped fields are **defensively optional** on the
SDK model so lagging payloads still parse; new responses omit them.
`transfer_type` is now `Literal["cash", "position"] | None` (default
`None`).

### Spec notes

- Core OpenAPI `info.version` still `3.25.0` (content-only change; paths 91→91,
102 operations / 101 mapped).
- Perps OpenAPI: removed `GET /margin/fcm/orders` and the `fcm` tag (paths
32→31, operations 35→34). Perps AsyncAPI / SCM specs unchanged.

### Infra

- Removed Claude Code Action workflows (`claude-code-review.yml`,
`claude.yml`) — the automated review check was failing CI without adding
required signal.

## 7.1.0 — 2026-07-17

Syncs the upstream OpenAPI/AsyncAPI specs **3.24.0 → 3.25.0** (Closes #475).
Expand Down
9 changes: 2 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,8 @@ If your change adds a new endpoint, register it in

## Review cycle

Most PRs receive an automated code review from Claude (the
`claude-review` check). This is **advisory, not required** — it fails
by design on Dependabot PRs and on PRs that modify the review workflow
itself. When it does run, please address the substantive feedback or
reply with a brief justification for skipping it. Maintainers
squash-merge after the required CI checks are green and review is
addressed.
Maintainers squash-merge after the required CI checks are green and any
human review feedback is addressed.

## Reporting bugs / requesting features

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ A professional, spec-first Python SDK for the [Kalshi](https://kalshi.com) predi
[![Type checked: mypy strict](https://img.shields.io/badge/mypy-strict-blue.svg)](https://mypy.readthedocs.io/)

- **Full coverage** of the Kalshi REST API (101 operations across 19 resources, OpenAPI v3.25.0) and WebSocket API (12 typed `subscribe_*` channels + 2 escape-hatch).
- **Perps (margin) API**: standalone `PerpsClient` / `AsyncPerpsClient` + `PerpsWebSocket` for the perpetual-futures exchange (35 REST operations, 6 WS channels), plus a `KlearClient` for the Self-Clearing-Member "Klear" settlement API (11 operations). See [Perps (margin) trading](#perps-margin-trading).
- **Perps (margin) API**: standalone `PerpsClient` / `AsyncPerpsClient` + `PerpsWebSocket` for the perpetual-futures exchange (34 REST operations, 6 WS channels), plus a `KlearClient` for the Self-Clearing-Member "Klear" settlement API (11 operations). See [Perps (margin) trading](#perps-margin-trading).
- **FIX protocol**: an async-first FIX engine (FIXT.1.1 / FIX50SP2) for both products — order-entry, drop-copy, market-data, post-trade (prediction), and RFQ (prediction) sessions (plus order-group management over the order-entry session) with typed message models, sequence recovery, and order-book / settlement reassembly. `from kalshi import FixClient` / `MarginFixClient`. See [FIX protocol](#fix-protocol-low-latency-trading).
- **V2 event-market orders**: `create_v2` / `amend_v2` / `decrease_v2` / `cancel_v2` plus batched variants on `/portfolio/events/orders/*` — the only order-write surface.
- **Funding & cost introspection**: `portfolio.deposits()`, `portfolio.withdrawals()`, `account.endpoint_costs()`.
Expand Down
5 changes: 5 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Shipped

- **v7.2.0 (2026-07-22)** — Spec-drift reconcile under OpenAPI 3.25.0
(#481 / #482 / #483). Soft-deprecate perps `orders.list_fcm` /
`list_all_fcm` (upstream removed `GET /margin/fcm/orders`).
`SubaccountTransfer` cash-only on the wire (`transfer_type` + position
fields defensive-optional). Removed Claude Code Action CI workflows.
- **v7.1.0 (2026-07-17)** — OpenAPI sync v3.24.0 → v3.25.0 (#475 / #476).
Additive: `MarginMarket.schedule` + nested `MarginMarketSchedule` (null for
24/7 markets). Core `POST /portfolio/intra_exchange_instance_transfer`
Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Out of scope:
- Spec-sync workflow runs with `contents: read` only; it cannot push,
open PRs, or execute upstream-derived Python.
- Third-party Actions SHA-pinned in workflows that hold elevated
permissions (release, spec-sync, claude review).
permissions (release, spec-sync).
- RSA-PSS request signing with timestamp; signatures rejected if
clock-skew exceeds the API's tolerance.

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ markets API.
backpressure strategies, and an in-memory orderbook builder. Async-only —
access via `AsyncKalshiClient.ws`.
- **Perps (margin) API** — standalone `PerpsClient` / `AsyncPerpsClient` +
`PerpsWebSocket` for the perpetual-futures exchange (35 REST operations, 6 WS
`PerpsWebSocket` for the perpetual-futures exchange (34 REST operations, 6 WS
channels), and a `KlearClient` for the Self-Clearing-Member settlement API
(11 operations, Bearer token auth). See [Perps](perps.md).
- **FIX protocol** — a hand-rolled, async-first FIX engine (FIXT.1.1 / FIX50SP2)
Expand Down
52 changes: 52 additions & 0 deletions docs/migration.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,57 @@
# Migration

## v7.1 → v7.2.0

Reconciles in-place OpenAPI/perps OpenAPI edits under version string **3.25.0**
(no `info.version` bump upstream). **No breaking public-API removals** —
one soft-deprecation and a defensive model relaxation.

### Deprecated: `PerpsClient.orders.list_fcm()` / `list_all_fcm()`

Kalshi removed `GET /margin/fcm/orders` from the perps OpenAPI, so the live
endpoint may 404. The methods (sync + async) are **retained** and emit a
`DeprecationWarning` on each call — same soft-deprecation pattern as
`exchange.announcements()` after 3.24.0. A future major release removes them
once the removal is confirmed permanent.

```python
# Still callable, but warns and may 404:
# perps.orders.list_fcm(subtrader_id="...")
# list(perps.orders.list_all_fcm(subtrader_id="..."))
```

Prediction-API FCM routes (`client.fcm.orders` / `client.fcm.positions` on
`/fcm/*`) are **unchanged**.

### Changed: `SubaccountTransfer` is cash-only on the wire

`GET /portfolio/subaccounts/transfers` no longer returns position-transfer
rows. Upstream dropped `transfer_type` and the position-only fields
(`market_ticker`, `side`, `count`, `price`) from the schema.

- New responses omit those fields; `t.transfer_type` is `None` unless a lagging
server still sends it.
- Position moves continue via `subaccounts.transfer_position()` (and its
request/response models) — not via the transfers list.
- The SDK keeps the dropped fields as **optional** so older payloads still
parse (defensive optional-ization).

```python
page = client.subaccounts.list_transfers()
for t in page:
# cash row only
print(t.transfer_id, t.amount_cents, t.from_subaccount, t.to_subaccount)
# t.transfer_type may be None (no longer required on the wire)
```

### Infra

Claude Code Action workflows (`claude-review` / `@claude`) were removed from
CI; they are not part of the public SDK surface.

See the [changelog](https://github.com/TexasCoding/kalshi-python-sdk/blob/main/CHANGELOG.md)
for the full list.

## v7.0 → v7.1.0

Syncs the SDK to OpenAPI/AsyncAPI spec **3.25.0**. **No breaking changes.**
Expand Down
9 changes: 8 additions & 1 deletion docs/perps.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ async with AsyncPerpsClient.from_env(demo=True) as perps:
|---|---|
| `exchange` | `status()`, `enabled()` (per-member access gate), `risk_parameters()` |
| `markets` | `list()`, `get()`, `orderbook()`, `candlesticks()` |
| `orders` | `create()`, `get()`, `list()` / `list_all()`, `cancel()`, `decrease()`, `amend()`, `list_fcm()` / `list_all_fcm()` |
| `orders` | `create()`, `get()`, `list()` / `list_all()`, `cancel()`, `decrease()`, `amend()` |
| `order_groups` | `list()`, `get()`, `create()`, `delete()`, `reset()`, `trigger()`, `update_limit()` |
| `portfolio` | `positions()`, `fills()` / `fills_all()`, `trades()` / `trades_all()` |
| `margin` | `balance()`, `risk()`, `notional_risk_limit()`, `fee_tiers()`, `api_limits()` |
Expand All @@ -70,6 +70,13 @@ async with AsyncPerpsClient.from_env(demo=True) as perps:
The margin order side is `bid` / `ask` (not the prediction API's `yes` / `no`).
Orders create/cancel/decrease/amend are POSTs/DELETEs and are **never retried**.

!!! warning "Deprecated in v7.2.0 — `list_fcm` / `list_all_fcm`"
Kalshi removed `GET /margin/fcm/orders` from the perps OpenAPI. The SDK
methods still exist (sync + async) but emit a `DeprecationWarning` and may
404 against the live API. They will be removed in a future major release
once the removal is confirmed permanent. Prediction-API FCM
(`client.fcm.*` on `/fcm/*`) is unchanged.

## Value types & timestamps

- Prices are `DollarDecimal` — `FixedPointDollars` strings with up to 6 decimal
Expand Down
3 changes: 2 additions & 1 deletion docs/resources/subaccounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ for t in client.subaccounts.list_all_transfers():
```

Standard `Page[SubaccountTransfer]` pagination. `t.created_ts` is Unix
seconds.
seconds. Rows are **cash transfers only** — position moves use
`transfer_position()` and are not listed here.

## Netting

Expand Down
2 changes: 1 addition & 1 deletion kalshi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,4 +379,4 @@
"Withdrawal",
]

__version__ = "7.1.0"
__version__ = "7.2.0"
23 changes: 13 additions & 10 deletions kalshi/models/subaccounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,29 +125,32 @@ class GetSubaccountBalancesResponse(BaseModel):


class SubaccountTransfer(BaseModel):
"""A past transfer between subaccounts.
"""A past **cash** transfer between subaccounts.

``created_ts`` is a Unix seconds integer per spec (``format: int64``),
matching ``SubaccountBalance.updated_ts``. This is intentionally
different from RFQ/Quote timestamps, which are ISO datetime strings.

Spec v3.23.0 split transfers into two kinds via ``transfer_type``: ``cash``
(money moved; ``amount_cents`` set) and ``position`` (contracts moved). The
``market_ticker`` / ``side`` / ``count`` / ``price`` fields are populated only
for ``position`` transfers, so they are optional here. Spec v3.24.0 renamed the
per-contract ``price_cents`` (integer cents) → ``price``
(``FixedPointDollars``), surfacing as a ``Decimal`` in dollars.
Spec sync (in-place edit under OpenAPI 3.25.0, 2026-07-20/21) narrowed
``GET /portfolio/subaccounts/transfers`` to cash rows only. Upstream
dropped ``transfer_type`` and the position-only fields
(``market_ticker`` / ``side`` / ``count`` / ``price``) from this schema.
Position moves use :class:`ApplySubaccountPositionTransferRequest` /
:class:`ApplySubaccountPositionTransferResponse` on
``POST /portfolio/subaccounts/positions/transfer`` — they are not listed
here. Fields removed from the wire schema are retained as optional
(defensive optional-ization) so payloads from lagging servers still parse;
new responses omit them.
"""

transfer_id: str
from_subaccount: int
to_subaccount: int
amount_cents: int
created_ts: int
# Spec v3.23.0 required additions.
exchange_index: int
transfer_type: Literal["cash", "position"]
# Position-transfer-only fields (absent on cash transfers).
# Soft-kept after upstream removal from SubaccountTransfer (cash-only list).
transfer_type: Literal["cash", "position"] | None = None
market_ticker: str | None = None
side: Literal["yes", "no"] | None = None
count: int | None = None
Expand Down
2 changes: 1 addition & 1 deletion kalshi/perps/models/orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ class GetMarginOrderResponse(BaseModel):


class GetMarginOrdersResponse(BaseModel):
"""Paginated envelope for ``GET /margin/orders`` and ``GET /margin/fcm/orders``.
"""Paginated envelope for ``GET /margin/orders`` (and soft-deprecated FCM list).

Spec ``GetMarginOrdersResponse`` (line 1759). ``cursor`` drives
``list_all()`` / ``list_all_fcm()``.
Expand Down
Loading
Loading