Skip to main content

RFQ (Request for Quote) Messages

Overview

RFQ functionality involves two types of participants connecting via different FIX sessions: RFQ Creators - Users who want to trade via RFQ (connect via RT mode):
  1. Create RFQ via QuoteRequest (35=R)
  2. Receive quotes from market makers via Quote (35=S)
  3. Accept a quote via AcceptQuote (35=UA)
  4. Receive trade execution via ExecutionReport (35=8)
Market Makers - Users who provide quotes (connect via RfqMode):
  1. Receive QuoteRequest from exchange
  2. Respond with Quote (35=S)
  3. Receive acceptance notification
  4. Confirm execution via QuoteConfirm (35=U7)
RFQ Creators use the KalshiRT endpoint (same as order entry), which provides message persistence and retransmission support. Market Makers use the KalshiRFQ endpoint to receive RFQ broadcasts and submit quotes.

Message Flow

Full RFQ Flow (Creator via FIX)

QuoteRequest (35=R)

This message is used bidirectionally:
  • Creator → Exchange: Create a new RFQ
  • Exchange → Market Makers: Notify of new RFQ

Creator → Exchange (Create RFQ)

TagNameTypeRequiredDescription
131QuoteReqIdUUIDYClient-assigned RFQ identifier
146NoRelatedSymIntegerYNumber of symbols (must be 1)
55SymbolStringCMarket ticker. Required unless MVE legs are specified
38OrderQtyDecimalCNumber of contracts as a fixed-point decimal. Currently only whole contracts are accepted (for example 5, 5.0, or 5.00). Required unless CashOrderQty is specified
152CashOrderQtyDecimalCTarget cost in dollars. Required unless OrderQty is specified
453NoPartyIDsIntegerNNumber of parties (only 1 supported)
448PartyIdStringNFCM SubtraderId for the customer on whose behalf the RFQ is submitted
452PartyRoleIntegerN24 (CustomerAccount) - required when using PartyId
21015RestRemainderCharNY/N - Allow partial fills (default: N)
21016ReplaceExistingCharNY/N - Whether to delete existing RFQs as part of this RFQ’s creation (default: N)
20180MultivariateCollectionTickerStringCCollection ticker for parlay/MVE markets. Use instead of Symbol
20181NoMultivariateSelectedLegsIntegerCNumber of MVE legs (repeating group). Required with 20180
20182MultivariateSelectedEventTickerStringYEvent ticker for the leg
20183MultivariateSelectedMarketTickerStringYMarket ticker for the leg
20184MultivariateSelectedMarketSideStringYSide for the leg (“yes” or “no”)
MVE/Parlay Support: Instead of specifying a Symbol, you can submit MVE legs directly. The server will automatically resolve or create the parlay market and return the resolved market ticker in the QuoteRequestAck.

Exchange → Market Maker (RFQ Notification)

TagNameTypeRequiredDescription
131QuoteReqIdUUIDYServer-assigned RFQ identifier
146NoRelatedSymIntegerYNumber of symbols (always 1)
55SymbolStringYMarket ticker
38OrderQtyDecimalYNumber of contracts as a fixed-point decimal. Currently emitted as whole contracts
152CashOrderQtyDecimalNTarget cost in dollars (if specified by creator)
453NoPartyIDsIntegerNNumber of parties (always 1)
448PartyIdStringNRequester public communications ID. This value is pseudonymous and is not the requester’s SubtraderId
20180MultivariateCollectionTickerStringNCollection ticker for multivariate markets
20181NoMultivariateSelectedLegsIntegerNNumber of MVE legs (repeating group)
20182MultivariateSelectedEventTickerStringNEvent ticker for the leg
20183MultivariateSelectedMarketTickerStringNMarket ticker for the leg
20184MultivariateSelectedMarketSideStringNSide for the leg (“yes” or “no”)

QuoteRequestAck (35=b)

Exchange response to an inbound QuoteRequest from an RFQ creator.
TagNameTypeRequiredDescription
131QuoteReqIdUUIDYClient-assigned RFQ ID (echoed back)
303QuoteRequestTypeIntegerY1 (MANUAL)
21023RfqIdUUIDYServer-assigned RFQ ID
55SymbolStringCResolved market ticker. Present when MVE legs were submitted
The server-assigned RFQ ID is returned in tag 21023. Store it if you want to reconcile later Quote or QuoteStatusReport messages to the created RFQ. For RFQCancel, use your original client-assigned QuoteReqId (tag 131).
When creating an RFQ with MVE legs instead of a Symbol, the resolved market ticker is returned in tag 55. This is the market that was created or looked up based on your leg selection.

Quote (35=S)

This message is used bidirectionally:
  • Market Maker → Exchange: Submit a quote for an RFQ
  • Exchange → Creator: Notify creator of a new quote
If a new Quote is created when an existing quote for the same market already exists for the user, the exchange will cancel the existing quote.

Market Maker → Exchange (Submit Quote)

TagNameTypeRequiredDescription
117QuoteIdUUIDYClient-assigned quote identifier
131QuoteReqIdUUIDYServer-assigned RFQ ID (from QuoteRequest)
55SymbolStringYMarket ticker
132BidPxIntegerCYes price in cents (1-99)
133OfferPxIntegerCNo price in cents (1-99)
79AllocAccountIntegerNSubaccount number (0-32). If provided, the quote will be created for the specified subaccount.

Exchange → Creator (Quote Notification)

TagNameTypeRequiredDescription
117QuoteIdUUIDYQuote identifier (use this to accept)
131QuoteReqIdUUIDYServer-assigned RFQ ID
55SymbolStringYMarket ticker
132BidPxDecimalCYes price in dollars (e.g. 0.4500). Not present when zero
133OfferPxDecimalCNo price in dollars (e.g. 0.5500). Not present when zero
38OrderQtyDecimalNNumber of contracts as a fixed-point decimal. Currently emitted as whole contracts
Either BidPx or OfferPx can be zero, but not both. Zero indicates no quote for that side.

QuoteStatusReport (35=AI)

A QuoteStatusReport is sent by the exchange:
  1. In response to a Quote. Status will be PENDING if processed, or REJECTED if rejected
  2. When the requester accepts the quote. Status will be ACCEPTED
  3. In response to a QuoteCancel. Status will be CANCELLED
TagNameTypeRequiredDescription
117QuoteIdStringYQuote identifier (empty if rejected)
131QuoteReqIdStringYRequest reference
79AllocAccountIntegerCSubaccount number (0-32). Present if the quote was created for a subaccount
297QuoteStatusIntegerYCurrent status
38OrderQtyDecimalCQuantity of contracts as a fixed-point decimal. Currently emitted as whole contracts. Not present if REJECTED
132BidPxIntegerCYes price in cents. Only integer part considered. Not present if REJECTED
133OfferPxIntegerCNo price in cents. Only integer part considered. Not present if REJECTED
54AcceptedSideCharCSide accepted (1=Yes, 2=No). Only present if ACCEPTED
58TextStringCRejection reason. Only present if REJECTED

Quote Status Values (297)

  • ACCEPTED<0>: Requester accepted the quote
  • REJECTED<5>: Exchange rejected the quote
  • PENDING<10>: Quote processed, awaiting action
  • CANCELLED<17>: Quote cancelled

QuoteCancel (35=Z)

Market maker cancels an active quote.
TagNameTypeRequiredDescription
117QuoteIdStringYQuote to cancel
Exchange responds with QuoteStatusReport (Status=CANCELLED).

QuoteCancelStatus (35=U9)

Response to QuoteCancel from exchange.
TagNameTypeRequiredDescription
117QuoteIdStringYQuote identifier
298QuoteCancelStatusIntegerYCANCELED(0) or REJECTED(1)
58RejectReasonStringCPresent if QuoteCancelStatus is REJECTED

QuoteConfirm (35=U7)

Market maker confirms willingness to execute after quote acceptance.
TagNameTypeRequiredDescription
117QuoteIdStringYAccepted quote ID
Quote must be confirmed within 30 seconds of acceptance or it will be voided.

QuoteConfirmStatus (35=U8)

Exchange response to quote confirmation.
TagNameTypeRequiredDescription
117QuoteIdStringYQuote identifier
21010QuoteConfirmStatusIntegerYACCEPTED(0) or REJECTED(1)
58RejectReasonStringCPresent if QuoteConfirmStatus is REJECTED

AcceptQuote (35=UA)

RFQ creator accepts a quote from a market maker.
TagNameTypeRequiredDescription
117QuoteIdUUIDYQuote to accept
54SideCharYFIX side (1=BUY, 2=SELL). For AcceptQuote, BUY accepts the maker’s NO quote and SELL accepts the maker’s YES quote.
38OrderQtyDecimalNContracts to accept as a fixed-point decimal. Currently only whole contracts are accepted
11ClOrdIDStringNClient order ID
453NoPartyIDsIntegerNNumber of parties (only 1 supported)
448PartyIdStringNFCM SubtraderId for the customer on whose behalf the accept is submitted
452PartyRoleIntegerN24 (CustomerAccount) for SubtraderId

AcceptQuoteStatus (35=UC)

Exchange response to AcceptQuote.
TagNameTypeRequiredDescription
117QuoteIdStringYQuote identifier
21025AcceptQuoteStatusIntegerYACCEPTED(0) or REJECTED(1)
58TextStringCRejection reason if REJECTED

RFQCancel (35=UE)

RFQ creator cancels/deletes an active RFQ.
TagNameTypeRequiredDescription
131QuoteReqIdUUIDYClient-assigned RFQ ID (from original QuoteRequest)
Use your original client-assigned QuoteReqId from the QuoteRequest message. The RFQ ID already identifies the associated subtrader, so no PartyID fields are needed. When an RFQ is cancelled, market makers receive a QuoteRequestReject (35=AG) notification.

RFQCancelStatus (35=UB)

Exchange response to RFQCancel.
TagNameTypeRequiredDescription
131QuoteReqIdStringYRFQ identifier (echoes back the ID from RFQCancel request)
21013RFQCancelStatusIntegerYCANCELED(0) or REJECTED(1)
58TextStringCRejection reason if REJECTED

QuoteRequestReject (35=AG)

Exchange notifies that a quote request was cancelled.
TagNameTypeRequiredDescription
58TextStringYReason the quote has been cancelled
131QuoteReqIdStringYRequest identifier
658QuoteRequestRejectReasonIntegerYOTHER(99)
Market makers do not send QuoteRequestReject when ignoring a request.

Best Practices

For RFQ Creators

  1. RFQ ID Management
    • Store the server-assigned RFQ ID from QuoteRequestAck if you want to reconcile later Quote or QuoteStatusReport messages to the created RFQ
    • Use your original client-assigned QuoteReqId for RFQCancel
  2. Quote Selection
    • Compare quotes from multiple market makers
    • Accept quotes promptly as they may expire
    • Verify price and quantity before accepting
  3. Cancellation
    • Cancel RFQs you no longer need
    • Wait for RFQCancelStatus before considering cancelled

For Market Makers

  1. Response Time
    • Respond to quote requests promptly
    • Confirm accepted quotes within 30 seconds
    • Cancel stale quotes proactively
  2. Quote Management
    • Track active quotes locally
    • Handle quote replacements properly
    • Monitor for acceptance notifications
  3. Risk Management
    • Validate prices before quoting
    • Implement position limits
    • Handle partial quotes (one-sided)

Error Handling

  1. Rejection Scenarios
    • Invalid price range
    • Symbol not found
    • Insufficient balance
    • Technical issues
  2. Timeout Handling
    • 30-second confirmation window
    • Automatic quote expiration
    • Network disconnection recovery

Example Workflow

RFQ Creator Flow

8=FIXT.1.1|35=R|131=client-req-123|146=1|38=100|55=HIGHNY-23DEC31|

Market Maker Flow

8=FIXT.1.1|35=R|131=server-rfq-456|146=1|38=100|55=HIGHNY-23DEC31|453=1|448=anon-456|

Integration Notes

  • RFQ Creators use the KalshiRT endpoint (RT mode) - same connection as order entry, with message persistence and retransmission support
  • Market Makers use the KalshiRFQ endpoint (RfqMode) to receive RFQ broadcasts and submit quotes
  • ExecutionReport (35=8) is sent to the RFQ creator after trade execution
  • RFQs expire after 24 hours if not cancelled or accepted