{
  "openapi": "3.1.0",
  "info": {
    "title": "Prediction Hunt API",
    "description": "Cross-platform prediction market intelligence API. Real-time prices, cross-platform\nmarket matching, arbitrage opportunities, and smart money alerts across Kalshi,\nPolymarket, PredictIt, ProphetX, Opinion, and Predict.fun.\n\n**Authentication:** Pass your API key in the `X-API-Key` header (preferred) or as the\n`api_key` query parameter.\n\n**Versioning:** v1 endpoints are deprecated. All new integrations should use v2.\n",
    "version": "2.0.0",
    "contact": {
      "url": "/api/docs"
    },
    "license": {
      "name": "API Terms of Service",
      "url": "https://www.predictionhunt.com/terms-of-service"
    }
  },
  "servers": [
    {
      "url": "/api/v2",
      "description": "Current environment (local, preview, or production)"
    },
    {
      "url": "https://www.predictionhunt.com/api/v2",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyHeader": []
    }
  ],
  "tags": [
    {
      "name": "status",
      "description": "API health and per-platform ingestion status"
    },
    {
      "name": "matching",
      "description": "Cross-platform market matching"
    },
    {
      "name": "markets",
      "description": "Market listings"
    },
    {
      "name": "events",
      "description": "Event listings"
    },
    {
      "name": "prices",
      "description": "Price history and bulk snapshots"
    },
    {
      "name": "orderbook",
      "description": "Order book depth"
    },
    {
      "name": "signals",
      "description": "Arbitrage and expected value opportunities"
    },
    {
      "name": "alerts",
      "description": "Smart money and fade-the-whale signals"
    }
  ],
  "paths": {
    "/status": {
      "get": {
        "operationId": "getStatus",
        "tags": [
          "status"
        ],
        "summary": "API status",
        "description": "Returns API version and per-platform ingestion health. No authentication required.",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/matching-markets": {
      "get": {
        "operationId": "getMatchingMarkets",
        "tags": [
          "matching"
        ],
        "summary": "Search matching markets across platforms",
        "description": "Finds matching markets across all supported platforms for a given query, Polymarket\nmarket URL, or Polymarket condition ID. Exactly one of `q`, `polymarket_key`, or\n`kalshi_key` must be provided.\n\nCounts against the **matched-markets** monthly group quota.\n",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Free-text search query (min 3 characters, max 100 characters).",
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 100
            }
          },
          {
            "name": "polymarket_key",
            "in": "query",
            "description": "Polymarket condition ID or market URL slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kalshi_key",
            "in": "query",
            "description": "Kalshi market ticker.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              },
              "X-RateLimit-Limit-Matched-Markets-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Matched-Markets-Month"
              },
              "X-RateLimit-Remaining-Matched-Markets-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Matched-Markets-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingMarketsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/matching-markets/url": {
      "get": {
        "operationId": "getMatchingMarketsByUrl",
        "tags": [
          "matching"
        ],
        "summary": "Find matches from a market URL",
        "description": "Resolves matching markets across platforms for a given market page URL.\nSupports Polymarket, Kalshi, and PredictIt URLs.\n\nCounts against the **matched-markets** monthly group quota.\n",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Full market page URL (e.g. `https://polymarket.com/market/will-...`).",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              },
              "X-RateLimit-Limit-Matched-Markets-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Matched-Markets-Month"
              },
              "X-RateLimit-Remaining-Matched-Markets-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Matched-Markets-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingMarketsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/matching-markets/sports": {
      "get": {
        "operationId": "getMatchingMarketsSports",
        "tags": [
          "matching"
        ],
        "summary": "Sports event matching by league or sport",
        "description": "Returns matched game markets grouped by game for a given sport/league and optional date.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "sport",
            "in": "query",
            "required": true,
            "description": "Sport or league identifier (e.g. `nba`, `nfl`, `mlb`, `nhl`, `mls`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "in": "query",
            "description": "Game date in `YYYY-MM-DD` format. Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "platforms",
            "in": "query",
            "description": "Comma-separated platform filter.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SportsMatchingResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/markets": {
      "get": {
        "operationId": "listMarkets",
        "tags": [
          "markets"
        ],
        "summary": "List markets",
        "description": "Returns a paginated list of markets with current price data. Supports filtering by platform, status, category, and keyword.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "description": "Filter by platform.",
            "schema": {
              "type": "string",
              "enum": [
                "kalshi",
                "polymarket",
                "predictit",
                "prophetx",
                "opinion",
                "predictfun"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by market status.",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "resolved",
                "cancelled"
              ]
            }
          },
          {
            "name": "category",
            "in": "query",
            "description": "Filter by category (e.g. `politics`, `sports`, `crypto`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Keyword filter applied to market titles.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum results per page (1–500).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 50
            }
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarketsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/events": {
      "get": {
        "operationId": "listEvents",
        "tags": [
          "events"
        ],
        "summary": "List events",
        "description": "Returns a paginated list of events with their cross-platform market groups.\nCounts against the **matched-markets** monthly group quota.\n",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "event_type",
            "in": "query",
            "description": "Filter by event type (e.g. `election`, `sports`, `politics`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by event status.",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "resolved",
                "cancelled"
              ]
            }
          },
          {
            "name": "tags",
            "in": "query",
            "description": "Comma-separated tag filter.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "in": "query",
            "description": "Filter events by date (`YYYY-MM-DD`).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Keyword filter.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_groups",
            "in": "query",
            "description": "Set to `true` to include group details in each event.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum results per page (1–100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              },
              "X-RateLimit-Limit-Matched-Markets-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Matched-Markets-Month"
              },
              "X-RateLimit-Remaining-Matched-Markets-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Matched-Markets-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/search": {
      "get": {
        "operationId": "searchEvents",
        "tags": [
          "events"
        ],
        "summary": "Full-text event search",
        "description": "Searches events by keyword with optional type, status, and date filters. Returns matching events with their market groups.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search query (min 3 characters, max 100 characters).",
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 100
            }
          },
          {
            "name": "event_type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "resolved",
                "cancelled"
              ]
            }
          },
          {
            "name": "date_from",
            "in": "query",
            "description": "Earliest event date (`YYYY-MM-DD`).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "date_to",
            "in": "query",
            "description": "Latest event date (`YYYY-MM-DD`).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "include_groups",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum results per page (1–100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/prices/history": {
      "get": {
        "operationId": "getPriceHistory",
        "tags": [
          "prices"
        ],
        "summary": "OHLC price history",
        "description": "Returns OHLC candlestick price data for a single market over a given time range.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": true,
            "description": "Platform the market belongs to.",
            "schema": {
              "type": "string",
              "enum": [
                "kalshi",
                "polymarket",
                "predictit",
                "prophetx",
                "opinion",
                "predictfun"
              ]
            }
          },
          {
            "name": "market_id",
            "in": "query",
            "required": true,
            "description": "Platform-native market identifier.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "interval",
            "in": "query",
            "description": "Candle interval.",
            "schema": {
              "type": "string",
              "enum": [
                "1m",
                "5m",
                "15m",
                "1h",
                "1d"
              ],
              "default": "1h"
            }
          },
          {
            "name": "from",
            "in": "query",
            "description": "Start of the time range (ISO 8601).",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "End of the time range (ISO 8601). Defaults to now.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricesHistoryResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/prices/bulk": {
      "get": {
        "operationId": "getBulkPrices",
        "tags": [
          "prices"
        ],
        "summary": "Bulk price snapshot",
        "description": "Returns the latest price snapshot for up to 100 markets in a single request. Pass `ids` as a comma-separated list of `platform:market_id` pairs.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "ids",
            "in": "query",
            "required": true,
            "description": "Comma-separated list of `platform:market_id` pairs. Maximum 100 items.",
            "schema": {
              "type": "string",
              "example": "polymarket:32224,kalshi:KXPRESPERSON-28-GNEWS"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricesBulkResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/orderbook": {
      "get": {
        "operationId": "getOrderbook",
        "tags": [
          "orderbook"
        ],
        "summary": "Market orderbook",
        "description": "Returns the current bid/ask order book depth for a single market. Supported platforms: `polymarket`, `kalshi`, `opinion`, `predictfun`.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "kalshi",
                "polymarket",
                "opinion",
                "predictfun"
              ]
            }
          },
          {
            "name": "market_id",
            "in": "query",
            "required": true,
            "description": "Platform-native market identifier.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderbookResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/unified-orderbook": {
      "get": {
        "operationId": "getUnifiedOrderbook",
        "tags": [
          "orderbook"
        ],
        "summary": "Unified orderbook across platforms",
        "description": "Returns a merged order book combining depth from all platforms that have a market in the given match group.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "group_id",
            "in": "query",
            "required": true,
            "description": "Match group ID (integer). Obtain from `/matching-markets` or `/events`.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnifiedOrderbookResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/arb": {
      "get": {
        "operationId": "getArbitrageOpportunities",
        "tags": [
          "signals"
        ],
        "summary": "Arbitrage opportunities",
        "description": "Returns current cross-platform arbitrage opportunities sorted by ROI. Each opportunity\nrepresents a two-leg trade where buying YES on one platform and NO on another yields\na risk-free profit.\n\nCounts against the **arb** monthly group quota.\n",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "min_roi",
            "in": "query",
            "description": "Minimum ROI percentage to include (default 0.5).",
            "schema": {
              "type": "number",
              "minimum": 0,
              "default": 0.5
            }
          },
          {
            "$ref": "#/components/parameters/PlatformsParam"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum results to return (1–100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              },
              "X-RateLimit-Limit-Arb-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Arb-Month"
              },
              "X-RateLimit-Remaining-Arb-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Arb-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArbResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/ev": {
      "get": {
        "operationId": "getEVOpportunities",
        "tags": [
          "signals"
        ],
        "summary": "Expected value opportunities",
        "description": "Returns markets where the price on one platform is significantly mispriced relative\nto the consensus probability derived from all platforms.\n\nCounts against the **ev** monthly group quota.\n",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "min_roi",
            "in": "query",
            "description": "Minimum ROI percentage to include (default 1.0).",
            "schema": {
              "type": "number",
              "minimum": 0,
              "default": 1
            }
          },
          {
            "name": "side",
            "in": "query",
            "description": "Which outcome side to surface.",
            "schema": {
              "type": "string",
              "enum": [
                "yes",
                "no",
                "both"
              ],
              "default": "both"
            }
          },
          {
            "$ref": "#/components/parameters/PlatformsParam"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum results to return (1–100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              },
              "X-RateLimit-Limit-Ev-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Ev-Month"
              },
              "X-RateLimit-Remaining-Ev-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Ev-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EVResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/alerts/smart-money": {
      "get": {
        "operationId": "getSmartMoneyAlerts",
        "tags": [
          "alerts"
        ],
        "summary": "Smart money alerts",
        "description": "Returns a newest-first feed of large-order signals: whale buys, insider patterns,\nand captain-hook reversals.\n\nCounts against the **smart-money** monthly group quota.\n",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "alert_type",
            "in": "query",
            "description": "Filter by alert sub-type.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "smart_money",
                "insider",
                "captain_hook"
              ],
              "default": "all"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum alerts to return (1–100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/SinceParam"
          },
          {
            "name": "platform",
            "in": "query",
            "description": "Filter alerts by platform.",
            "schema": {
              "type": "string",
              "enum": [
                "kalshi",
                "polymarket",
                "predictit",
                "prophetx",
                "opinion",
                "predictfun"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              },
              "X-RateLimit-Limit-Smart-Money-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Smart-Money-Month"
              },
              "X-RateLimit-Remaining-Smart-Money-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Smart-Money-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/alerts/fade-finder": {
      "get": {
        "operationId": "getFadeFinderAlerts",
        "tags": [
          "alerts"
        ],
        "summary": "Fade finder alerts",
        "description": "Returns a newest-first feed of fade-the-whale signals — markets where large money\nhas historically moved the price in the wrong direction.\n\nCounts against the **fade-finder** monthly group quota.\n",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyQuery": []
          }
        ],
        "parameters": [
          {
            "name": "alert_type",
            "in": "query",
            "description": "Filter by alert sub-type.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "fade"
              ],
              "default": "all"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum alerts to return (1–100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/SinceParam"
          },
          {
            "name": "platform",
            "in": "query",
            "description": "Filter alerts by platform.",
            "schema": {
              "type": "string",
              "enum": [
                "kalshi",
                "polymarket",
                "predictit",
                "prophetx",
                "opinion",
                "predictfun"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-RateLimit-Limit-Second": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Second"
              },
              "X-RateLimit-Remaining-Second": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
              },
              "X-RateLimit-Limit-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Month"
              },
              "X-RateLimit-Remaining-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
              },
              "X-RateLimit-Limit-Fade-Finder-Month": {
                "$ref": "#/components/headers/X-RateLimit-Limit-Fade-Finder-Month"
              },
              "X-RateLimit-Remaining-Fade-Finder-Month": {
                "$ref": "#/components/headers/X-RateLimit-Remaining-Fade-Finder-Month"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Preferred authentication method. Pass your API key in the `X-API-Key` request header."
      },
      "ApiKeyQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "api_key",
        "description": "Discouraged. Pass your API key as a query parameter. Use header auth in production."
      }
    },
    "parameters": {
      "CursorParam": {
        "name": "cursor",
        "in": "query",
        "description": "Opaque pagination cursor from the `next_cursor` field of a previous response.",
        "schema": {
          "type": "string"
        }
      },
      "PlatformsParam": {
        "name": "platforms",
        "in": "query",
        "description": "Comma-separated platform filter. Valid values: `kalshi`, `polymarket`, `predictit`, `prophetx`, `opinion`, `predictfun`.",
        "schema": {
          "type": "string",
          "example": "kalshi,polymarket"
        }
      },
      "SinceParam": {
        "name": "since",
        "in": "query",
        "description": "Return only records created after this ISO 8601 timestamp.",
        "schema": {
          "type": "string",
          "format": "date-time",
          "example": "2026-04-01T00:00:00Z"
        }
      }
    },
    "headers": {
      "X-RateLimit-Limit-Second": {
        "description": "Per-second request limit for your API key tier.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining-Second": {
        "description": "Remaining requests in the current one-second window.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Limit-Month": {
        "description": "Monthly request quota for your API key tier.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining-Month": {
        "description": "Remaining requests in the current calendar month.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Limit-Matched-Markets-Month": {
        "description": "Monthly quota for the matched-markets endpoint group.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining-Matched-Markets-Month": {
        "description": "Remaining monthly quota for the matched-markets endpoint group.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Limit-Arb-Month": {
        "description": "Monthly quota for the arb endpoint group.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining-Arb-Month": {
        "description": "Remaining monthly quota for the arb endpoint group.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Limit-Ev-Month": {
        "description": "Monthly quota for the ev endpoint group.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining-Ev-Month": {
        "description": "Remaining monthly quota for the ev endpoint group.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Limit-Smart-Money-Month": {
        "description": "Monthly quota for the smart-money endpoint group.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining-Smart-Money-Month": {
        "description": "Remaining monthly quota for the smart-money endpoint group.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Limit-Fade-Finder-Month": {
        "description": "Monthly quota for the fade-finder endpoint group.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining-Fade-Finder-Month": {
        "description": "Remaining monthly quota for the fade-finder endpoint group.",
        "schema": {
          "type": "integer"
        }
      },
      "Retry-After": {
        "description": "Seconds until the rate limit window resets.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid or missing request parameters.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "success": false,
              "error": "Missing required parameter",
              "message": "Provide exactly one of: q, polymarket_key, kalshi_key."
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid API key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "success": false,
              "error": "Authentication required. Provide an X-API-Key header or api_key query parameter."
            }
          }
        }
      },
      "Forbidden": {
        "description": "API key inactive, expired, or not authorized for this endpoint.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "success": false,
              "error": "API Key not authorized for this endpoint."
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Rate limit exceeded. Check `Retry-After` header for reset time.",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          },
          "X-RateLimit-Limit-Second": {
            "$ref": "#/components/headers/X-RateLimit-Limit-Second"
          },
          "X-RateLimit-Remaining-Second": {
            "$ref": "#/components/headers/X-RateLimit-Remaining-Second"
          },
          "X-RateLimit-Limit-Month": {
            "$ref": "#/components/headers/X-RateLimit-Limit-Month"
          },
          "X-RateLimit-Remaining-Month": {
            "$ref": "#/components/headers/X-RateLimit-Remaining-Month"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "success": false,
              "error": "Per-second rate limit exceeded"
            }
          }
        }
      },
      "InternalServerError": {
        "description": "Unexpected server error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "success": false,
              "error": "Internal server error"
            }
          }
        }
      }
    },
    "schemas": {
      "Alert": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "alert_type": {
            "type": "string",
            "description": "Sub-type: `whale_smart_money`, `whale_insider`, `whale_captain_hook`, `whale_fade`."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "event_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "group_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "event_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "market_slug": {
            "type": [
              "string",
              "null"
            ]
          },
          "platform_buy": {
            "type": [
              "string",
              "null"
            ]
          },
          "data": {
            "type": [
              "object",
              "null"
            ],
            "description": "Platform-specific supplemental data."
          }
        }
      },
      "AlertsResponse": {
        "type": "object",
        "properties": {
          "alerts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Alert"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "has_more": {
            "type": "boolean"
          }
        }
      },
      "ArbLeg": {
        "type": "object",
        "properties": {
          "market_id": {
            "type": "string"
          },
          "platform": {
            "type": "string",
            "enum": [
              "kalshi",
              "polymarket",
              "predictit",
              "prophetx",
              "opinion",
              "predictfun"
            ]
          },
          "price": {
            "type": "number"
          },
          "side": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ]
          },
          "source_url": {
            "type": "string",
            "format": "uri"
          },
          "liquidity_usd": {
            "type": "number",
            "description": "Available liquidity at this price in USD."
          }
        }
      },
      "ArbOpportunity": {
        "type": "object",
        "properties": {
          "group_id": {
            "type": "integer"
          },
          "group_title": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "event_date": {
            "type": "string",
            "format": "date"
          },
          "detected_at": {
            "type": "string",
            "format": "date-time"
          },
          "roi_pct": {
            "type": "number",
            "description": "Return on investment percentage if both legs fill."
          },
          "total_cost": {
            "type": "number",
            "description": "Total outlay in dollars to place all legs."
          },
          "legs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArbLeg"
            }
          }
        }
      },
      "ArbResponse": {
        "type": "object",
        "properties": {
          "as_of": {
            "type": "string",
            "format": "date-time"
          },
          "count": {
            "type": "integer"
          },
          "delay_seconds": {
            "type": "integer",
            "description": "Data age in seconds. Non-zero on Free tier."
          },
          "opportunities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArbOpportunity"
            }
          }
        }
      },
      "BulkPrice": {
        "type": "object",
        "properties": {
          "last_price": {
            "type": "number"
          },
          "yes_ask": {
            "type": "number"
          },
          "yes_bid": {
            "type": "number"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "success",
          "error"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "EVLeg": {
        "type": "object",
        "properties": {
          "market_id": {
            "type": "string"
          },
          "platform": {
            "type": "string",
            "enum": [
              "kalshi",
              "polymarket",
              "predictit",
              "prophetx",
              "opinion",
              "predictfun"
            ]
          },
          "price": {
            "type": "number"
          },
          "side": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ]
          },
          "source_url": {
            "type": "string",
            "format": "uri"
          },
          "roi_pct": {
            "type": "number",
            "description": "Estimated ROI relative to consensus probability."
          },
          "ev_usd_per_dollar": {
            "type": "number",
            "description": "Expected value gain per dollar wagered."
          }
        }
      },
      "EVOpportunity": {
        "type": "object",
        "properties": {
          "group_id": {
            "type": "integer"
          },
          "group_title": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "event_date": {
            "type": "string",
            "format": "date"
          },
          "detected_at": {
            "type": "string",
            "format": "date-time"
          },
          "consensus_probability": {
            "type": "number",
            "description": "Median implied probability across all platforms (0–1)."
          },
          "legs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EVLeg"
            }
          }
        }
      },
      "EVResponse": {
        "type": "object",
        "properties": {
          "as_of": {
            "type": "string",
            "format": "date-time"
          },
          "delay_seconds": {
            "type": "integer"
          },
          "opportunities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EVOpportunity"
            }
          }
        }
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "event_name": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "event_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "resolved",
              "cancelled"
            ]
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventGroup"
            }
          }
        }
      },
      "EventGroup": {
        "type": "object",
        "properties": {
          "group_id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "platform_count": {
            "type": "integer"
          },
          "platforms": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "EventsResponse": {
        "type": "object",
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Event"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "total_count": {
            "type": "integer"
          }
        }
      },
      "Market": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Internal Prediction Hunt market ID."
          },
          "market_id": {
            "type": "string",
            "description": "Platform-native market identifier."
          },
          "platform": {
            "type": "string",
            "enum": [
              "kalshi",
              "polymarket",
              "predictit",
              "prophetx",
              "opinion",
              "predictfun"
            ]
          },
          "title": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "resolved",
              "cancelled"
            ]
          },
          "price": {
            "$ref": "#/components/schemas/MarketPrice"
          },
          "expiration_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "source_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        }
      },
      "MarketPrice": {
        "type": "object",
        "description": "Current bid/ask prices. Binary markets use a 0–100 scale (cents). Polymarket CLOB markets use a 0–1 decimal scale.",
        "properties": {
          "last_price": {
            "type": [
              "number",
              "null"
            ]
          },
          "yes_bid": {
            "type": [
              "number",
              "null"
            ]
          },
          "yes_ask": {
            "type": [
              "number",
              "null"
            ]
          },
          "no_bid": {
            "type": [
              "number",
              "null"
            ]
          },
          "no_ask": {
            "type": [
              "number",
              "null"
            ]
          },
          "volume": {
            "type": [
              "number",
              "null"
            ]
          },
          "liquidity": {
            "type": [
              "number",
              "null"
            ],
            "description": "Total available liquidity in USD."
          }
        }
      },
      "MarketsResponse": {
        "type": "object",
        "properties": {
          "markets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Market"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "total_count": {
            "type": "integer"
          }
        }
      },
      "MatchingEvent": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "confidence": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Confidence in the cross-platform match."
          },
          "event_type": {
            "type": "string"
          },
          "event_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MatchingGroup"
            }
          }
        }
      },
      "MatchingGroup": {
        "type": "object",
        "properties": {
          "group_id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "markets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MatchingMarketRef"
            }
          }
        }
      },
      "MatchingMarketRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Platform-native market identifier."
          },
          "source": {
            "type": "string",
            "enum": [
              "kalshi",
              "polymarket",
              "predictit",
              "prophetx",
              "opinion",
              "predictfun"
            ]
          },
          "source_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "MatchingMarketsResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "count": {
            "type": "integer"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MatchingEvent"
            }
          }
        }
      },
      "OHLCCandle": {
        "type": "object",
        "required": [
          "timestamp",
          "open",
          "high",
          "low",
          "close"
        ],
        "properties": {
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "open": {
            "type": "number"
          },
          "high": {
            "type": "number"
          },
          "low": {
            "type": "number"
          },
          "close": {
            "type": "number"
          },
          "mid": {
            "type": "number",
            "description": "Midpoint of yes_bid and yes_ask at candle close."
          },
          "yes_bid": {
            "type": "number"
          },
          "yes_ask": {
            "type": "number"
          },
          "volume": {
            "type": "number"
          },
          "dollar_volume": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "OrderbookLevel": {
        "type": "array",
        "description": "[price, size] tuple — price is in the same scale as MarketPrice, size is the number of contracts.",
        "items": {
          "type": "number"
        },
        "minItems": 2,
        "maxItems": 2
      },
      "OrderbookResponse": {
        "type": "object",
        "properties": {
          "market_id": {
            "type": "string"
          },
          "platform": {
            "type": "string"
          },
          "yes": {
            "$ref": "#/components/schemas/OrderbookSide"
          },
          "no": {
            "$ref": "#/components/schemas/OrderbookSide"
          }
        }
      },
      "OrderbookSide": {
        "type": "object",
        "properties": {
          "bids": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderbookLevel"
            }
          },
          "asks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderbookLevel"
            }
          }
        }
      },
      "PlatformStatus": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "stale",
              "unknown"
            ],
            "description": "`ok` = updated within last 30 minutes; `stale` = older than 30 minutes."
          },
          "last_updated": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "active_markets": {
            "type": "integer"
          }
        }
      },
      "PricesBulkResponse": {
        "type": "object",
        "properties": {
          "prices": {
            "type": "object",
            "description": "Map of `\"platform:market_id\"` to current price snapshot.",
            "additionalProperties": {
              "$ref": "#/components/schemas/BulkPrice"
            }
          }
        }
      },
      "PricesHistoryResponse": {
        "type": "object",
        "properties": {
          "candles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OHLCCandle"
            }
          }
        }
      },
      "SearchEvent": {
        "type": "object",
        "properties": {
          "event_name": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "event_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "status": {
            "type": "string"
          },
          "group_count": {
            "type": "integer"
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchGroup"
            }
          }
        }
      },
      "SearchGroup": {
        "type": "object",
        "properties": {
          "group_id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "platform_count": {
            "type": "integer"
          },
          "markets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SportsMarketRef"
            }
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string"
          },
          "count": {
            "type": "integer"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchEvent"
            }
          }
        }
      },
      "SportsGame": {
        "type": "object",
        "properties": {
          "event_date": {
            "type": "string",
            "format": "date"
          },
          "game_title": {
            "type": "string"
          },
          "group_id": {
            "type": "integer"
          },
          "markets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SportsMarketRef"
            }
          }
        }
      },
      "SportsMarketRef": {
        "type": "object",
        "properties": {
          "market_id": {
            "type": "string"
          },
          "platform": {
            "type": "string",
            "enum": [
              "kalshi",
              "polymarket",
              "predictit",
              "prophetx",
              "opinion",
              "predictfun"
            ]
          },
          "last_price": {
            "type": [
              "number",
              "null"
            ]
          },
          "yes_bid": {
            "type": [
              "number",
              "null"
            ]
          },
          "yes_ask": {
            "type": [
              "number",
              "null"
            ]
          },
          "source_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        }
      },
      "SportsMatchingResponse": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "games": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SportsGame"
            }
          }
        }
      },
      "StatusResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok"
            ]
          },
          "version": {
            "type": "string",
            "example": "2.0.0"
          },
          "documentation_url": {
            "type": "string"
          },
          "platforms": {
            "type": "object",
            "description": "Per-platform ingestion health keyed by platform name.",
            "additionalProperties": {
              "$ref": "#/components/schemas/PlatformStatus"
            }
          }
        }
      },
      "UnifiedOrderbookPlatformEntry": {
        "type": "object",
        "properties": {
          "market_id": {
            "type": "string"
          },
          "ticker": {
            "type": "string",
            "description": "Present for Kalshi markets."
          },
          "token_id": {
            "type": "string",
            "description": "Present for Polymarket CLOB markets."
          },
          "timestamp": {
            "type": "integer",
            "description": "Unix timestamp of the orderbook snapshot."
          },
          "bids": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderbookLevel"
            }
          },
          "asks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderbookLevel"
            }
          }
        }
      },
      "UnifiedOrderbookResponse": {
        "type": "object",
        "properties": {
          "event_name": {
            "type": "string"
          },
          "candidate": {
            "type": "string",
            "description": "The specific outcome/candidate this orderbook represents."
          },
          "platforms": {
            "type": "object",
            "description": "Per-platform orderbook keyed by platform name.",
            "additionalProperties": {
              "$ref": "#/components/schemas/UnifiedOrderbookPlatformEntry"
            }
          },
          "combined": {
            "$ref": "#/components/schemas/OrderbookSide"
          }
        }
      }
    }
  }
}
