API DocumentationProfessional trading
/
Controlled pilot
Predictions API · v2 pilot

Build trading systems on YM.

Discover markets, place canonical orders, and reconcile execution through a participant-scoped private feed.

Available Market discovery

Canonical events, families, markets, L2 snapshots, trades and statistics.

Pilot Order entry

Idempotent REST commands for NEW, single-order REPLACE and CANCEL.

Pilot Private execution

Authenticated snapshot, replay, resume and live canonical order events.

RESThttps://ympredictions.com
Private feedwss://ympredictions.com/v1/trading-feed
OAuthhttps://auth.ympredictions.com/realms/ymp/protocol/openid-connect/token
Activation is environment-specific. Confirm that YM has enabled v2 for your endpoint and account before sending commands. The URL remains /v1; order and feed payloads identify schema version 2. v1 order fields and private-feed cursors are not accepted by v2.
Command admission is not execution. An HTTP 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.

Obtain pilot credentials.

YM supplies a client ID, client secret, account binding and approved scopes during onboarding.

Select a canonical market.

Use an immutable market_id with the current positive market_generation.

Open the private feed.

Complete snapshot bootstrap and wait for stream.ready before sending commands.

Submit and reconcile.

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.

ScopePurpose
orders:writeSubmit approved NEW, REPLACE and CANCEL commands.
orders:readRead the token-bound account's orders, trades, positions and portfolio.
trading-feed:readOpen the account's private lifecycle feed.
balances:readRead balances for the bound account.
trading:professionalSelect an explicitly provisioned professional capacity profile. It grants no trading authority itself.
  • Never put user_id in 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.

On 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.

ActionOutcomeEconomic meaning
BUYYESIncrease YES exposure at the stated YES price.
SELLYESReduce held YES exposure at the stated YES price.
BUYNOIncrease NO exposure at the stated NO price.
SELLNOReduce 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.

PENDINGadmitted by YM
WORKINGeffective at venue
PARTIALfill and remainder
TERMINALfilled, cancelled, expired or rejected
  • pending_action=REPLACE or CANCEL means the prior venue-effective state remains authoritative until confirmation.
  • state_quality=RECONCILIATION_REQUIRED means stop mutating that order until YM restores confirmed venue truth.
  • Only fills with settlement_status=POSTED are financially complete.

Idempotency and recovery

Every economic command needs a stable client identity before transmission.

  • Use one unique Idempotency-Key per command and one unique client_order_id per 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_id and apply only newer order_version values.
  • 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.

publiclimit ≤ 200
GET/v1/market-familiesGrouped propositions

Use view=canonical to discover proposition families and their immutable market leaves.

publiclimit ≤ 500
GET/v1/marketsList canonical markets

Use view=canonical. Filter by status, category, event or family; paginate with the opaque cursor.

publiclimit ≤ 500
GET/v1/markets/{marketID}Market detail and generation

Request view=canonical. Use the returned immutable ID, current generation and lifecycle fields for command construction.

public
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.

publicsnapshot
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.

publiclimit ≤ 200
GET/v1/markets/{marketID}/statsMarket statistics

Derived volume, trader counts, average position and open-interest statistics. Not an execution authority.

public

Create an order

POST /v1/orders admits one canonical limit order. Participant identity comes from the bearer token.

Response: 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.

orders:write200 / 201limit orders

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_version must come from the latest canonical order.
  • price_cents stays in the order's immutable outcome coordinate, including for NO.
  • total_quantity includes quantity already filled.
  • 202 means admitted; the old price and quantity remain effective until order.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.

orders:readlimit ≤ 500
GET/v1/orders/{orderID}One canonical order

Returns the complete lifecycle snapshot and an ETag derived from order_version. Supports If-None-Match.

orders:read
GET/v1/tradesParticipant trades

Legacy account activity in venue-side/YES-book coordinates. Use the v2 private feed for live participant-relative fills.

orders:read
GET/v1/positionsYES / NO exposure

Current position projection, optionally narrowed to one market.

orders:read
GET/v1/portfolioPortfolio summary

Account-level portfolio summary and positions.

orders:read
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.

balances:read

Private trading feed

The authenticated WebSocket is the live participant channel for canonical commands, orders, replacements, fills and terminal state.

Endpoint: wss://ympredictions.com/v1/trading-feed
Schema: 2 · Scope: trading-feed:read

Bootstrap

  1. stream.welcome
  2. stream.snapshot_started
  3. zero or more stream.snapshot_chunk frames
  4. stream.snapshot_completed
  5. events after the snapshot high-water mark
  6. stream.ready

Do not begin strategy command flow before stream.ready.

Lifecycle events

EventUse
order.command_resultAdmission or rejection outcome for NEW, REPLACE or CANCEL.
order.workingVenue evidence confirms the order is working.
order.replacedThe new single-order price and quantity are effective.
order.fillComplete updated order state plus available fill evidence.
order.cancelledCancellation is effective and terminal.
order.expired / order.rejectedVenue 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.

StatusMeaningClient action
400Invalid requestCorrect the payload; do not retry blindly.
401 / 403Authentication or scope deniedRefresh credentials or correct onboarding.
404Resource outside participant scopeReconcile identity; do not invent a replacement ID.
409Current state conflicts with commandFollow the specific code, refresh state, then decide.
429Capacity exceededHonor Retry-After; preserve command identity.
503Required authority unavailableFollow retryable and retry an uncertain command with the same identity.
Unknown commit state: after a timeout or connection loss, retry the exact request with the same idempotency key and query canonical state. Never issue a new economic command merely because the response was lost.

Limits

These are current protocol and controlled-pilot limits, not a public production SLA.

ResourceCurrent limit
Idempotency key / client order ID200 characters; ym: prefix reserved
Batch NEW / CANCELNot enabled for v2 pilot; intended maximum 250 items
Order and canonical-market pages500 items maximum
Recent public market trades200 items maximum
REST L2 depth200 levels per side; default 20
Private-feed frameServer-advertised; current profile caps at 256 KiB
Private-feed snapshot chunkAt most 100 orders, possibly fewer to respect frame size
Professional command profileCurrently 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.

In developmentWebSocket order entryThe same canonical command model over a persistent low-latency session.
In developmentProfessional market-data streamRecoverable DXmatch-derived snapshots and deltas with bounded subscriptions.
In developmentCancel safetyMass cancel, cancel-on-disconnect and participant kill controls.
In developmentBatch commandsPer-item replay and canonical error conformance before pilot activation.
ConditionalFIXSubject to venue access, conformance and a measurable performance benefit.
Not offered: external mass-quote or atomic bid/ask quote-set replacement. Current REPLACE targets one venue order.