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
98 changes: 72 additions & 26 deletions docs/resources/communications.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,33 @@ answer. The requester accepts a side; the maker confirms; the trade settles.

Auth required throughout.

!!! warning "Deprecated since v3.0.0"
The flat method names (`list_rfqs`, `get_rfq`, `create_rfq`, `delete_rfq`,
`list_all_rfqs`, `list_quotes`, `get_quote`, `create_quote`,
`delete_quote`, `list_all_quotes`, `accept_quote`, `confirm_quote`) on
`CommunicationsResource` still work but emit `DeprecationWarning` and will
be removed in a future release. Switch to the `rfqs.` / `quotes.`
sub-namespaces documented below.

## Quick reference

| Method | Endpoint |
|---|---|
| `get_id()` | `GET /communications/id` |
| `list_rfqs(...)` / `list_all_rfqs(...)` | `GET /communications/rfqs` |
| `get_rfq(rfq_id)` | `GET /communications/rfqs/{rfq_id}` |
| `create_rfq(...)` | `POST /communications/rfqs` |
| `delete_rfq(rfq_id)` | `DELETE /communications/rfqs/{rfq_id}` |
| `list_quotes(...)` / `list_all_quotes(...)` | `GET /communications/quotes` |
| `get_quote(quote_id)` | `GET /communications/quotes/{quote_id}` |
| `create_quote(...)` | `POST /communications/quotes` |
| `delete_quote(quote_id)` | `DELETE /communications/quotes/{quote_id}` |
| `accept_quote(quote_id, *, accepted_side)` | `POST /communications/quotes/{quote_id}/accept` |
| `confirm_quote(quote_id)` | `POST /communications/quotes/{quote_id}/confirm` |
| `rfqs.list(...)` / `rfqs.list_all(...)` | `GET /communications/rfqs` |
| `rfqs.get(rfq_id)` | `GET /communications/rfqs/{rfq_id}` |
| `rfqs.create(...)` | `POST /communications/rfqs` |
| `rfqs.delete(rfq_id)` | `DELETE /communications/rfqs/{rfq_id}` |
| `quotes.list(...)` / `quotes.list_all(...)` | `GET /communications/quotes` |
| `quotes.get(quote_id)` | `GET /communications/quotes/{quote_id}` |
| `quotes.create(...)` | `POST /communications/quotes` |
| `quotes.delete(quote_id)` | `DELETE /communications/quotes/{quote_id}` |
| `quotes.accept(quote_id, *, accepted_side)` | `POST /communications/quotes/{quote_id}/accept` |
| `quotes.confirm(quote_id)` | `POST /communications/quotes/{quote_id}/confirm` |

`get_id()` returns your `participant_id` — the value you'll pass as
`quote_creator_user_id` / `rfq_creator_user_id` when filtering lists.
`quote_creator_user_id` / `rfq_creator_user_id` when filtering lists. It stays
at the top level because it has no sub-noun.

## Requester flow

Expand All @@ -32,20 +41,22 @@ Auth required throughout.
me = client.communications.get_id()

# 1) Post an RFQ asking for a price on 500 contracts.
rfq = client.communications.create_rfq(
rfq = client.communications.rfqs.create(
market_ticker="KXPRES-24-DJT",
contracts=500,
rest_remainder=True,
)
print(rfq.rfq.rfq_id)

# 2) Poll for incoming quotes (or subscribe to the `communications` WS channel).
quotes = client.communications.list_quotes(rfq_creator_user_id=me.user_id)
quotes = client.communications.quotes.list(rfq_creator_user_id=me.user_id)
for q in quotes:
print(q.quote_id, q.yes_bid, q.no_bid)

# 3) Accept a side on one of them.
accepted = client.communications.accept_quote(quotes.items[0].quote_id, accepted_side="yes")
accepted = client.communications.quotes.accept(
quotes.items[0].quote_id, accepted_side="yes"
)
```

## Maker flow
Expand All @@ -54,11 +65,11 @@ accepted = client.communications.accept_quote(quotes.items[0].quote_id, accepted
me = client.communications.get_id()

# 1) Watch for incoming RFQs.
for rfq in client.communications.list_all_rfqs(status="open"):
for rfq in client.communications.rfqs.list_all(status="open"):
print(rfq.rfq_id, rfq.market_ticker, rfq.contracts)

# 2) Quote one.
resp = client.communications.create_quote(
resp = client.communications.quotes.create(
rfq_id="rfq_abc",
yes_bid="0.60",
no_bid="0.40",
Expand All @@ -67,11 +78,11 @@ resp = client.communications.create_quote(

# 3) Wait for the counterparty to accept.
# 4) Confirm to lock the fill.
client.communications.confirm_quote(resp.quote.quote_id)
client.communications.quotes.confirm(resp.quote.quote_id)
```

!!! warning "`list_quotes` requires a user-id filter"
`list_quotes` and `list_all_quotes` **must** be called with at least one of:
!!! warning "`quotes.list` requires a user-id filter"
`quotes.list` and `quotes.list_all` **must** be called with at least one of:

- `quote_creator_user_id=` (filter to a specific quoter)
- `rfq_creator_user_id=` (filter to a specific RFQ originator)
Expand All @@ -87,15 +98,15 @@ client.communications.confirm_quote(resp.quote.quote_id)

```python
# All quotes you made — no get_id() needed.
for q in client.communications.list_all_quotes(user_filter="self"):
for q in client.communications.quotes.list_all(user_filter="self"):
print(q.quote_id, q.yes_bid)

# All quotes against RFQs you originated.
for q in client.communications.list_all_quotes(rfq_user_filter="self"):
for q in client.communications.quotes.list_all(rfq_user_filter="self"):
...

# Same shortcut on RFQs:
for rfq in client.communications.list_all_rfqs(user_filter="self"):
for rfq in client.communications.rfqs.list_all(user_filter="self"):
...
```

Expand All @@ -105,11 +116,11 @@ upgrade.

## Post-only quotes

`create_quote()` accepts `post_only=True` (added in v2.1.0) to ensure your
`quotes.create()` accepts `post_only=True` (added in v2.1.0) to ensure your
resting order is canceled rather than crossed if it would take liquidity:

```python
client.communications.create_quote(
client.communications.quotes.create(
rfq_id="rfq_abc",
yes_bid="0.60", no_bid="0.40",
rest_remainder=True,
Expand All @@ -118,7 +129,7 @@ client.communications.create_quote(
```

!!! info "Delete is not server-idempotent"
`delete_rfq(rfq_id)` and `delete_quote(quote_id)` propagate a 404 as
`rfqs.delete(rfq_id)` and `quotes.delete(quote_id)` propagate a 404 as
`KalshiNotFoundError` when the RFQ or quote is already canceled,
expired, or never existed. The SDK does **not** swallow it — the caller
owns safe-retry idempotency:
Expand All @@ -127,7 +138,7 @@ client.communications.create_quote(
from kalshi.errors import KalshiNotFoundError

try:
client.communications.delete_rfq(rfq_id)
client.communications.rfqs.delete(rfq_id)
except KalshiNotFoundError:
pass # already canceled — idempotent
```
Expand All @@ -137,12 +148,47 @@ client.communications.create_quote(
`open`, `accepted`, `confirmed`, `canceled`. Status filtering accepts these
literal strings.

## Migrating from v2.x

| v2.x (deprecated) | v3.0.0 (canonical) |
|---|---|
| `client.communications.list_rfqs(...)` | `client.communications.rfqs.list(...)` |
| `client.communications.list_all_rfqs(...)` | `client.communications.rfqs.list_all(...)` |
| `client.communications.get_rfq(rfq_id)` | `client.communications.rfqs.get(rfq_id)` |
| `client.communications.create_rfq(...)` | `client.communications.rfqs.create(...)` |
| `client.communications.delete_rfq(rfq_id)` | `client.communications.rfqs.delete(rfq_id)` |
| `client.communications.list_quotes(...)` | `client.communications.quotes.list(...)` |
| `client.communications.list_all_quotes(...)` | `client.communications.quotes.list_all(...)` |
| `client.communications.get_quote(quote_id)` | `client.communications.quotes.get(quote_id)` |
| `client.communications.create_quote(...)` | `client.communications.quotes.create(...)` |
| `client.communications.delete_quote(quote_id)` | `client.communications.quotes.delete(quote_id)` |
| `client.communications.accept_quote(quote_id, accepted_side=...)` | `client.communications.quotes.accept(quote_id, accepted_side=...)` |
| `client.communications.confirm_quote(quote_id)` | `client.communications.quotes.confirm(quote_id)` |

`get_id()` is unchanged.

## Reference

::: kalshi.resources.communications.CommunicationsResource
options:
heading_level: 3

::: kalshi.resources.communications.RFQsResource
options:
heading_level: 3

::: kalshi.resources.communications.QuotesResource
options:
heading_level: 3

::: kalshi.resources.communications.AsyncCommunicationsResource
options:
heading_level: 3

::: kalshi.resources.communications.AsyncRFQsResource
options:
heading_level: 3

::: kalshi.resources.communications.AsyncQuotesResource
options:
heading_level: 3
9 changes: 8 additions & 1 deletion docs/resources/markets.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ recent trades.
| `bulk_candlesticks(*, market_tickers, ...)` | `GET /markets/candlesticks` | no |
| `bulk_orderbooks(*, tickers)` | `GET /markets/orderbooks` | **yes** |
| `list_trades(...)` | `GET /markets/trades` | no |
| `list_trades_all(...)` | walks `list_trades` | no |
| `list_all_trades(...)` | walks `list_trades` | no |

!!! warning "Orderbook endpoints require auth"
`orderbook()` and `bulk_orderbooks()` raise `AuthRequiredError` on an
Expand Down Expand Up @@ -130,6 +130,13 @@ for trade in page:
print(trade.trade_id, trade.taker_side, trade.yes_price, trade.count)
```

!!! warning "Deprecated since v3.0.0"
`list_trades_all` is the legacy name; it still works but emits
`DeprecationWarning` and will be removed in a future release. Use
`list_all_trades` instead — see [#349][issue-349].

[issue-349]: https://github.com/TexasCoding/kalshi-python-sdk/issues/349

## Reference

::: kalshi.resources.markets.MarketsResource
Expand Down
10 changes: 10 additions & 0 deletions kalshi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@
WeeklySchedule,
Withdrawal,
)
from kalshi.resources.communications import (
AsyncQuotesResource,
AsyncRFQsResource,
QuotesResource,
RFQsResource,
)
from kalshi.types import NullableList, StrictInt

__all__ = [
Expand All @@ -186,6 +192,8 @@
"ApplySubaccountTransferRequest",
"AssociatedEvent",
"AsyncKalshiClient",
"AsyncQuotesResource",
"AsyncRFQsResource",
"AuthRequiredError",
"Balance",
"BatchCancelOrdersRequest",
Expand Down Expand Up @@ -312,6 +320,8 @@
"PriceDistribution",
"Quote",
"QuoteStatusLiteral",
"QuotesResource",
"RFQsResource",
"RateLimit",
"RfqStatusLiteral",
"Schedule",
Expand Down
Loading
Loading