Skip to main content
Use the Requester API to request executable Combo quotes, accept a winning quote, and track the trade through onchain execution. This guide walks through the complete workflow.
Keep the CLOB API secret and passphrase on trusted infrastructure. Never expose them in a browser or other untrusted client.

Request and Execute a Quote

The production gateway is https://combos-rfq-gateway-requester-api.polymarket.com, with base path /v1/requester/rfq.
1

Prepare the Trading Account

Create a Polymarket account, obtain its CLOB API credentials, and fund the account wallet. Set up the wallet and trading approvals by following Wallets and Authentication.Resolve the CLOB credential address, order signer, order maker, and signature type for the account’s wallet:Both requester gateways reject EOA accounts. The Requester API returns UNSUPPORTED_REQUESTER_SIGNATURE_TYPE; use a Deposit, Proxy, or Safe Wallet.
2

Sign Request Headers

Every request requires these CLOB L2 headers:
  • POLY_ADDRESS
  • POLY_API_KEY
  • POLY_PASSPHRASE
  • POLY_TIMESTAMP
  • POLY_SIGNATURE
POLY_ADDRESS is the address associated with the CLOB API credentials. Use the wallet identity values resolved in the previous step for the request body and signed order.Compute POLY_SIGNATURE with HMAC-SHA256, using the base64-decoded CLOB secret as the key. Sign an uppercase method, a Unix timestamp in seconds, the full request path without the host or query string, and the exact serialized body sent on the wire. Omit the body for GET requests. Encode the digest as base64url with padding preserved.
Generate a fresh timestamp and signature for every request, including each status poll.
3

Choose the Combo Legs

Fetch active Combo-enabled markets from the public catalog:
The response contains a markets array and an opaque next_cursor. Pass the cursor back as cursor to fetch the next page. For each market, position_ids, outcomes, and outcome_prices are aligned by array index: index 0 is YES and index 1 is NO.Choose 2–50 unique, mutually compatible outcome position IDs and pass them in leg_position_ids.
4

Create the RFQ

Choose the request direction and size:
  • A BUY sets the maximum collateral budget, including fees. Use unit: "notional".
  • A SELL specifies the number of Combo shares to sell. Use unit: "shares".
value_e6 is a string in 6-decimal base units, and side must currently be "YES". The gateway holds the request until the quote competition finishes. The examples below use a Deposit Wallet. The API accepts at most 15 create requests per rolling minute for each maker_address; requests above that limit return HTTP 429 with RATE_LIMITED.
An executable response includes the server-owned RFQ ID, winning quote, and acceptance deadline:
expires_at and request.created_at are Unix timestamps in milliseconds. The acceptance window is five seconds from quote readiness. Sign and accept the order before expires_at. total_required_e6 is the exact balance required: collateral including fees for BUY, or Combo shares for SELL. For BUY, net_receive_e6 is the Combo shares received. For SELL, it is the exact collateral proceeds after fees.If no usable quote is available, the gateway returns HTTP 200 with a terminal business outcome:
A local create timeout or lost connection has an unknown outcome. The RFQ may have been created even if you never received its server-owned ID. This API has no idempotency key or lookup for that case, and retrying may create another RFQ.
5

Build and Sign the Requester Order

Build an Exchange v3 order from the returned request and quote. Use Polygon chain ID 137 and Exchange v3 contract 0xe3333700cA9d93003F00f0F71f8515005F6c00Aa for the EIP-712 domain.For both directions, copy maker_amount_e6 to makerAmount and taker_amount_e6 to takerAmount, and use the returned Combo YES position ID as tokenId. Set side to 0 for BUY or 1 for SELL.The builder field must be the zero bytes32 value. A non-zero value is rejected with BUILDER_ATTRIBUTION_NOT_ALLOWED. This gateway does not support Builder attribution. Approved builders that need orders attributed to their Builder code must authenticate and submit them through the Builder Gateway workflow instead.Use the same wallet identity selected when creating the RFQ. The wallet type determines which payload to sign and how to encode signed_order.signature:For a Deposit Wallet, wrap the Exchange v3 order in the Deposit Wallet’s TypedDataSign structure. Both maker and signer in contents are the Deposit Wallet address. The account or session signer signs this outer payload.
Deposit Wallet Typed Data
For a Proxy or Safe Wallet, sign the Exchange v3 Order directly. Set maker to the Proxy or Safe Wallet address, signer to the account signer, and signatureType to 1 or 2, respectively.
Proxy or Safe Wallet Typed Data
Sign the selected payload with the account or session signer. Deposit Wallets must wrap the raw signature for ERC-7739 validation; Proxy and Safe Wallets submit the signature returned by signing the Exchange Order directly.
6

Accept the Quote

Submit the signed order with the winning quote_id before the returned expires_at deadline.
The response contains the latest known state. If Last Look is pending, the gateway waits up to one second for an execution or terminal update before returning.
EXECUTING is not a confirmed fill. A response may instead remain AWAITING_MAKER_CONFIRMATION, or return HTTP 200 with status: "FAILED" and an error object if the maker declines or execution fails. Retrying the same authenticated acceptance does not execute the order twice; use rfq_id as the stable recovery identifier.
7

Poll Status

After acceptance, fetch durable status with a newly signed L2 request.
Status reads before acceptance return HTTP 409. Poll while the state is AWAITING_MAKER_CONFIRMATION, EXECUTING, MINED, or RETRYING. Stop on a successful CONFIRMED or FILLED state, or a terminal FAILED, EXPIRED, or CANCELED state. A local polling timeout does not mean the trade failed; resume polling the same rfq_id.

Handle Errors

Validation and dependency failures use non-200 HTTP statuses with stable string codes:
Treat codes as strings so integrations remain compatible with new codes. HTTP 200 can still contain a failed business outcome; always inspect both status and the nested error object.