{
  "openapi": "3.0.0",
  "x-origin": [
    {
      "url": "https://api.odds-api.io/v3/docs/doc.json",
      "format": "swagger",
      "version": "2.0",
      "converter": {
        "url": "https://github.com/mermade/oas-kit",
        "version": "7.0.8"
      }
    }
  ],
  "info": {
    "description": "Odds-API.io is a powerful sports betting odds comparison API, providing real-time data from 265+ bookmakers across 34 sports with near zero latency.\n\n- 265+ bookmakers supported\n- 34 sports including Football, Basketball, Tennis, Esports and more\n- Real-time odds with close to zero latency\n- Pre-match & In-play odds coverage\n- 99.9% uptime for reliability",
    "title": "Odds-API.io - Real-Time Sports Betting Odds API (v3)",
    "contact": {},
    "version": "3.0.0"
  },
  "paths": {
    "/arbitrage-bets": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns active arbitrage opportunities filtered by bookmakers. Only returns opportunities where ALL legs use the specified bookmakers.",
        "tags": [
          "Arbitrage Bets"
        ],
        "summary": "Get arbitrage betting opportunities",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"Bet365,SingBet\"",
            "description": "Comma-separated list of bookmakers (e.g. Bet365,SingBet)",
            "name": "bookmakers",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": 50,
            "description": "Maximum number of results (default 50, max 500)",
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "example": true,
            "description": "Include event details",
            "name": "includeEventDetails",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/dto.ArbitrageOpportunity"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bookmakers": {
      "get": {
        "description": "Fetch a list of supported bookmakers",
        "tags": [
          "Bookmakers"
        ],
        "summary": "Get Bookmakers",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/models.Bookmaker"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bookmakers/selected": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Fetch the list of bookmakers selected by the authenticated user",
        "tags": [
          "Bookmakers"
        ],
        "summary": "Get Selected Bookmakers",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bookmakers/selected/clear": {
      "put": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Remove all selected bookmakers for the authenticated user. Rate limited to once every 12 hours; the cooldown may be shorter for newly created accounts.",
        "tags": [
          "Bookmakers"
        ],
        "summary": "Clear Selected Bookmakers",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bookmakers/selected/select": {
      "put": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Add bookmakers to the authenticated user",
        "tags": [
          "Bookmakers"
        ],
        "summary": "Select Bookmakers",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"Bet365,SingBet\"",
            "description": "Comma-separated list of bookmaker names (e.g. Bet365,SingBet)",
            "name": "bookmakers",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/events": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns events with enhanced filtering and pagination",
        "tags": [
          "Events"
        ],
        "summary": "Get Events",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"football\"",
            "description": "Sport slug (e.g. football)",
            "name": "sport",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"england-premier-league\"",
            "description": "League slug (e.g. england-premier-league)",
            "name": "league",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "example": 38,
            "description": "Filter by participant ID (home or away)",
            "name": "participantId",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "example": "\"pending,live\"",
            "description": "Comma-separated event statuses (e.g. pending,live,settled)",
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"2025-10-28T10:00:00Z\"",
            "description": "Start date/time in RFC3339 format (e.g. 2025-10-28T10:00:00Z)",
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"2025-10-28T23:59:59Z\"",
            "description": "End date/time in RFC3339 format (e.g. 2025-10-28T23:59:59Z). If omitted, defaults to 14 days from now.",
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"SingBet\"",
            "description": "Filter by bookmaker name - returns only events that have odds available from this bookmaker (e.g. SingBet)",
            "name": "bookmaker",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "example": 20,
            "description": "Maximum number of events to return. Every response is capped at 5000; use limit + skip to paginate larger ranges.",
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "example": 0,
            "description": "Number of events to skip (for pagination)",
            "name": "skip",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/dto.SimpleEventDto"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/events/live": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns all currently live events from all sports with optional sport filter",
        "tags": [
          "Events"
        ],
        "summary": "Get Live Events",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"football\"",
            "description": "Sport slug to filter by (e.g. football)",
            "name": "sport",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/dto.SimpleEventDto"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/events/search": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Searches all upcoming events using a text query. Returns up to 10 results.",
        "tags": [
          "Events"
        ],
        "summary": "Search Events",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"Liverpool\"",
            "description": "Search term (min 3 characters)",
            "name": "query",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/dto.SimpleEventDto"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns a single event by its unique identifier",
        "tags": [
          "Events"
        ],
        "summary": "Get Event by ID",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": 123456,
            "description": "Event ID",
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/dto.SimpleEventDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/historical/events": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns finished events for a given sport and league within a date range. Maximum date span is 31 days. Historical data is available from December 2025 onwards.",
        "tags": [
          "Historical"
        ],
        "summary": "Get Historical Events",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"football\"",
            "description": "Sport slug (e.g. football, basketball)",
            "name": "sport",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"england-premier-league\"",
            "description": "League slug (e.g. england-premier-league)",
            "name": "league",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"2026-01-01T00:00:00Z\"",
            "description": "Start date in RFC3339 format",
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"2026-01-31T23:59:59Z\"",
            "description": "End date in RFC3339 format",
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/dto.SimpleEventDto"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/historical/events/search": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Searches finished events by team name across all leagues, optionally scoped to a sport. Maximum date span is 31 days (defaults to the trailing 31 days). Returns up to 100 events, newest first. Historical data is available from December 2025 onwards.",
        "tags": [
          "Historical"
        ],
        "summary": "Search Historical Events",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"Brann\"",
            "description": "Team name fragment, minimum 3 characters",
            "name": "query",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"football\"",
            "description": "Sport slug (e.g. football, basketball)",
            "name": "sport",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"2026-01-01T00:00:00Z\"",
            "description": "Start date in RFC3339 format",
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"2026-01-31T23:59:59Z\"",
            "description": "End date in RFC3339 format",
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/dto.SimpleEventDto"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/historical/odds": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns closing odds for a finished event from selected bookmakers, including scores.",
        "tags": [
          "Historical"
        ],
        "summary": "Get Historical Odds",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"123456\"",
            "description": "Event ID from /historical/events",
            "name": "eventId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"Bet365,SingBet\"",
            "description": "Comma-separated list of bookmaker names (max 30)",
            "name": "bookmakers",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"ML,Totals\"",
            "description": "Comma-separated market names to return (e.g. ML,Totals). Returns all markets when omitted.",
            "name": "markets",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.EventResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/historical/closing-lines": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns closing odds for every settled event across one or more leagues in a date range, in a single request. Paid plans only.",
        "tags": [
          "Historical"
        ],
        "summary": "Get Historical Closing Lines",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"football\"",
            "description": "Sport slug (e.g. football, basketball)",
            "name": "sport",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"england-premier-league,spain-la-liga\"",
            "description": "Comma-separated league slugs (max 10)",
            "name": "leagues",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"2026-01-01T00:00:00Z\"",
            "description": "Start date in RFC3339 format",
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"2026-12-31T23:59:59Z\"",
            "description": "End date in RFC3339 format. Maximum 366 days after from, so a full season fits in one sweep.",
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"ML,Totals\"",
            "description": "Comma-separated market names",
            "name": "markets",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"Bet365,Unibet\"",
            "description": "Comma-separated list of bookmaker names (max 30)",
            "name": "bookmakers",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": 100,
            "description": "Maximum number of events to return. Every response is capped at 100; use limit + skip to paginate.",
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "example": 0,
            "description": "Number of events to skip (for pagination)",
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/controllers.EventResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/leagues": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns a list of leagues (name, slug, event count) for a specified sport",
        "tags": [
          "Leagues"
        ],
        "summary": "Get Leagues",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"football\"",
            "description": "Sport slug (e.g. football, basketball)",
            "name": "sport",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": false,
            "description": "If true, include leagues without active events",
            "name": "all",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/controllers.LeagueResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/odds": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns odds comparison for a specific event from selected bookmakers.",
        "tags": [
          "Odds"
        ],
        "summary": "Get Event Odds",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"123456\"",
            "description": "Event ID",
            "name": "eventId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"Bet365,Unibet\"",
            "description": "Comma-separated list of bookmaker names (max 30)",
            "name": "bookmakers",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.EventResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/odds/movements": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns all historical odds movements for a specific market type and handicap line of a specific event from a bookmaker.",
        "tags": [
          "Odds"
        ],
        "summary": "Get Odds Movements",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"123456\"",
            "description": "Event ID",
            "name": "eventId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Bookmaker name (e.g. Bet365, SingBet)",
            "name": "bookmaker",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Market type name (e.g. ML, Spread, Totals)",
            "name": "market",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Handicap line (e.g. 0.5, 1.0, 2.5) - not required for ML markets",
            "name": "marketLine",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.HandicapMovementsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/odds/multi": {
      "get": {
        "description": "Returns odds comparison for up to 10 events from selected bookmakers (counts as only 1 request).",
        "tags": [
          "Odds"
        ],
        "summary": "Get Odds for Multiple Events",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated list of up to 10 Event IDs",
            "name": "eventIds",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated list of bookmaker names (max 30)",
            "name": "bookmakers",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/controllers.EventResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/odds/updated": {
      "get": {
        "description": "Returns updated event odds for a specific bookmaker since a given UNIX timestamp (max 90 seconds old)",
        "tags": [
          "Odds"
        ],
        "summary": "Get updated event odds since a given timestamp",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix timestamp (max 90 seconds old)",
            "name": "since",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Bookmaker name (e.g. Bet365)",
            "name": "bookmaker",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sport name (e.g. Football)",
            "name": "sport",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/controllers.EventResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/participants": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns participants (teams) for a specified sport",
        "tags": [
          "Participants"
        ],
        "summary": "Get Participants",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"football\"",
            "description": "Sport slug (e.g. football)",
            "name": "sport",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"Chelsea\"",
            "description": "Search term to filter by name",
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/dto.ParticipantDto"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/participants/{id}": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns a single participant by its unique identifier",
        "tags": [
          "Participants"
        ],
        "summary": "Get Participant by ID",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": 38,
            "description": "Participant ID",
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/dto.ParticipantDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/sports": {
      "get": {
        "description": "Returns a list of sports with name and slug",
        "tags": [
          "Sports"
        ],
        "summary": "Get Sports",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/controllers.SportResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/dropping-odds": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns odds that have dropped significantly from their opening values. Data is pre-computed and updated every ~30 seconds. Results are sorted by the selected time window's drop percentage (descending). Pagination metadata is returned in response headers (X-Total-Count, X-Page, X-Per-Page, X-Updated-At).\n\n**Data source selection:**\n- If both `sport` and `league` are provided → reads league-specific data (all entries for that league)\n- If only `sport` is provided → reads sport-level data (top 200 per sport)\n- If neither → reads global data (top 500 across all sports)\n\n**Note:** This endpoint requires a paid plan (Starter or above). Free plan users will receive a 403 error.\n\n**Note:** `leagues` and `league` are mutually exclusive. `leagues` fetches from the sport- or global-level dataset and filters server-side.",
        "tags": [
          "Dropping Odds"
        ],
        "summary": "Get Dropping Odds",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "football",
            "description": "Sport slug (e.g. football, basketball)",
            "name": "sport",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "england-premier-league",
            "description": "League slug (e.g. england-premier-league). Requires sport param. Mutually exclusive with leagues.",
            "name": "league",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "england-premier-league,spain-la-liga",
            "description": "Comma-separated league slugs to filter by multiple leagues at once (e.g. england-premier-league,spain-la-liga). Mutually exclusive with league.",
            "name": "leagues",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "Spread,Totals",
            "description": "Comma-separated market names to filter by (case-insensitive). Supported: ML, Spread, Totals, Spread HT, Totals HT, Totals 1Q, Spread 1Q, Team Total Home, Team Total Away, Corners Spread, Corners Totals, Corners Spread HT, Corners Totals HT, Bookings Spread, Bookings Totals, Player Props",
            "name": "markets",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "opening",
            "description": "Time window for drop filtering and sorting. Default: opening",
            "name": "timeWindow",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "opening",
                "12h",
                "24h",
                "48h"
              ],
              "default": "opening"
            }
          },
          {
            "example": 5,
            "description": "Minimum drop percentage for the selected time window. Default: 0",
            "name": "minDrop",
            "in": "query",
            "schema": {
              "type": "number",
              "default": 0
            }
          },
          {
            "example": 50,
            "description": "Maximum results per page (default 50, max 200)",
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "example": 1,
            "description": "Page number, 1-indexed (default 1)",
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "example": true,
            "description": "Include event details (home, away, date, sport, league). Default: false",
            "name": "includeEventDetails",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Total-Count": {
                "description": "Total number of entries matching the filters",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Page": {
                "description": "Current page number",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Per-Page": {
                "description": "Number of results per page",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Updated-At": {
                "description": "Timestamp of the last pipeline run (unix milliseconds)",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/dto.DroppingOddsEntry"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/value-bets": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns value bets for a specific bookmaker with optional match info. Updated every 5 seconds.",
        "tags": [
          "Value Bets"
        ],
        "summary": "Get Value Bets",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "\"Bet365\"",
            "description": "Bookmaker name (e.g. Bet365)",
            "name": "bookmaker",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "baseball",
            "description": "Filter by sport slug (e.g. baseball). Optional.",
            "name": "sport",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "example": "usa-mlb",
            "description": "Filter by league slug (e.g. usa-mlb). Requires sport to also be set.",
            "name": "league",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "example": true,
            "description": "Include event details",
            "name": "includeEventDetails",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/dto.EventValueBet"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/participants/{id}/logo": {
      "get": {
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Returns the team/participant crest as a PNG image, served from the Odds-API domain. Logos are cached server-side; responses carry Cache-Control: public, max-age=86400. Returns 404 when no logo exists for the participant.",
        "tags": [
          "Participants"
        ],
        "summary": "Get Participant Logo",
        "parameters": [
          {
            "description": "API key for authentication",
            "name": "apiKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": 38,
            "description": "Participant ID",
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PNG image",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Bad Gateway — transient upstream failure, retry later",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/controllers.ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "https://api.odds-api.io/v3"
    }
  ],
  "components": {
    "schemas": {
      "controllers.ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "example": "Error message"
          }
        }
      },
      "controllers.EventResponse": {
        "type": "object",
        "properties": {
          "away": {
            "type": "string"
          },
          "awayId": {
            "type": "integer"
          },
          "bookmakerIds": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "bookmakers": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/dto.MultiMarketDto"
              }
            }
          },
          "date": {
            "type": "string"
          },
          "home": {
            "type": "string"
          },
          "homeId": {
            "type": "integer"
          },
          "id": {
            "type": "integer"
          },
          "league": {
            "$ref": "#/components/schemas/controllers.League"
          },
          "scores": {
            "$ref": "#/components/schemas/dto.Score"
          },
          "sport": {
            "$ref": "#/components/schemas/controllers.Sport"
          },
          "status": {
            "type": "string"
          },
          "urls": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        }
      },
      "controllers.HandicapMovement": {
        "type": "object",
        "properties": {
          "away": {
            "type": "number"
          },
          "draw": {
            "type": "number"
          },
          "hdp": {
            "type": "string"
          },
          "home": {
            "type": "number"
          },
          "max": {
            "type": "integer"
          },
          "timestamp": {
            "type": "integer"
          }
        }
      },
      "controllers.HandicapMovementsResponse": {
        "type": "object",
        "properties": {
          "bookmaker": {
            "type": "string"
          },
          "eventid": {
            "type": "string"
          },
          "latest": {
            "$ref": "#/components/schemas/controllers.HandicapMovement"
          },
          "movements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/controllers.HandicapMovement"
            }
          },
          "opening": {
            "$ref": "#/components/schemas/controllers.HandicapMovement"
          }
        }
      },
      "controllers.League": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Premier League"
          },
          "slug": {
            "type": "string",
            "example": "premier-league"
          }
        }
      },
      "controllers.LeagueResponse": {
        "type": "object",
        "properties": {
          "eventsCount": {
            "type": "integer",
            "example": 32
          },
          "name": {
            "type": "string",
            "example": "England - Premier League"
          },
          "slug": {
            "type": "string",
            "example": "england-premier-league"
          }
        }
      },
      "controllers.Sport": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Football"
          },
          "slug": {
            "type": "string",
            "example": "football"
          }
        }
      },
      "controllers.SportResponse": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Football"
          },
          "slug": {
            "type": "string",
            "example": "football"
          }
        }
      },
      "dto.ArbitrageLeg": {
        "type": "object",
        "properties": {
          "bookmaker": {
            "type": "string"
          },
          "bookmakerFixtureId": {
            "type": "string"
          },
          "directLink": {
            "type": "string"
          },
          "href": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "odds": {
            "type": "string",
            "example": "0"
          },
          "side": {
            "description": "\"home\", \"away\", \"draw\"",
            "type": "string"
          }
        }
      },
      "dto.ArbitrageOpportunity": {
        "type": "object",
        "properties": {
          "event": {
            "description": "Only included if includeEventDetails=true",
            "allOf": [
              {
                "$ref": "#/components/schemas/dto.EventInfo"
              }
            ]
          },
          "eventId": {
            "type": "integer"
          },
          "id": {
            "type": "string"
          },
          "impliedProbability": {
            "type": "number"
          },
          "legs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/dto.ArbitrageLeg"
            }
          },
          "market": {
            "$ref": "#/components/schemas/dto.Market"
          },
          "optimalStakes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/dto.OptimalStake"
            }
          },
          "profitMargin": {
            "type": "number"
          },
          "totalStake": {
            "type": "number"
          },
          "updatedAt": {
            "type": "string"
          }
        }
      },
      "dto.BookmakerOdds": {
        "type": "object",
        "properties": {
          "away": {
            "type": "string"
          },
          "awayDirectLink": {
            "type": "string"
          },
          "draw": {
            "type": "string"
          },
          "drawDirectLink": {
            "type": "string"
          },
          "hdp": {
            "type": "string"
          },
          "home": {
            "type": "string"
          },
          "homeDirectLink": {
            "type": "string"
          },
          "href": {
            "type": "string"
          }
        }
      },
      "dto.EventInfo": {
        "type": "object",
        "properties": {
          "away": {
            "type": "string"
          },
          "date": {
            "type": "string"
          },
          "home": {
            "type": "string"
          },
          "league": {
            "type": "string"
          },
          "sport": {
            "type": "string"
          }
        }
      },
      "dto.EventValueBet": {
        "type": "object",
        "properties": {
          "betSide": {
            "type": "string"
          },
          "bookmaker": {
            "type": "string"
          },
          "bookmakerOdds": {
            "$ref": "#/components/schemas/dto.BookmakerOdds"
          },
          "event": {
            "$ref": "#/components/schemas/dto.EventInfo"
          },
          "eventId": {
            "type": "integer"
          },
          "expectedValue": {
            "type": "number"
          },
          "expectedValueUpdatedAt": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "market": {
            "$ref": "#/components/schemas/dto.MarketResult"
          }
        }
      },
      "dto.DroppingOddsEntry": {
        "type": "object",
        "properties": {
          "eventId": {
            "type": "integer",
            "example": 69455182
          },
          "event": {
            "$ref": "#/components/schemas/dto.DroppingOddsEvent"
          },
          "market": {
            "$ref": "#/components/schemas/dto.Market"
          },
          "betSide": {
            "type": "string",
            "enum": [
              "home",
              "away",
              "over",
              "under"
            ],
            "example": "home"
          },
          "odds": {
            "$ref": "#/components/schemas/dto.DroppingOddsMovement"
          },
          "lastMovedAt": {
            "type": "integer",
            "nullable": true,
            "description": "Unix milliseconds timestamp of last odds movement",
            "example": 1775851240182
          },
          "updatedAt": {
            "type": "integer",
            "description": "Unix milliseconds timestamp of last pipeline update",
            "example": 1775854172851
          }
        }
      },
      "dto.DroppingOddsEvent": {
        "type": "object",
        "properties": {
          "home": {
            "type": "string",
            "example": "Arsenal"
          },
          "away": {
            "type": "string",
            "example": "Bournemouth"
          },
          "date": {
            "type": "string",
            "description": "ISO 8601 date",
            "example": "2026-04-12T15:00:00.000Z"
          },
          "sport": {
            "$ref": "#/components/schemas/dto.Sport"
          },
          "league": {
            "$ref": "#/components/schemas/dto.League"
          }
        }
      },
      "dto.DroppingOddsMovement": {
        "type": "object",
        "properties": {
          "opening": {
            "type": "number",
            "description": "Opening odds value",
            "example": 2.05
          },
          "current": {
            "type": "number",
            "description": "Current odds value",
            "example": 1.52
          },
          "drop": {
            "$ref": "#/components/schemas/dto.OddsDrop"
          }
        }
      },
      "dto.OddsDrop": {
        "type": "object",
        "properties": {
          "sinceOpening": {
            "type": "number",
            "description": "Percentage drop since opening",
            "example": 25.9
          },
          "12h": {
            "type": "number",
            "nullable": true,
            "description": "Percentage drop in last 12 hours",
            "example": 8.4
          },
          "24h": {
            "type": "number",
            "nullable": true,
            "description": "Percentage drop in last 24 hours",
            "example": 12.3
          },
          "48h": {
            "type": "number",
            "nullable": true,
            "description": "Percentage drop in last 48 hours",
            "example": null
          }
        }
      },
      "dto.League": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          }
        }
      },
      "dto.Market": {
        "type": "object",
        "properties": {
          "hdp": {
            "type": "number"
          },
          "label": {
            "type": "string",
            "description": "Player name for player prop markets (e.g. \"Carlos Baleba\"). Only present on player prop entries."
          },
          "name": {
            "type": "string"
          }
        }
      },
      "dto.MarketResult": {
        "type": "object",
        "properties": {
          "away": {
            "type": "string"
          },
          "draw": {
            "type": "string"
          },
          "hdp": {
            "type": "number"
          },
          "home": {
            "type": "string"
          },
          "max": {
            "type": "number"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "dto.MultiMarketDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "odds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/dto.Odds"
            }
          },
          "updatedAt": {
            "type": "string"
          }
        }
      },
      "dto.Odds": {
        "type": "object",
        "properties": {
          "12": {
            "type": "string"
          },
          "1X": {
            "description": "Specialty market fields\nDouble Chance: 1X (home or draw), 12 (home or away), X2 (draw or away)",
            "type": "string"
          },
          "X2": {
            "type": "string"
          },
          "away": {
            "type": "string"
          },
          "awayLink": {
            "type": "string"
          },
          "depthAway": {
            "type": "string"
          },
          "depthDraw": {
            "type": "string"
          },
          "depthHome": {
            "type": "string"
          },
          "depthLayAway": {
            "type": "string"
          },
          "depthLayDraw": {
            "type": "string"
          },
          "depthLayHome": {
            "type": "string"
          },
          "depthLayNo": {
            "type": "string"
          },
          "depthLayOver": {
            "type": "string"
          },
          "depthLayUnder": {
            "type": "string"
          },
          "depthLayYes": {
            "type": "string"
          },
          "depthNo": {
            "type": "string"
          },
          "depthOver": {
            "type": "string"
          },
          "depthUnder": {
            "type": "string"
          },
          "depthYes": {
            "type": "string"
          },
          "draw": {
            "type": "string"
          },
          "drawLink": {
            "type": "string"
          },
          "even": {
            "type": "string"
          },
          "hdp": {
            "type": "number"
          },
          "home": {
            "type": "string"
          },
          "homeLink": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "layAway": {
            "type": "string"
          },
          "layDraw": {
            "type": "string"
          },
          "layHome": {
            "type": "string"
          },
          "layNo": {
            "type": "string"
          },
          "layOver": {
            "type": "string"
          },
          "layUnder": {
            "type": "string"
          },
          "layYes": {
            "type": "string"
          },
          "max": {
            "type": "integer"
          },
          "no": {
            "type": "string"
          },
          "none": {
            "description": "First Team To Score: none option",
            "type": "string"
          },
          "odd": {
            "description": "Odd/Even market",
            "type": "string"
          },
          "odds": {
            "description": "Labeled markets (Half Time / Full Time, Correct Score) - single odds value per outcome",
            "type": "string"
          },
          "over": {
            "type": "string"
          },
          "under": {
            "type": "string"
          },
          "yes": {
            "type": "string"
          }
        }
      },
      "dto.OptimalStake": {
        "type": "object",
        "properties": {
          "bookmaker": {
            "type": "string"
          },
          "potentialReturn": {
            "type": "number"
          },
          "side": {
            "type": "string"
          },
          "stake": {
            "type": "number"
          }
        }
      },
      "dto.ParticipantDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "sport": {
            "description": "slug format (e.g., \"football\")",
            "type": "string"
          }
        }
      },
      "dto.PeriodScore": {
        "type": "object",
        "properties": {
          "away": {
            "type": "integer"
          },
          "home": {
            "type": "integer"
          }
        }
      },
      "dto.Score": {
        "type": "object",
        "properties": {
          "away": {
            "type": "integer"
          },
          "home": {
            "type": "integer"
          },
          "periods": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/dto.PeriodScore"
            }
          }
        }
      },
      "dto.SimpleEventDto": {
        "type": "object",
        "properties": {
          "away": {
            "type": "string"
          },
          "awayId": {
            "type": "integer"
          },
          "bookmakerCount": {
            "type": "integer"
          },
          "date": {
            "type": "string"
          },
          "home": {
            "type": "string"
          },
          "homeId": {
            "type": "integer"
          },
          "id": {
            "type": "integer"
          },
          "league": {
            "$ref": "#/components/schemas/dto.League"
          },
          "scores": {
            "$ref": "#/components/schemas/dto.Score"
          },
          "sport": {
            "$ref": "#/components/schemas/dto.Sport"
          },
          "status": {
            "type": "string"
          },
          "clock": {
            "allOf": [
              {
                "$ref": "#/components/schemas/dto.ClockDto"
              }
            ],
            "description": "Live match clock (live events only; absent when no clock data is available)"
          }
        }
      },
      "dto.Sport": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          }
        }
      },
      "models.Bookmaker": {
        "type": "object",
        "properties": {
          "active": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "dto.ClockDto": {
        "type": "object",
        "description": "Live match-clock state for in-play events. minute/playedSeconds are extrapolated server-side from the live feed and only advance while running is true.",
        "properties": {
          "minute": {
            "type": "integer",
            "example": 67,
            "description": "Current match minute"
          },
          "playedSeconds": {
            "type": "integer",
            "example": 4023,
            "description": "Seconds of play elapsed"
          },
          "period": {
            "type": "integer",
            "example": 2,
            "description": "Current period number"
          },
          "running": {
            "type": "boolean",
            "example": true,
            "description": "Whether the clock is currently running"
          },
          "statusDetail": {
            "type": "string",
            "example": "2nd half",
            "description": "Human-readable phase of play"
          },
          "serve": {
            "type": "string",
            "enum": [
              "home",
              "away"
            ],
            "description": "Current server (tennis, table tennis, volleyball)"
          },
          "injuryTime": {
            "type": "integer",
            "example": 4,
            "description": "Announced injury/stoppage time in minutes (football)"
          }
        }
      }
    }
  }
}