Canonical events, families, markets, L2 snapshots, trades and statistics.
Build trading systems on YM.
Discover markets, place canonical orders, and reconcile execution through a participant-scoped private feed.
Idempotent REST commands for NEW, single-order REPLACE and CANCEL.
Authenticated snapshot, replay, resume and live canonical order events.
https://ympredictions.comwss://ympredictions.com/v1/trading-feedhttps://auth.ympredictions.com/realms/ymp/protocol/openid-connect/token/v1; order and feed payloads identify schema version 2. v1 order fields and private-feed cursors are not accepted by v2.201 or 202 confirms that YM durably admitted the command. Wait for canonical venue-effective state on the private feed.Quickstart
The shortest safe path opens the private feed before submitting an order, then treats feed state as execution authority.
YM supplies a client ID, client secret, account binding and approved scopes during onboarding.
Use an immutable market_id with the current positive market_generation.
Complete snapshot bootstrap and wait for stream.ready before sending commands.
Send a unique command identity, then converge local state by event_id and order_version.
1. Get an access token
curl -sS -X POST \
'https://auth.ympredictions.com/realms/ymp/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=<client-id>' \
--data-urlencode 'client_secret=<client-secret>'
2. Find a tradeable market
curl -sS \
'https://ympredictions.com/v1/markets?view=canonical&status=active&limit=20'
Require status=OPEN, publication_state=PUBLIC_OPEN, a future close time, and market_generation > 0. The order endpoint remains the final admission authority.
3. Open the private feed
npx wscat \
-c 'wss://ympredictions.com/v1/trading-feed' \
-H 'Authorization: Bearer <access-token>'
4. Create one resting order
curl -sS -X POST 'https://ympredictions.com/v1/orders' \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: strategy-a-new-000001' \
-d '{
"client_order_id": "strategy-a-order-000001",
"market_id": "<market-id>",
"market_generation": 4,
"action": "BUY",
"outcome": "YES",
"price_cents": 45,
"quantity": 10,
"time_in_force": "GTC"
}'
Keep the returned command and order IDs. Wait for order.working, order.fill, or a terminal event before treating the result as venue-effective. A BUY NO @ 35 request must remain BUY / NO / 35 in REST and Private Feed v2; never complement NO prices in a command.
Authentication
Professional clients use OAuth 2.0 client credentials. Tokens are short-lived, account-bound bearer credentials.
| Scope | Purpose |
|---|---|
orders:write | Submit approved NEW, REPLACE and CANCEL commands. |
orders:read | Read the token-bound account's orders, trades, positions and portfolio. |
trading-feed:read | Open the account's private lifecycle feed. |
balances:read | Read balances for the bound account. |
trading:professional | Select an explicitly provisioned professional capacity profile. It grants no trading authority itself. |
- Never put
user_idin an order command. - Keep client secrets and access tokens out of logs and URLs.
- Obtain a replacement token before expiry and reconnect the feed from the last applied cursor.
Market identity
Trade immutable market leaves, not titles, slugs, provider references, event IDs or family IDs.
Event
The real-world fixture, election or question grouping.
Family
A coordinated proposition such as match winner, set winner or tournament winner.
Market leaf
One binary outcome market. Public orders select YES or NO; YM normalizes both to its internal YES book.
Generation
The current admission fence for that market definition.
stale_market_generation: stop, fetch GET /v1/markets/{marketID}?view=canonical, re-evaluate the definition, and build a new command. Never increment the value locally.Actions, outcomes and prices
Every public price is an integer from 0 through 100 in the selected outcome's coordinate. YM derives venue side and accounting effect.
| Action | Outcome | Economic meaning |
|---|---|---|
| BUY | YES | Increase YES exposure at the stated YES price. |
| SELL | YES | Reduce held YES exposure at the stated YES price. |
| BUY | NO | Increase NO exposure at the stated NO price. |
| SELL | NO | Reduce held NO exposure at the stated NO price. |
Do not complement NO prices. BUY NO at 35 means pay 35 cents for NO. The retired v1 fields side, position_side, intent, and decimal price are rejected.
Time in force: use GTC for resting liquidity and IOC for protected immediate execution. DAY is venue-session scoped and is not a substitute for long-lived prediction-market liquidity.
Order lifecycle
YM separates command admission, venue execution and financial posting. Do not collapse them into one generic accepted state.
pending_action=REPLACEorCANCELmeans the prior venue-effective state remains authoritative until confirmation.state_quality=RECONCILIATION_REQUIREDmeans stop mutating that order until YM restores confirmed venue truth.- Only fills with
settlement_status=POSTEDare financially complete.
Idempotency and recovery
Every economic command needs a stable client identity before transmission.
- Use one unique
Idempotency-Keyper command and one uniqueclient_order_idper new order. - For an uncertain response, retry the exact payload with the same key. Never manufacture a new identity until the original outcome is known.
- Deduplicate private-feed delivery by
event_idand apply only newerorder_versionvalues. - Persist the signed feed cursor only after the event has been durably applied locally.
Market data
Public REST supports discovery, command preflight and snapshot recovery. It is not yet a professional streaming market-data contract.
GET/v1/eventsEvent-first discovery
Filter canonical events by category, sport, competition, lifecycle or time window. Optionally include families and leaves.
GET/v1/market-familiesGrouped propositions
Use view=canonical to discover proposition families and their immutable market leaves.
GET/v1/marketsList canonical markets
Use view=canonical. Filter by status, category, event or family; paginate with the opaque cursor.
GET/v1/markets/{marketID}Market detail and generation
Request view=canonical. Use the returned immutable ID, current generation and lifecycle fields for command construction.
GET/v1/markets/{marketID}/bookCurrent L2 snapshot
Returns bids, asks, projection sequence and timestamp in YES-book coordinates. YES ask p maps to BUY YES p or SELL NO 100-p; YES bid p maps to SELL YES p or BUY NO 100-p. Depth defaults to 20 and is capped at 200 levels per side.
GET/v1/markets/{marketID}/tradesRecent public trades
Recent taker-side public activity. This is not a participant's private drop copy or authoritative fill state.
GET/v1/markets/{marketID}/statsMarket statistics
Derived volume, trader counts, average position and open-interest statistics. Not an execution authority.
Create an order
POST /v1/orders admits one canonical limit order. Participant identity comes from the bearer token.
201 means newly admitted; 200 means exact idempotent replay. Neither alone proves the order is working at DXmatch.POST/v1/ordersAdmit NEW
Required headers: bearer token, JSON content type and Idempotency-Key. Required body fields are shown in the quickstart.
Replace an order
REPLACE mutates one existing venue order while retaining its stable YM and DX identity.
curl -sS -X POST \
'https://ympredictions.com/v1/orders/<order-id>/replace' \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: strategy-a-replace-000001' \
-d '{
"expected_order_version": 4,
"price_cents": 44,
"total_quantity": 10
}'
expected_order_versionmust come from the latest canonical order.price_centsstays in the order's immutable outcome coordinate, including for NO.total_quantityincludes quantity already filled.202means admitted; the old price and quantity remain effective untilorder.replaced.- A rejected replacement leaves the prior effective order in place.
Cancel an order
Cancellation is final only when the canonical order is terminal or the private feed delivers order.cancelled.
curl -sS -X POST \
'https://ympredictions.com/v1/orders/<order-id>/cancel' \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: strategy-a-cancel-000001' \
-d '{}'
Batch cancellation is not enabled for the v2 pilot. It will remain outside the participant contract until per-item replay and error-envelope conformance passes.
Account state
Private REST reads are self-scoped by bearer identity. Optional user_id filters cannot select another participant.
GET/v1/ordersCanonical orders
Filter by market, execution status, pending action or state quality. Paginate with the opaque cursor.
GET/v1/orders/{orderID}One canonical order
Returns the complete lifecycle snapshot and an ETag derived from order_version. Supports If-None-Match.
GET/v1/tradesParticipant trades
Legacy account activity in venue-side/YES-book coordinates. Use the v2 private feed for live participant-relative fills.
GET/v1/positionsYES / NO exposure
Current position projection, optionally narrowed to one market.
GET/v1/portfolioPortfolio summary
Account-level portfolio summary and positions.
GET/v1/accounts/{userID}/balancesLedger-derived balances
The path account must match the token-bound financial account unless the caller is a separately authorized operator.
Private trading feed
The authenticated WebSocket is the live participant channel for canonical commands, orders, replacements, fills and terminal state.
wss://ympredictions.com/v1/trading-feedSchema:
2 · Scope: trading-feed:readBootstrap
stream.welcomestream.snapshot_started- zero or more
stream.snapshot_chunkframes stream.snapshot_completed- events after the snapshot high-water mark
stream.ready
Do not begin strategy command flow before stream.ready.
Lifecycle events
| Event | Use |
|---|---|
order.command_result | Admission or rejection outcome for NEW, REPLACE or CANCEL. |
order.working | Venue evidence confirms the order is working. |
order.replaced | The new single-order price and quantity are effective. |
order.fill | Complete updated order state plus available fill evidence. |
order.cancelled | Cancellation is effective and terminal. |
order.expired / order.rejected | Venue or lifecycle terminal state. |
Resume
wss://ympredictions.com/v1/trading-feed?cursor=<URL-encoded-signed-cursor>
Delivery is at least once. Require schema_version == 2. The cursor is opaque, signed, participant-bound and not a DXmatch offset. On reconnect, replay from the last event your system durably applied. Before cutover, finish v1 through the announced boundary and retain its terminal/fill history. A cursorless v2 snapshot replaces nonterminal state only; it does not replay v1 history.
Errors and retries
Use the machine-readable code, not free-form text, to choose an action.
| Status | Meaning | Client action |
|---|---|---|
| 400 | Invalid request | Correct the payload; do not retry blindly. |
| 401 / 403 | Authentication or scope denied | Refresh credentials or correct onboarding. |
| 404 | Resource outside participant scope | Reconcile identity; do not invent a replacement ID. |
| 409 | Current state conflicts with command | Follow the specific code, refresh state, then decide. |
| 429 | Capacity exceeded | Honor Retry-After; preserve command identity. |
| 503 | Required authority unavailable | Follow retryable and retry an uncertain command with the same identity. |
Limits
These are current protocol and controlled-pilot limits, not a public production SLA.
| Resource | Current limit |
|---|---|
| Idempotency key / client order ID | 200 characters; ym: prefix reserved |
| Batch NEW / CANCEL | Not enabled for v2 pilot; intended maximum 250 items |
| Order and canonical-market pages | 500 items maximum |
| Recent public market trades | 200 items maximum |
| REST L2 depth | 200 levels per side; default 20 |
| Private-feed frame | Server-advertised; current profile caps at 256 KiB |
| Private-feed snapshot chunk | At most 100 orders, possibly fewer to respect frame size |
| Professional command profile | Currently 3,300 authenticated requests/minute when explicitly provisioned |
Capacity is assigned during onboarding and may be narrower. Cancellation uses independently reserved capacity. Clients must handle 429 and Retry-After.
In development
These capabilities are not part of the current contract. Do not build a production dependency on them yet.