Skip to content

Communications (RFQ / Quote)

Kalshi's bilateral block-trade rail. An RFQ is a private "make me a market on this contract at this size?" message; a Quote is a counterparty's answer. The requester accepts a side; the maker confirms; the trade settles.

Auth required throughout.

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

get_id() returns your participant_id — the value you'll pass as quote_creator_user_id / rfq_creator_user_id when filtering lists.

Requester flow

# Identify yourself for filtering downstream.
me = client.communications.get_id()

# 1) Post an RFQ asking for a price on 500 contracts.
rfq = client.communications.create_rfq(
    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)
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")

Maker flow

me = client.communications.get_id()

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

# 2) Quote one.
resp = client.communications.create_quote(
    rfq_id="rfq_abc",
    yes_bid="0.60",
    no_bid="0.40",
    rest_remainder=False,
)

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

list_quotes requires a user-id filter

list_quotes and list_all_quotes 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)
  • user_filter="self" (server-side shorthand for "the caller's quotes")
  • rfq_user_filter="self" (server-side shorthand for "quotes on the caller's RFQs")

user_filter / rfq_user_filter were added in spec v3.18.0 and let you avoid round-tripping get_id() first. Passing rfq_id= alone raises ValueError locally before the round trip — this enforces a server-side requirement.

Filtering shortcuts (v2.1.0)

# All quotes you made — no get_id() needed.
for q in client.communications.list_all_quotes(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"):
    ...

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

UserFilterLiteral only accepts "self" today — the spec leaves room for server-side shorthands like "organization" in the future without an SDK upgrade.

Post-only quotes

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

client.communications.create_quote(
    rfq_id="rfq_abc",
    yes_bid="0.60", no_bid="0.40",
    rest_remainder=True,
    post_only=True,    # cancel rather than cross
)

RFQ statuses

open, accepted, confirmed, canceled. Status filtering accepts these literal strings.

Reference

kalshi.resources.communications.CommunicationsResource

CommunicationsResource(transport: SyncTransport)

Bases: SyncResource

Sync communications / RFQ API.

kalshi.resources.communications.AsyncCommunicationsResource

AsyncCommunicationsResource(transport: AsyncTransport)

Bases: AsyncResource

Async communications / RFQ API.