{
  "openapi": "3.0.3",
  "info": {
    "title": "Problyx Public API",
    "version": "1.0.0",
    "description": "Read-only public API for Problyx prediction markets. Anonymous access is allowed at 10 requests/minute per IP; send an API key in the `X-API-Key` header for 30 requests/minute per key. Create keys in your Problyx profile settings. The free tier is an evaluation tier \u2014 for higher limits, commercial use or production traffic, email info@problyx.com. Please link back to the `url` field when displaying Problyx data.",
    "contact": {
      "name": "Problyx API",
      "email": "info@problyx.com",
      "url": "https://www.problyx.com/developers"
    },
    "termsOfService": "https://problyx.com/terms"
  },
  "servers": [{ "url": "https://api.problyx.com/public/v1" }],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "X-API-Key" }
    },
    "schemas": {
      "Outcome": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "labelEn": { "type": "string" },
          "labelEs": { "type": "string" },
          "probability": { "type": "number", "minimum": 0, "maximum": 1 },
          "pool": { "type": "number" },
          "sortOrder": { "type": "integer" }
        }
      },
      "Market": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "titleEn": { "type": "string" },
          "titleEs": { "type": "string" },
          "descriptionEn": { "type": "string" },
          "descriptionEs": { "type": "string" },
          "category": { "type": "string" },
          "status": { "type": "string", "enum": ["active", "closed", "resolved", "cancelled", "resolution_locked"] },
          "outcomeType": { "type": "string", "enum": ["binary", "multi"] },
          "eventId": { "type": "string", "format": "uuid", "nullable": true },
          "yesProbability": { "type": "number", "minimum": 0, "maximum": 1 },
          "noProbability": { "type": "number", "minimum": 0, "maximum": 1 },
          "yesPool": { "type": "number" },
          "noPool": { "type": "number" },
          "outcomes": { "type": "array", "items": { "$ref": "#/components/schemas/Outcome" } },
          "totalVolume": { "type": "number" },
          "uniqueTraders": { "type": "integer" },
          "totalTrades": { "type": "integer" },
          "imageUrl": { "type": "string" },
          "closesAt": { "type": "string", "format": "date-time" },
          "resolvedAt": { "type": "string", "format": "date-time", "nullable": true },
          "resolvedOutcome": { "type": "string", "nullable": true },
          "createdAt": { "type": "string", "format": "date-time" },
          "updatedAt": { "type": "string", "format": "date-time" },
          "url": { "type": "string", "description": "Canonical problyx.com page. Link back to it when displaying this data." }
        }
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "titleEn": { "type": "string" },
          "titleEs": { "type": "string" },
          "category": { "type": "string" },
          "status": { "type": "string" },
          "outcomeMode": { "type": "string", "enum": ["exclusive", "independent"], "description": "exclusive: outcome probabilities sum to ~100%. independent: each outcome is an autonomous yes/no market." },
          "imageUrl": { "type": "string" },
          "markets": { "type": "array", "items": { "$ref": "#/components/schemas/Market" } },
          "closesAt": { "type": "string", "format": "date-time" },
          "createdAt": { "type": "string", "format": "date-time" },
          "updatedAt": { "type": "string", "format": "date-time" },
          "url": { "type": "string" }
        }
      },
      "Quote": {
        "type": "object",
        "properties": {
          "shares": { "type": "number" },
          "pricePerShare": { "type": "number" },
          "priceImpact": { "type": "number" },
          "estimatedReturn": { "type": "number" },
          "newProbability": { "type": "number" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": false },
          "error": {
            "type": "object",
            "properties": { "code": { "type": "string" }, "message": { "type": "string" } }
          }
        }
      }
    },
    "parameters": {
      "limit": { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } },
      "offset": { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0, "maximum": 10000 } }
    }
  },
  "security": [{}, { "ApiKeyAuth": [] }],
  "paths": {
    "/markets": {
      "get": {
        "summary": "List public markets",
        "parameters": [
          { "name": "q", "in": "query", "schema": { "type": "string" }, "description": "Free-text search" },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["active", "closed", "resolved", "cancelled"] } },
          { "name": "category", "in": "query", "schema": { "type": "string" }, "description": "e.g. Politics, Sports, Crypto" },
          { "name": "sort", "in": "query", "schema": { "type": "string", "enum": ["newest", "volume", "traders", "trades", "closing", "hot", "trending", "probability"], "default": "newest" } },
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" }
        ],
        "responses": {
          "200": { "description": "Paginated market list: `{ success, data: { items, total, limit, offset } }`" },
          "400": { "description": "Invalid filter", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/markets/{id}": {
      "get": {
        "summary": "Get one market",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": {
          "200": { "description": "`{ success, data: Market }`" },
          "404": { "description": "Not found (also returned for private markets)" }
        }
      }
    },
    "/markets/{id}/quote": {
      "get": {
        "summary": "Preview a trade without executing it",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "outcome", "in": "query", "schema": { "type": "string", "enum": ["yes", "no"], "default": "yes" } },
          { "name": "amount", "in": "query", "required": true, "schema": { "type": "number", "exclusiveMinimum": 0 }, "description": "Amount in PP (Problyx Points, virtual currency)" },
          { "name": "action", "in": "query", "schema": { "type": "string", "enum": ["buy", "sell"], "default": "buy" } }
        ],
        "responses": {
          "200": { "description": "`{ success, data: Quote }`" },
          "409": { "description": "Market closed" },
          "410": { "description": "Market resolved or cancelled" },
          "423": { "description": "Market settling (resolution locked)" }
        }
      }
    },
    "/events": {
      "get": {
        "summary": "List public events (containers grouping related markets)",
        "parameters": [
          { "name": "q", "in": "query", "schema": { "type": "string" } },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["active", "resolved", "cancelled"] } },
          { "name": "category", "in": "query", "schema": { "type": "string" } },
          { "name": "sort", "in": "query", "schema": { "type": "string" } },
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" }
        ],
        "responses": { "200": { "description": "Paginated event list: `{ success, data: { items, total, limit, offset } }`" } }
      }
    },
    "/events/{id}": {
      "get": {
        "summary": "Get one event with its markets",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": {
          "200": { "description": "`{ success, data: Event }`" },
          "404": { "description": "Not found (also returned for private events)" }
        }
      }
    }
  }
}
