Parlay Integration

Provide Parlay price quotes and confirmation responses to ProphetX by authenticating with the MM API, seeding events and markets, and subscribing to the parlay WebSocket.

Provide Parlay price quotes and confirmation responses to ProphetX by authenticating with the Market Maker (MM) API, seeding events and markets, and subscribing to the parlay WebSocket.

Overview

  1. Web and mobile clients send parlay quote requests for a list of unique outcomes to the ProphetX backend.
  2. ProphetX broadcasts those requests to integrated Market Makers through WebSocket, and Market Makers return quote responses through a callback REST API.
  3. When a participant accepts a price, ProphetX sends a private confirmation request to Market Makers that can satisfy the order. Market Makers then send their confirmation response through a callback REST API.
  4. After ProphetX receives the confirmation, ProphetX publishes an order.finalized message on the private channel to confirm execution of the parlay.

API documentation

API Documentation

Example Python code: Python Parlay API Integration Guide

Example Golang code: Golang Parlay Integration Guide

Before you start

  1. Follow the first three steps in Trading API Integration to get your Trading API credentials and ingest events and markets. The parlay API uses the same Market Maker API credentials.
  2. Review the Python or Golang example implementation before you connect to the parlay WebSocket.

Core flow

  1. Exchange a session key by using your Access Key and Secret Key.
  2. Optional: Get your current cash balance.
  3. Seed events and markets for the tournaments you want to trade.

Step 2: Connect to the parlay WebSocket

See subscribe(self) in the Python example and ListenForMessages() in the Golang example. The parlay WebSocket exposes seven topics.

  1. price.confirm.new delivers a parlay request to the intended Market Maker when ProphetX needs a quote. Send your quote response in the following callback payload format:
{
  "parlay_id": "price_quote_request['parlay_id']",
  "offers": [
    {
      "valid_until": 1723564800000000000,
      "price": 1000,
      "max_risk": 200,
      "estimated_price": [
        {
          "strike_id": "strike_1",
          "price": 200
        },
        {
          "strike_id": "strike_2",
          "price": 220
        }
      ]
    }
  ]
}

Quote callback fields

Use these rules when you send the /orders/offers callback:

FieldDescription
max_riskMaximum risk from the requestor perspective.
priceParlay price from the requestor perspective. Use American price format. Do not follow normal price ladder, and can be set to any given price.
valid_untilExpiration time for the offer as a Unix timestamp in nanoseconds. Set this value to a time greater than 0 and less than 5 seconds after you send the callback. Do not set this value to 0.
estimated_priceOptional per-strike price breakdown for frontend display. Include strike_id and price for each strike you want to show. This value does not need to contain every strike in the parlay and is not required for the offer itself.
  1. price.confirm.new is also documented here for the confirmation callback you send after a participant accepts the quoted price. Use the following payload format:
{
  "action": "accept",   //or reject
  "confirmed_price": "...",
  "confirmed_quantity": 100.0,  // Optional. If null, no change to the quantity
  "price_probability": [
    {
      "max_risk": 200.0,
      "strikes": [
        {
          "strike_id": "strike_1",
          "probability": 0.5 
        },
        {
          "strike_id": "strike_2",
          "probability": 0.4 
        }
      ],
      "correlation": "..."  // (not determined yet)
    },
    {
      "max_risk": 3000.0,
      "strikes": [
        {
          "strike_id": "strike_1",
          "probability": 0.4
        },
        {
          "strike_id": "strike_2",
          "probability": 0.5 
        }
      ]
    }
  ]
}

Timeout and latency expectations

Use these timeout windows when you implement quote and confirmation handling:

ScenarioExpected timing
Maximum time for a Market Maker to submit a quoteProphetX uses a queue system and processes quotes in the order received. If no Market Maker quotes within 5 seconds, the request times out.
Maximum time for a participant to accept a quote5 seconds.
Timeout for the Market Maker to confirm after the participant accepts5 seconds.
Expected latency for execution to appear in the channel after Market Maker confirmationWithin 1 second.
  1. order.matched is broadcast to all Market Makers connected to the parlay WebSocket. The message includes the latest matched parlay price and filled quantity from all Market Makers. Example message:
{
  "payload": {
    "market_strikes": [...],
    "matched_at": 1759216871383341000,
    "fill_price": 188,
    "filled_quantity": 3.49,
    "parlay_id": "28250d66–30a4–406b-b90c-cd65c96d4c72",
    "timestamp": 1759216871383340000
  }
}
  1. order.finalized is sent after ProphetX receives the confirmation callback. This message confirms that the parlay order has been executed on the ProphetX side. Example payload:
{
  "payload": {
    "confirmed_price": -100000,
    "confirmed_quantity": 1349.049722844427,
    "price": -100000,
    "order_uuid": "01977e64–756b-7a75-b218-f0a0e4032004",
    "parlay_id": "23851166–3e18–4b3c-aea7–16de1b114bb8",
    "status": "finalized",
    "updated_at": 1750172203426483200
  },
  "timestamp": 1750172203428558300
}
  1. order.settled is sent to the order owner after one order in the parlay reaches settlement.
{
  "payload": {
    "order_uuid": "01991588–274d-70be-ac0a-cf876677d57f",
    "parlay_id": "fdd7e3fb-ef50–42eb-9d73–43d3d7f1390f",
    "settlement_status": "profit",
    "settled_at": 1757002869231213000,
    "profit": 150
  },
  "timestamp": 1757002869231213000
}
  1. parlay.settled is sent to the parlay owner after all orders in the parlay reach settlement.
{
  "payload": {
    "parlay_id": "fdd7e3fb-ef50–42eb-9d73–43d3d7f1390f",
    "settlement_status": "profit",
    "settled_at": 1757002869231213000,
    "profit": 150
  },
  "timestamp": 1757002869231213000
}
  1. health_check works the same way as the Trading API. If your client does not receive this message for more than 30 seconds, reconnect to the WebSocket.