Skip to main content
Market makers should read the Combos/RFQ guide before integrating. It explains quote construction, visibility, last look, and recovery.
The public polymarket.v1.RFQAPI gRPC service creates, reads, and manages RFQs and quotes. An RFQ references the exact symbol of an open, tradable instrument, such as a combo instrument. The service also exposes the gRPC-only RFQ event stream. Every REST endpoint below has an equivalent unary gRPC RPC. REST JSON uses lower camel case; protobuf fields use snake case.

Endpoints

All calls require bearer-token authentication and an acting participant, supplied through x-participant-id or the token’s participant_id claim. Each unary method has a separate per-firm rate-limit bucket with one second of burst capacity, shared across REST and gRPC requests. Your RFQ tier determines the CreateQuote and DeleteQuote limits. See RFQ rate-limit tiers for rates and eligibility requirements. Opening StreamRFQEvents is limited to one new stream per second per firm. See Rate Limits.

RFQ Lifecycle

rfq_trade is emitted only when an RFQ-originated order fills, and is visible to all authorized stream subscribers. The diagram shows the logical flow; delivery order between quote_executed and rfq_trade is not guaranteed. Successful AcceptQuote produces both rfq_closed and quote_accepted. A client may receive the public rfq_closed event first. Stop creating or replacing quotes for that RFQ, but keep existing quote state until the private quote event arrives or GetQuotes confirms its current status.

Create an RFQ

POST /v1/rfqs
The response contains the new rfqId. A created RFQ starts in RFQ_STATUS_OPEN.

Query RFQs

GET /v1/rfqs?limit=10&status=RFQ_STATUS_OPEN The response has rfqs and an opaque cursor. An exact RFQ ID that is absent or not visible returns an empty rfqs array. Each RFQ includes an optional price tick. An RFQ on a combo also includes the combo’s ordered leg snapshot:
tickSize is the instrument’s minimum price increment in dollars (tick_size in protobuf). Quote prices must be multiples of this value and within the instrument’s price limits. It is also included in rfq_created and rfq_closed events. If tickSize is absent, read it from GET /v1/combos?symbol=<rfq.symbol>. settlementPrice is a canonical decimal string such as "0", "0.4", or "1". It is not inverted for SIDE_SELL legs. An absent field means no valid settlement is currently available; it is distinct from a present "0". Treat absence as unavailable, not proof that the leg is unresolved. Leg order and sides are fixed when the RFQ is created. Settlement prices are hydrated when the RFQ is returned, so later exact and list reads can expose settlements that were unavailable at creation. Historical RFQs created before leg snapshots were introduced can have an empty comboLegs array.

Close an RFQ

DELETE /v1/rfqs/{rfqId} closes an open RFQ. Only its requester can close it. The response is {}.

Quotes

A quote can offer both requester sides:
  • buyPrice is the price for a requester buy; the maker sells.
  • sellPrice is the price for a requester sell; the maker buys.
Set an unavailable side to "0". At least one side must be positive. Nonzero prices must be within the instrument’s price limits and land on its tick size.

Create or Replace a Quote

POST /v1/rfqs/quotes
The service derives buyQtyDecimal and sellQtyDecimal from the RFQ:
  • A quantity RFQ uses its qtyDecimal for every offered side.
  • A cash RFQ derives each side independently from cashOrderQty / price, rounded down to the instrument’s fractional quantity scale.
Every successful CreateQuote returns a new quoteId, including replacements. To replace, send the same rfqId with new prices; no previous quote ID is needed. Use the returned ID to delete the new quote. Confirm or decline the accepted quote using quote_accepted.quote.id. quote_deleted identifies a canceled old quote; quote_created carries the new ID. A new response does not guarantee all older quotes were canceled. Check GetQuotes if their state is unclear.

Query Quotes

GET /v1/rfqs/quotes?rfqId=rfq_... Without rfqId, provide exactly one of userFilter=USER_FILTER_SELF or rfqUserFilter=USER_FILTER_SELF. The response has quotes and an opaque cursor. Each visible Quote carries durable execution state once available: The requester and quoter can both see both exchange order IDs. A Quote does not expose client order IDs. GetQuotes is the durable recovery path when a stream event is missed. For compatibility, stream events retain their existing recipient-specific wrapper fields. The embedded Quote contains the durable fields above.
Cursors are query-, participant-, and path-bound. Treat them as opaque and reuse them only with the same filters and authenticated participant.

Accept a Quote

PUT /v1/rfqs/{rfqId}/quotes/{quoteId}/accept
Only the requester can accept an active quote. SIDE_BUY selects buyPrice; SIDE_SELL selects sellPrice. The selected price must be positive. Acceptance closes the RFQ, emits public rfq_closed, changes the quote to QUOTE_STATUS_ACCEPTED, emits participant-private quote_accepted, and starts last look.

Delete a Quote

DELETE /v1/rfqs/{rfqId}/quotes/{quoteId} deletes the caller’s active quote while the RFQ is open. The selected maker can also delete its accepted quote before the confirmation deadline to decline during last look. The response is {}.

Confirm a Quote

PUT /v1/rfqs/{rfqId}/quotes/{quoteId}/confirm The selected maker must confirm before confirmationDeadline. Confirmation changes the quote to QUOTE_STATUS_CONFIRMED and schedules paired order submission. The response is {}.

Query RFQ Trades

GET /v1/rfqs/trades or RFQAPI.GetRFQTrades returns anonymous original fills where either order originated from an RFQ, including later fills on resting orders and fills on single instruments or combos. All authorized RFQ participants see the same trades. Each fill appears once, even when both orders originated from RFQs. No account, participant, order, RFQ, or quote IDs are included. Later corrections and busts do not amend these prints; use Drop Copy for your own reconciliation. REST timestamps use RFC 3339; gRPC uses google.protobuf.Timestamp. The response contains trades and cursor, ordered by execution time descending, then trade ID descending. An empty cursor ends the traversal. Each trade has the same RFQTrade fields as the stream event. Repeat the same participant, filters, and limit on every page; change only cursor. Keep omitted timestamps omitted: the cursor preserves the original boundaries. Invalid limits, changed query parameters, or start_time >= end_time return INVALID_ARGUMENT. A start time before available history returns FAILED_PRECONDITION.
Use gRPC for pagination. Long REST cursors can exceed the current query-string size limit and return HTTP 403.
History can appear after the live event. Requery overlapping execution-time windows with a fresh cursor and deduplicate by trade_id to find late arrivals. See stream recovery.

Statuses

Events and Recovery

RFQAPI.StreamRFQEvents is a live, best-effort gRPC stream. Public RFQ events are visible to participants; quote events are private to the requester and relevant maker. The stream has no replay, gap-free handoff, ordering, or deduplication guarantee. Open the stream for low-latency changes. On startup, reconnect, or after a suspected missed event, reconcile durable state with GetRFQs and GetQuotes. See RFQ Events Stream.

Accelerated Contracts

Pursuant to Rule 5.3(n)(iv) of its Rulebook, Polymarket US has designated the following contracts as “accelerated contracts”:
  • All contracts listed for trading on Polymarket US for which an RFQ may be submitted.

See Also

Combos API

Create and read combo instruments

Combos/RFQ Guide

Maker workflow and quote rules

RFQ Events Stream

Current event payloads and recovery behavior

Authentication

OAuth metadata and required scopes