Request & Lifecycle Reference
Status: Beta (v0.1) — dark-launched. The endpoints below are implemented and gated behind the PredictionMarketsRFSEnabled feature flag (employees-only first; they return 404 everywhere the flag is off). Field names are camelCase to match the rest of the Predictions REST surface. Wire shapes match the merged implementation (PREDICT-4876); enum encodings differ between REST and WebSocket — see the note under RFSSummary. These pages are intentionally not linked from the sidebar during the rollout.
The RFS-specific surface is small: two write entry points that share one implementation, one response object (RFSSummary), and a short request lifecycle. Once the request resolves, everything else — orders, fills, positions, settlement — comes from the standard combo orderbook data model and lifecycle, identified by the derived comboSymbol.
Two ways to issue an RFS
PREDICT-4876 merged combo creation and RFS issuance into one server-side path, while keeping both REST entry points. They differ only in how legs are identified; the validation, idempotency, audit, and broadcast semantics are identical.
| Endpoint | Use when | Legs identified by | Response |
|---|---|---|---|
POST /v1/prediction-markets/combos/rfs | You want to issue an RFS directly. | instrumentSymbol + direction (resolved to contract ids server-side). | 201 Created → CreateRFSResponse |
POST /v1/prediction-markets/combos with an rfs block | You're creating a combo and want to solicit liquidity on it in the same call. | contractId + requiredOutcome. | 200/201 → CreateComboResponse (carries rfs) |
Both are gated by PredictionMarketsRFSEnabled (a request carrying an rfs block returns 404 while the flag is dark, before the body is parsed, so a dark-feature payload can't leak its shape via validation errors). Both require the PredictionsNewOrder permission on a trading account.
Issuance is idempotent per (combo, requester): resubmitting identical parameters returns the existing active RFS; submitting different parameters while one is still active fails with 409 Conflict.
RFSParams
The RFS parameter block. It is the body of the rfs field on POST /v1/prediction-markets/combos, and — composed with legs — the body of the dedicated POST /v1/prediction-markets/combos/rfs endpoint (CreateRFSRequest). All fields are optional.
| Field | Type | Description |
|---|---|---|
side | enum Buy | Sell | null | Direction the taker plans to trade the combo as a whole. Informational only — does not affect matching or the resulting (two-sided) orderbook. |
size | integer | null | Indicative size in whole contracts. Mutually exclusive with notional — supply at most one. Omitted means the taker declines to share size. |
notional | string (decimal) | null | Indicative dollar amount, string-decimal per the CDI convention (e.g. "1000.00"). Mutually exclusive with size. Mirrors total_spend on PredictionsQuoteRequest, so a taker who thinks in dollars need not convert to contracts first. |
structureTypes | string[] | Taker-asserted discovery tags. Values: SAME_EVENT, CROSS_EVENT, BASKET, SPREAD, CONDITIONAL, CROSS_CLASS, ANY. Max 16 entries; each non-empty and ≤ 64 chars after trimming. |
eventId | string | null | Optional taker-asserted event id (SGP discovery aid), ≤ 128 chars. When absent, the server attempts to derive it from the legs when all legs share a single event. |
assetClasses is server-derived and not accepted here (see RFSSummary for its current status).
RFSLeg
The leg shape on the dedicated POST /v1/prediction-markets/combos/rfs endpoint, and the shape legs are returned in on RFSSummary. (On POST /v1/prediction-markets/combos, legs use the combo contractId shape instead — see below.)
| Field | Type | Description |
|---|---|---|
instrumentSymbol | string | A currently listed single-contract ticker (e.g. GEMI-BTC-EOY26-HI120000). Combos cannot be legs. |
direction | enum Yes | No | Which side of the underlying contract. At v0.1 launch the same constraints as combo contracts apply (YES-only is the working assumption). |
ratio | integer | null | Quantity of this leg per combo contract. Defaults to 1 when omitted; an explicit 0 is rejected. Non-1 values are reserved for future structures (e.g. spreads). |
On POST /v1/prediction-markets/combos, each leg is instead { contractId, requiredOutcome, ratio? } — contractId accepts a JSON string ("373432") or whole number (373432), requiredOutcome is "Yes"/"No". The server derives each broadcast RFSLeg's instrumentSymbol and direction from the resolved leg contracts.
CreateRFSRequest
Body for POST /v1/prediction-markets/combos/rfs — RFSParams plus the legs.
| Field | Type | Cardinality | Description |
|---|---|---|---|
legs | RFSLeg[] | 2–6 | Ordered list of legs. Order is canonical and used to derive the comboSymbol. |
(plus all RFSParams fields) | optional | side, size | notional, structureTypes, eventId. |
CreateRFSResponse
| Field | Type | Description |
|---|---|---|
request | RFSSummary | The persisted RFS. |
RFSSummary
The persistent record of an RFS, mirroring the proto RequestForStream. Returned under request on the dedicated endpoint and under rfs on the combo-create response.
| Field | Type | Description |
|---|---|---|
rfsId | string (UUID) | Globally unique. Stable across REST, WebSocket, and FIX (FIX QuoteReqID). |
comboSymbol | string | The derived combo instrument ticker, content-addressable from the leg set per the combo ticker format. Identical leg sets always produce the same comboSymbol; duplicate submissions reuse the existing book. Clients should key off this string to interact with the resulting orderbook on every surface. |
legs | RFSLeg[] | Ordered list of legs (with resolved instrumentSymbol/direction). |
side | enum Buy | Sell | null | Echoes the request. Informational only. |
size | integer | null | Indicative size in whole contracts, if shared. Mutually exclusive with notional. |
notional | string (decimal) | null | Indicative dollar amount, if shared. Mutually exclusive with size. |
structureTypes | string[] | Echoes the request's tags. |
assetClasses | string[] | Derived from the legs' underlying contracts. Currently always empty — the leg→category derivation is pending the PREDICT-4732 categories rework. When populated it will drive the maker-side discovery filter. |
eventId | string | null | Populated when all legs share a single event (SGP discovery). Null otherwise. |
state | enum RfsState | One of RFS_STATE_REQUESTED, RFS_STATE_OPEN, RFS_STATE_CLOSED, RFS_STATE_REJECTED. A successful create returns RFS_STATE_OPEN. See Request lifecycle. |
comboCreatedAt | timestamp (RFC 3339, UTC) | null | The underlying combo orderbook creation time — not the RFS row's own create time (server-internal row timestamps are not surfaced). |
comboContractId | integer (int64) | Internal contract id for the underlying combo. A convenience field; clients should key off comboSymbol. |
:::note Enum encoding differs by surface
On REST, side/direction/state serialize as Buy/Sell, Yes/No, and RFS_STATE_OPEN. On the requestForStream WebSocket broadcast, the same values use the full proto enum names — RFS_SIDE_BUY, RFS_LEG_DIRECTION_YES, RFS_STATE_OPEN — and abbreviated JSON keys. Document each surface against its own page; see WebSocket Reference.
:::
The request is public and anonymous: it is broadcast on the public requestForStream channel with no taker identifier on the wire, and the broadcast strips the internal-only fields (comboContractId and the server-internal row timestamps). The exchange knows the submitter (for clearing, risk, and self-trade prevention); the public stream does not.
There is no created flag on RFSSummary. Whether a brand-new combo book was opened or an existing one re-solicited is observable two ways: the combo-create endpoint returns alreadyExisted on its response, and comboCreatedAt reflects when the combo book was first created.
Request lifecycle
There are two lifecycles, and keeping them separate is the key to understanding RFS:
- The RFS request — a transient action: submit, validate, persist, announce. Resolves in well under a second, then it's done.
- The combo contract — the long-lived instrument the request creates or references. Its lifecycle (trading, halts, settlement, delisting) is the standard combo orderbook lifecycle, documented in Combo Contracts.
Request states (RfsState)
| State | Meaning |
|---|---|
RFS_STATE_REQUESTED | Submitted; the exchange is validating the legs and deriving the comboSymbol. Transient, pre-validation. |
RFS_STATE_OPEN | Succeeded and announced on requestForStream. The combo contract is live. The create endpoints return this state on success. |
RFS_STATE_CLOSED | Natural sunset of an OPEN RFS — e.g. the underlying combo settled or was swept by housekeeping. Surfaced on the broadcast/replay feed, not by the create call. |
RFS_STATE_REJECTED | Failed validation, auth, or risk before reaching OPEN (unknown/ineligible leg, malformed payload). No contract created or affected. |
Code
The taker never has to manage anything past OPEN: once announced, the request's job is done and the combo contract takes over on its own lifecycle. CLOSED is bookkeeping on the RFS row that follows the combo's sunset — not an action the taker takes.
The request is one-shot; quote lifetime is the maker's call
An RFS is sent once. It is not a standing session the taker maintains, and it does not impose any duration on the responses it draws. What happens next is entirely up to the makers:
- A maker decides whether to quote at all.
- A maker decides how long their quotes stay live — their orders rest on the combo book until they cancel them, exactly like any other order on the venue. There is no quote TTL imposed by RFS and no obligation to keep a quote up for any minimum time.
- A maker can re-price by cancelling and re-posting, add depth, or pull out entirely, on their own schedule.
So the request seeds demand; the makers own the supply side and its timing. A taker watching the book sees whatever quotes makers have chosen to leave live at that moment.
Handoff to the combo contract
When the request is RFS_STATE_OPEN:
- The exchange publishes a
RequestForStreamEventon therequestForStreamchannel with the derivedcomboSymbol. - The combo instrument is visible on standard market-data feeds:
{comboSymbol}@bookTicker,{comboSymbol}@depth*,{comboSymbol}@trade,contractStatus. - Approved market makers post orders to
comboSymbolvia the standard order-entry path (REST, WS, FIX). - The taker (or anyone) takes liquidity via standard aggressive orders.
- Positions go into the standard combo position ledger and settle per the combo's underlying-leg resolution rules.
There is no separate "stream session" object to manage after OPEN. The mental model: "this combo now exists and has fresh demand on it — treat it like any other combo."
Combo contract lifecycle (standard, referenced)
Everything below belongs to the combo contract, not RFS. It is identical whether the combo was pre-listed or created by an RFS, and is documented in Combo Contracts.
Halts
Halts apply to the combo's underlying legs. If a leg halts, the combo book's tradability is affected per standard combo halt behavior.
| Halt class | Effect on the combo |
|---|---|
| Routine event-window halt on a leg | Combo enters pre-settlement; standard combo halt behavior. |
| Data-integrity halt on a leg | Combo trading paused; standard combo halt behavior. |
| Market-wide halt | All books, combos included, are halted. |
| Voided leg | Combo voids per standard combo void handling; positions unwound at entry price (see Combo Contracts). |
| Sports event-state halt (pause, video review) | Applies to combos referencing the event; standard sports-leg halt. |
| Macro pre-release blackout | Combos referencing the affected print are blocked from new orders; standard macro halt. |
Idle housekeeping
A combo that attracts no resting interest for an extended idle window may be delisted by housekeeping — most relevant for combos spun up on demand that never gain traction. Pre-listed combos may be retained by curation policy. Either way the behavior is part of the contract lifecycle; an RFS submission does not set or change a combo's delisting policy. Windows are operationally configured per asset class and are intentionally long; the duration is an open question.
What's not in the RFS surface
These apply to the combo once it's live but are standard combo orderbook concerns, identified by comboSymbol:
| Concern | Source |
|---|---|
| Orders on the combo book | Standard order data model + lifecycle (NEW / OPEN / PARTIALLY_FILLED / FILLED / CANCELLED) |
| Trade records, fills, sweeps | Standard trade-tape and account-event data model |
| Positions, balances | Standard positions/balances data model |
| Per-leg execution allocation, self-trade prevention, fill-ratio SLAs | Venue-wide / combo orderbook |
| Settlement records | Standard combo settlement (Combo Contracts) |
The standard trade-record schema picks up no new fields on account of RFS. A combo behaves identically whether it was pre-listed or created by an RFS, so the CMB ticker prefix on comboSymbol is the signal that an instrument is a combo — no separate "how did this originate?" field is needed.
If you find yourself looking for an RFS-specific Quote, Acceptance, Fill, or OrderState object: you don't need one. Those are standard orderbook objects on comboSymbol.