Custodial Integration
In the custodial model, the builder holds Combo positions for users in one omnibus Deposit Wallet and controls the account signer. The same account and builder identity must request and accept each quote.Request and Execute a Quote
Choose 2–50 unique, mutually compatible underlying market position IDs as the legs. These are outcome position IDs from Combo-enabled markets, not CLOB token IDs or the derived Combo position IDs. Contradictory legs cannot form a Combo. A BUY request sets the maximum collateral budget, including fees. A SELL request specifies the number of Combo shares to sell.- TypeScript
- Python
- API
Use
requestComboQuote() on a TypeScript SecureClient to request, accept, and
track a Combo quote.Don’t have the TypeScript SDK installed? Start with the
TypeScript SDK guide’s wallet integrations,
then come back.1
Create a Custodial Client
Configure a
SecureClient with the wallet signer, Deposit Wallet address, and
Builder API Key. This server-side example keeps the account key and builder
secret on trusted infrastructure.2
Request a Quote
Call If no usable quote is available,
requestComboQuote() with the leg position IDs and a human-readable
collateral amount. Amounts and sizes must be positive and have at most six
decimal places. Combo quote requests currently target the YES side, which the
SDK supplies by default. The method resolves when the quote competition closes.result.quote is null and result.reason
explains the outcome. A winning quote includes its acceptance deadline in
result.quote.expiresAt, as a Unix timestamp in milliseconds. Use that value
rather than assuming a fixed acceptance window.For a SELL quote, pass direction: OrderSide.SELL with a human-readable size
instead of amount. The returned quote.netReceive is the exact collateral
proceeds after fees.3
Accept and Track the Quote
Pass the returned quote to An acceptance with
acceptComboQuote() immediately. After it enters
execution, call waitForComboFill() to wait for a terminal result.status: "executing" is not yet a confirmed fill. A maker
decline, expired window, or execution failure is returned as a business outcome.
A local timeout does not mean the trade failed.Non-Custodial Integration
In the non-custodial model, each user controls the account signer for their own Deposit Wallet, while the builder provides integration authorization from trusted infrastructure.- TypeScript
Use Here, The user must approve the requester order before the quote expires. Preserve the
returned quote and retry acceptance before
remoteBuilderSigning() with a TypeScript SecureClient so the connected
wallet authorizes account actions while your server keeps the Builder API secret.Start with a connected Viem WalletClient and the user’s Deposit Wallet
address. See the TypeScript wallet integrations
if you have not configured the account signer yet.Set Up Remote Builder Signing
Combo quote requests require authenticated account access. Create aSecureClient with remoteBuilderSigning() so the user’s signer and the
builder’s signing service authorize their parts of the request separately.walletClient is the connected Viem WalletClient and
depositWalletAddress is that user’s Deposit Wallet. Authenticate calls to
/api/builder/sign with your application session. For cookie authentication,
pass credentials: "include" when the signing API is cross-origin. For bearer
authentication, pass the token through the headers option on
remoteBuilderSigning().Use a Deposit Wallet already associated with the user. To provision a new
account first, follow Create New Accounts.The signing response gives the browser the Builder key identifier, passphrase,
timestamp, and a signature scoped to that request. The Builder secret never
leaves the signing server.Request and Execute a User-Authorized Quote
Use the same Combo requester methods as the custodial TypeScript flow. The account identity now comes from the user’s signer and Deposit Wallet, while Builder authentication comes from your signing API.result.quote.expiresAt if wallet or
remote signing fails. Keep the RFQ ID to recover status after an interrupted
Gateway response or local timeout.Handle Outcomes and Errors
Custodial and non-custodial accounts share the same quote and execution outcomes. The account model changes who authorizes the trade, not how the RFQ progresses. Keep the RFQ ID until the request reaches a terminal state.
No executable quote, failed acceptance, and terminal execution failure are
business outcomes. They can be returned successfully by the service and should
not be treated as transport failures.
Check Each Case
- TypeScript
- Python
- API
Use
requestComboQuote() and its follow-up methods on SecureClient to detect
each case. Use the original RFQ ID when a local wait times out.If remote signing fails while accepting a quote, preserve
result.quote and
retry acceptance before result.quote.expiresAt. The acceptance may not have
reached the Builder Gateway, so do not assume that a status read can recover it.Next Steps
Collateral Return
Release pUSD from compatible Combo positions before resolution.
Discover Combo Markets
Find eligible markets and their leg position IDs.