{
    "openapi": "3.0.3",
    "info": {
        "title": "InPlayGuru API",
        "version": "v1",
        "description": "The account side of InPlayGuru for your own code: the strategies you built and every pick they produced, with results and the match state behind each one. Read them, page through history, set a result by hand, create and manage strategies.\n\nPart of the Ultra plan and available only on it. Authenticate with your account's API key as a bearer token; generate it on the API settings page. Rate limit: 120 requests per minute per account. Full reference: https://inplayguru.com/developers/api",
        "contact": {
            "name": "InPlayGuru developer docs",
            "url": "https://inplayguru.com/developers"
        }
    },
    "externalDocs": {
        "description": "API reference",
        "url": "https://inplayguru.com/developers/api"
    },
    "servers": [
        {
            "url": "https://inplayguru.com/api/v1",
            "description": "InPlayGuru"
        }
    ],
    "security": [
        {
            "apiKey": []
        }
    ],
    "tags": [
        {
            "name": "Strategies",
            "description": "Your strategies, with the same counts and strike rate the app shows."
        },
        {
            "name": "Picks",
            "description": "Every pick your strategies produced, with its result and match state."
        }
    ],
    "paths": {
        "/picks": {
            "get": {
                "operationId": "listPicks",
                "tags": [
                    "Picks"
                ],
                "summary": "List picks",
                "description": "Picks across all your strategies or the ones you name. Newest first by default; use cursor to page back through history or after_id to tail new picks. Never send both.",
                "parameters": [
                    {
                        "name": "strategy_id",
                        "in": "query",
                        "description": "One strategy id or a comma-separated list. Only your own strategies.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "integer",
                                "format": "int64"
                            }
                        },
                        "style": "form",
                        "explode": false
                    },
                    {
                        "name": "result",
                        "in": "query",
                        "description": "open is every pick without a result: not completed yet, or ended without a verdict.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "hit",
                                "miss",
                                "open"
                            ]
                        }
                    },
                    {
                        "name": "created_after",
                        "in": "query",
                        "description": "Inclusive lower bound on the pick time, ISO 8601. A date alone means midnight UTC.",
                        "schema": {
                            "type": "string",
                            "format": "date-time"
                        }
                    },
                    {
                        "name": "created_before",
                        "in": "query",
                        "description": "Inclusive upper bound on the pick time, ISO 8601.",
                        "schema": {
                            "type": "string",
                            "format": "date-time"
                        }
                    },
                    {
                        "name": "league_id",
                        "in": "query",
                        "description": "A league id as it appears in pick payloads (match.league.id).",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "match_id",
                        "in": "query",
                        "description": "A match id as it appears in pick payloads. Returns every pick your strategies made on that match.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "description": "Expansions of the pick object, comma-separated, or all. Without it each pick is a compact row.",
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string",
                                "enum": [
                                    "snapshot",
                                    "prematch",
                                    "stats",
                                    "odds",
                                    "odds_series",
                                    "details",
                                    "all"
                                ]
                            }
                        },
                        "style": "form",
                        "explode": false
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Page size.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 20,
                            "default": 20
                        }
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "description": "Newest first: return picks with an id lower than this. Pass meta.next_cursor of the previous page.",
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "after_id",
                        "in": "query",
                        "description": "Oldest first: return picks with an id higher than this. Pass meta.last_id of the previous poll.",
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "minimum": 0
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of picks",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PickList"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/PlanRequired"
                    },
                    "422": {
                        "$ref": "#/components/responses/Unprocessable"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/picks/{id}": {
            "get": {
                "operationId": "getPick",
                "tags": [
                    "Picks"
                ],
                "summary": "Get a pick",
                "description": "One pick with every expansion applied: the numbers at the moment of the pick, the pre-match stats, the full-time stats and quotes, the odds series and the full team, league, season and stadium objects.",
                "responses": {
                    "200": {
                        "description": "The pick",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PickResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/PlanRequired"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "parameters": [
                    {
                        "$ref": "#/components/parameters/id"
                    }
                ]
            },
            "patch": {
                "operationId": "setPickResult",
                "tags": [
                    "Picks"
                ],
                "summary": "Set a result by hand",
                "description": "true = hit, false = miss, null = no result. Clears the automatic outcome (outcome_id becomes null, manual_result true) and the strategy's strike rate follows, exactly like the history page.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PickResult"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The updated pick",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PickResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/PlanRequired"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/Unprocessable"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "parameters": [
                    {
                        "$ref": "#/components/parameters/id"
                    }
                ]
            },
            "delete": {
                "operationId": "deletePick",
                "tags": [
                    "Picks"
                ],
                "summary": "Delete a pick",
                "description": "Removes the pick from the strategy history and from its counts, permanently.",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/PlanRequired"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "parameters": [
                    {
                        "$ref": "#/components/parameters/id"
                    }
                ]
            }
        },
        "/strategies": {
            "get": {
                "operationId": "listStrategies",
                "tags": [
                    "Strategies"
                ],
                "summary": "List strategies",
                "description": "Every strategy of the account, newest first, each with its stats. Not paginated: the whole list arrives in one response.",
                "responses": {
                    "200": {
                        "description": "All strategies",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StrategyList"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/PlanRequired"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "createStrategy",
                "tags": [
                    "Strategies"
                ],
                "summary": "Create a strategy",
                "description": "Creates a strategy that starts disabled and without rules. Rules are written in the app; the strategy can be enabled once it has at least one. Strategy slots apply exactly as in the app.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StrategyCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The new strategy",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StrategyDetailResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/StrategyLimit"
                    },
                    "422": {
                        "$ref": "#/components/responses/Unprocessable"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/strategies/import": {
            "post": {
                "operationId": "importStrategy",
                "tags": [
                    "Strategies"
                ],
                "summary": "Import a shared strategy",
                "description": "Copies a shared strategy into the account from the last segment of its share link, rules included, and enables it right away like the gallery import does.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StrategyImport"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The imported copy",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StrategyDetailResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/StrategyLimit"
                    },
                    "404": {
                        "description": "No strategy behind that share key (code unknown_share_key)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/Unprocessable"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/strategies/{id}": {
            "get": {
                "operationId": "getStrategy",
                "tags": [
                    "Strategies"
                ],
                "summary": "Get a strategy",
                "description": "One strategy with its per-league breakdown in leagues: the same rows the strategy page shows, biggest first.",
                "responses": {
                    "200": {
                        "description": "The strategy",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StrategyDetailResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/PlanRequired"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "parameters": [
                    {
                        "$ref": "#/components/parameters/id"
                    }
                ]
            },
            "patch": {
                "operationId": "updateStrategy",
                "tags": [
                    "Strategies"
                ],
                "summary": "Update a strategy",
                "description": "Partial update: send only the fields to change. Enabling a strategy without rules answers 422 with code no_rules. Changes reach the matching engine the same way a click in the app does.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StrategyUpdate"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The updated strategy",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StrategyDetailResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/PlanRequired"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/Unprocessable"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "parameters": [
                    {
                        "$ref": "#/components/parameters/id"
                    }
                ]
            },
            "delete": {
                "operationId": "deleteStrategy",
                "tags": [
                    "Strategies"
                ],
                "summary": "Delete a strategy",
                "description": "Deletes the strategy and every pick it ever made, permanently. There is no undo.",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/PlanRequired"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "parameters": [
                    {
                        "$ref": "#/components/parameters/id"
                    }
                ]
            }
        },
        "/strategies/{id}/duplicate": {
            "post": {
                "operationId": "duplicateStrategy",
                "tags": [
                    "Strategies"
                ],
                "summary": "Duplicate a strategy",
                "description": "Copies the strategy with its rules and league filter: named \"... (Copy)\", disabled, with an empty history and its own share link.",
                "responses": {
                    "201": {
                        "description": "The copy",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/StrategyDetailResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/StrategyLimit"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "parameters": [
                    {
                        "$ref": "#/components/parameters/id"
                    }
                ]
            }
        }
    },
    "components": {
        "securitySchemes": {
            "apiKey": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "API key",
                "description": "Your account's API key from https://inplayguru.com/settings/api, sent as \"Authorization: Bearer <key>\". One key per account; regenerating replaces it at once."
            }
        },
        "parameters": {
            "id": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "The resource id, as returned by the API.",
                "schema": {
                    "type": "integer",
                    "format": "int64"
                }
            }
        },
        "headers": {
            "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for the account.",
                "schema": {
                    "type": "integer"
                }
            },
            "X-RateLimit-Remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                    "type": "integer"
                }
            },
            "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                    "type": "integer"
                }
            }
        },
        "responses": {
            "Unauthorized": {
                "description": "No usable API key on the request (codes missing_api_key, invalid_api_key, expired_api_key).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "PlanRequired": {
                "description": "The account is not on the Ultra plan (code plan_required, carries upgrade_url).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "StrategyLimit": {
                "description": "Every strategy slot is in use (code strategy_limit_reached, carries max and current).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "NotFound": {
                "description": "No such strategy or pick in your account.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "Unprocessable": {
                "description": "Understood but not applicable as sent: field validation (errors object) or a coded refusal such as no_rules, nothing_to_update, conflicting_cursors, unknown_strategy, invalid_strategy_id, unknown_league, unknown_include.",
                "content": {
                    "application/json": {
                        "schema": {
                            "oneOf": [
                                {
                                    "$ref": "#/components/schemas/ValidationError"
                                },
                                {
                                    "$ref": "#/components/schemas/Error"
                                }
                            ]
                        }
                    }
                }
            },
            "RateLimited": {
                "description": "Over the per-account ceiling (code rate_limited). Wait for Retry-After seconds.",
                "headers": {
                    "Retry-After": {
                        "$ref": "#/components/headers/Retry-After"
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "required": [
                    "message"
                ],
                "properties": {
                    "message": {
                        "type": "string"
                    },
                    "code": {
                        "type": "string",
                        "description": "Stable code to branch on, present where it helps."
                    }
                },
                "additionalProperties": true
            },
            "ValidationError": {
                "type": "object",
                "required": [
                    "message",
                    "errors"
                ],
                "properties": {
                    "message": {
                        "type": "string"
                    },
                    "errors": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    }
                }
            },
            "Outcome": {
                "type": "object",
                "required": [
                    "id",
                    "label"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "label": {
                        "type": "string",
                        "nullable": true
                    }
                }
            },
            "LeagueFilter": {
                "type": "object",
                "required": [
                    "id",
                    "name"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "format": "int64"
                    },
                    "name": {
                        "type": "string"
                    }
                }
            },
            "StrategyStats": {
                "type": "object",
                "required": [
                    "picks",
                    "hits",
                    "misses",
                    "open",
                    "strike_rate"
                ],
                "properties": {
                    "picks": {
                        "type": "integer"
                    },
                    "hits": {
                        "type": "integer"
                    },
                    "misses": {
                        "type": "integer"
                    },
                    "open": {
                        "type": "integer",
                        "description": "Picks without a result."
                    },
                    "strike_rate": {
                        "type": "integer",
                        "nullable": true,
                        "minimum": 0,
                        "maximum": 100,
                        "description": "Hits as a percentage of settled picks; null while nothing has settled."
                    }
                }
            },
            "Strategy": {
                "type": "object",
                "required": [
                    "id",
                    "name",
                    "enabled",
                    "alerts_enabled",
                    "outcome",
                    "is_prematch",
                    "prematch_lead_minutes",
                    "note",
                    "league_filter",
                    "rules_count",
                    "stats",
                    "share_url",
                    "created_at",
                    "updated_at"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "format": "int64"
                    },
                    "name": {
                        "type": "string",
                        "maxLength": 80
                    },
                    "enabled": {
                        "type": "boolean"
                    },
                    "alerts_enabled": {
                        "type": "boolean",
                        "description": "Whether picks are sent to Telegram. Picks are recorded and delivered to webhooks either way."
                    },
                    "outcome": {
                        "nullable": true,
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/Outcome"
                            }
                        ]
                    },
                    "is_prematch": {
                        "type": "boolean"
                    },
                    "prematch_lead_minutes": {
                        "type": "integer",
                        "nullable": true,
                        "minimum": 1,
                        "maximum": 10080
                    },
                    "note": {
                        "type": "string",
                        "nullable": true,
                        "maxLength": 2000
                    },
                    "league_filter": {
                        "nullable": true,
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/LeagueFilter"
                            }
                        ]
                    },
                    "rules_count": {
                        "type": "integer",
                        "description": "Zero means the strategy cannot be enabled yet."
                    },
                    "stats": {
                        "$ref": "#/components/schemas/StrategyStats"
                    },
                    "share_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "StrategyCreate": {
                "type": "object",
                "required": [
                    "name"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                    },
                    "outcome_id": {
                        "type": "integer",
                        "nullable": true,
                        "description": "An outcome id as used by the app's outcome picker."
                    },
                    "note": {
                        "type": "string",
                        "nullable": true,
                        "maxLength": 2000
                    },
                    "alerts_enabled": {
                        "type": "boolean",
                        "default": true
                    },
                    "prematch_lead_minutes": {
                        "type": "integer",
                        "nullable": true,
                        "minimum": 1,
                        "maximum": 10080,
                        "description": "Minutes before kickoff for a pre-match strategy; null means in-play."
                    }
                }
            },
            "StrategyUpdate": {
                "type": "object",
                "minProperties": 1,
                "properties": {
                    "name": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                    },
                    "enabled": {
                        "type": "boolean"
                    },
                    "alerts_enabled": {
                        "type": "boolean"
                    },
                    "outcome_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "note": {
                        "type": "string",
                        "nullable": true,
                        "maxLength": 2000
                    },
                    "prematch_lead_minutes": {
                        "type": "integer",
                        "nullable": true,
                        "minimum": 1,
                        "maximum": 10080
                    }
                }
            },
            "StrategyImport": {
                "type": "object",
                "required": [
                    "share_key"
                ],
                "properties": {
                    "share_key": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "The last segment of a share link (/s/{share_key})."
                    }
                }
            },
            "LeagueStats": {
                "type": "object",
                "description": "One league of a strategy's breakdown, from the same counters the strategy page shows.",
                "required": [
                    "league",
                    "picks",
                    "hits",
                    "misses",
                    "open",
                    "strike_rate",
                    "fair_odd"
                ],
                "properties": {
                    "league": {
                        "type": "object",
                        "required": [
                            "id",
                            "name",
                            "cc"
                        ],
                        "properties": {
                            "id": {
                                "type": "string",
                                "description": "Opaque league id, the same one pick payloads carry. Usable as the league_id filter of the picks list."
                            },
                            "name": {
                                "type": "string",
                                "nullable": true
                            },
                            "cc": {
                                "type": "string",
                                "nullable": true
                            }
                        }
                    },
                    "picks": {
                        "type": "integer"
                    },
                    "hits": {
                        "type": "integer"
                    },
                    "misses": {
                        "type": "integer"
                    },
                    "open": {
                        "type": "integer",
                        "description": "Picks without a result."
                    },
                    "strike_rate": {
                        "type": "integer",
                        "nullable": true,
                        "minimum": 0,
                        "maximum": 100
                    },
                    "fair_odd": {
                        "type": "number",
                        "nullable": true,
                        "description": "100 divided by the strike rate, as on the strategy page; null while no pick has hit."
                    }
                }
            },
            "StrategyDetail": {
                "description": "A strategy as returned by every single-strategy endpoint: the list item plus its per-league breakdown.",
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Strategy"
                    },
                    {
                        "type": "object",
                        "required": [
                            "leagues"
                        ],
                        "properties": {
                            "leagues": {
                                "type": "array",
                                "description": "One row per league the strategy has picked in, biggest first. Empty until the first pick.",
                                "items": {
                                    "$ref": "#/components/schemas/LeagueStats"
                                }
                            }
                        }
                    }
                ]
            },
            "StrategyDetailResponse": {
                "type": "object",
                "required": [
                    "data"
                ],
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/StrategyDetail"
                    }
                }
            },
            "StrategyList": {
                "type": "object",
                "required": [
                    "data"
                ],
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Strategy"
                        }
                    }
                }
            },
            "TeamRef": {
                "type": "object",
                "description": "Compact by default (id, name, cc). With include=details the full team object as webhooks carry it (form, formation, manager, market value and more, when covered).",
                "required": [
                    "id",
                    "name"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Opaque id. Compare byte-for-byte, never parse."
                    },
                    "name": {
                        "type": "string",
                        "nullable": true
                    },
                    "cc": {
                        "type": "string",
                        "nullable": true
                    }
                },
                "additionalProperties": true
            },
            "LeagueRef": {
                "type": "object",
                "description": "Compact by default (id, name, cc). With include=details the full league object (table positions, round) when known.",
                "required": [
                    "id",
                    "name"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Opaque id. Usable as the league_id filter of the picks list."
                    },
                    "name": {
                        "type": "string",
                        "nullable": true
                    },
                    "cc": {
                        "type": "string",
                        "nullable": true
                    }
                },
                "additionalProperties": true
            },
            "Timer": {
                "type": "object",
                "description": "The match clock at the moment of the pick: min, live, stage (stage map on the webhooks page) and injury-time info where the feed provides it.",
                "properties": {
                    "min": {
                        "type": "integer",
                        "nullable": true
                    },
                    "live": {
                        "type": "boolean"
                    },
                    "stage": {
                        "type": "integer"
                    }
                },
                "additionalProperties": true
            },
            "Quote": {
                "type": "object",
                "description": "One recorded quote of a market: odd_home, odd_draw, odd_away, odd_over, odd_under, odd_yes, odd_no, odd_odd, odd_even, handicap and ss (the score the quote was taken at), as the market provides them.",
                "additionalProperties": true
            },
            "OddsPoint": {
                "description": "A quote with the match minute it was recorded at. The quote taken before kickoff comes first, with minute null.",
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Quote"
                    },
                    {
                        "type": "object",
                        "required": [
                            "minute"
                        ],
                        "properties": {
                            "minute": {
                                "type": "integer",
                                "nullable": true
                            }
                        }
                    }
                ]
            },
            "PrematchWindow": {
                "type": "object",
                "description": "One sample of matches, split by where they were played. Every value is a [home, away] pair: this fixture's home team first.",
                "required": [
                    "all",
                    "home",
                    "away"
                ],
                "properties": {
                    "all": {
                        "type": "array",
                        "description": "[home, away]",
                        "items": {
                            "type": "number",
                            "nullable": true
                        },
                        "minItems": 2,
                        "maxItems": 2,
                        "nullable": true
                    },
                    "home": {
                        "type": "array",
                        "description": "[home, away]",
                        "items": {
                            "type": "number",
                            "nullable": true
                        },
                        "minItems": 2,
                        "maxItems": 2,
                        "nullable": true
                    },
                    "away": {
                        "type": "array",
                        "description": "[home, away]",
                        "items": {
                            "type": "number",
                            "nullable": true
                        },
                        "minItems": 2,
                        "maxItems": 2,
                        "nullable": true
                    }
                }
            },
            "PrematchStat": {
                "type": "object",
                "description": "One pre-match stat. Keys ending in _pc are percentages from 0 to 100, everything else is a per-match average. A sample the feed could not fill is null, never zero.",
                "required": [
                    "last_5",
                    "last_10",
                    "h2h"
                ],
                "properties": {
                    "last_5": {
                        "nullable": true,
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/PrematchWindow"
                            }
                        ]
                    },
                    "last_10": {
                        "nullable": true,
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/PrematchWindow"
                            }
                        ]
                    },
                    "h2h": {
                        "type": "number",
                        "nullable": true,
                        "description": "The last 5 head-to-head meetings, from the home team's side."
                    }
                }
            },
            "Prematch": {
                "type": "object",
                "description": "What was known before kickoff: both teams' stats and the pre-match quotes. Present with include=prematch.",
                "required": [
                    "stats",
                    "odds"
                ],
                "properties": {
                    "stats": {
                        "type": "object",
                        "description": "Stat key to its samples, for example goals_scored_avg, btts_pc, o_25_pc, corners_for, win_pc.",
                        "additionalProperties": {
                            "$ref": "#/components/schemas/PrematchStat"
                        }
                    },
                    "odds": {
                        "type": "object",
                        "description": "Market id to the quote taken before kickoff.",
                        "additionalProperties": {
                            "$ref": "#/components/schemas/Quote"
                        }
                    }
                }
            },
            "Match": {
                "type": "object",
                "description": "The picked match. Everything that changes during a match (score, score_ht, stats, stats_ht, odds, odds_series) is its full-time value and stays null until ended is true. What the strategy saw when it fired is in the pick's snapshot.",
                "required": [
                    "id",
                    "date",
                    "ended",
                    "score",
                    "score_ht",
                    "favorite",
                    "home",
                    "away",
                    "league"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Opaque id. Usable as the match_id filter of the picks list."
                    },
                    "date": {
                        "type": "string",
                        "nullable": true,
                        "description": "Kickoff, ISO 8601 UTC."
                    },
                    "ended": {
                        "type": "boolean",
                        "description": "Whether the match has ended and its full-time values are filled in."
                    },
                    "score": {
                        "type": "array",
                        "description": "[home, away]",
                        "items": {
                            "type": "integer",
                            "nullable": true
                        },
                        "minItems": 2,
                        "maxItems": 2,
                        "nullable": true
                    },
                    "score_ht": {
                        "type": "array",
                        "description": "[home, away]",
                        "items": {
                            "type": "integer",
                            "nullable": true
                        },
                        "minItems": 2,
                        "maxItems": 2,
                        "nullable": true
                    },
                    "favorite": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Pre-match favorite: 0 home, 1 away, null none. Never test it with truthiness: 0 is a real value."
                    },
                    "home": {
                        "nullable": true,
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/TeamRef"
                            }
                        ]
                    },
                    "away": {
                        "nullable": true,
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/TeamRef"
                            }
                        ]
                    },
                    "league": {
                        "nullable": true,
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/LeagueRef"
                            }
                        ]
                    },
                    "season": {
                        "type": "object",
                        "nullable": true,
                        "additionalProperties": true,
                        "description": "With include=details."
                    },
                    "stadium": {
                        "type": "object",
                        "nullable": true,
                        "additionalProperties": true,
                        "description": "With include=details. Carries a weather object when conditions are known."
                    },
                    "prematch": {
                        "$ref": "#/components/schemas/Prematch"
                    },
                    "stats": {
                        "type": "object",
                        "description": "Stat key to [home, away] pair. An absent key means the stat was not covered, never zero.",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "number",
                                "nullable": true
                            },
                            "minItems": 2,
                            "maxItems": 2
                        },
                        "nullable": true
                    },
                    "stats_ht": {
                        "type": "object",
                        "description": "Stat key to [home, away] pair. An absent key means the stat was not covered, never zero.",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "number",
                                "nullable": true
                            },
                            "minItems": 2,
                            "maxItems": 2
                        },
                        "nullable": true
                    },
                    "odds": {
                        "type": "object",
                        "description": "Market id to quote entry (odd_home, odd_draw, odd_away, odd_over, odd_under, odd_yes, odd_no, odd_odd, odd_even, handicap, ss, suspended, curr_line). Market ids are documented on the webhooks page.",
                        "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                        },
                        "nullable": true
                    },
                    "odds_series": {
                        "type": "object",
                        "nullable": true,
                        "description": "With include=odds_series. Market id to every recorded quote in minute order, from before kickoff to the final whistle; null until the match has ended.",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "$ref": "#/components/schemas/OddsPoint"
                            }
                        }
                    }
                }
            },
            "Snapshot": {
                "type": "object",
                "description": "The moment of the pick: the score, clock, detailed stats and quotes the strategy evaluated when it fired. Same numbers as data.match of a pick.created webhook event. Present with include=snapshot.",
                "required": [
                    "score",
                    "timer",
                    "stats",
                    "odds"
                ],
                "properties": {
                    "score": {
                        "type": "array",
                        "description": "[home, away]",
                        "items": {
                            "type": "integer",
                            "nullable": true
                        },
                        "minItems": 2,
                        "maxItems": 2,
                        "nullable": true
                    },
                    "timer": {
                        "nullable": true,
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/Timer"
                            }
                        ]
                    },
                    "stats": {
                        "type": "object",
                        "description": "Stat key to [home, away] pair. An absent key means the stat was not covered, never zero.",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "number",
                                "nullable": true
                            },
                            "minItems": 2,
                            "maxItems": 2
                        }
                    },
                    "odds": {
                        "type": "object",
                        "description": "Market id to quote entry (odd_home, odd_draw, odd_away, odd_over, odd_under, odd_yes, odd_no, odd_odd, odd_even, handicap, ss, suspended, curr_line). Market ids are documented on the webhooks page.",
                        "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            },
            "Pick": {
                "type": "object",
                "required": [
                    "id",
                    "strategy_id",
                    "strategy",
                    "created_at",
                    "updated_at",
                    "minute",
                    "score",
                    "is_prematch",
                    "result",
                    "strike",
                    "outcome_id",
                    "manual_result",
                    "match"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "format": "int64"
                    },
                    "strategy_id": {
                        "type": "integer",
                        "format": "int64"
                    },
                    "strategy": {
                        "type": "object",
                        "nullable": true,
                        "required": [
                            "id",
                            "name"
                        ],
                        "properties": {
                            "id": {
                                "type": "integer",
                                "format": "int64"
                            },
                            "name": {
                                "type": "string"
                            }
                        }
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "minute": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Match minute at the moment of the pick; null for a pick made before kickoff."
                    },
                    "score": {
                        "type": "array",
                        "description": "[home, away]",
                        "items": {
                            "type": "integer",
                            "nullable": true
                        },
                        "minItems": 2,
                        "maxItems": 2,
                        "nullable": true
                    },
                    "is_prematch": {
                        "type": "boolean",
                        "nullable": true
                    },
                    "result": {
                        "type": "string",
                        "enum": [
                            "hit",
                            "miss",
                            "pending",
                            "unresolved"
                        ],
                        "description": "pending until the match has ended; unresolved once it ended without a verdict."
                    },
                    "strike": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Hit, miss, no result. Never collapse it with a truthiness check."
                    },
                    "outcome_id": {
                        "type": "integer",
                        "nullable": true,
                        "description": "The outcome the result was settled on; null while open and after a result set by hand."
                    },
                    "manual_result": {
                        "type": "boolean"
                    },
                    "match": {
                        "nullable": true,
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/Match"
                            }
                        ]
                    },
                    "snapshot": {
                        "$ref": "#/components/schemas/Snapshot"
                    }
                }
            },
            "PickResult": {
                "type": "object",
                "required": [
                    "strike"
                ],
                "properties": {
                    "strike": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "true = hit, false = miss, null = clear the result."
                    }
                }
            },
            "PickListMeta": {
                "type": "object",
                "required": [
                    "limit",
                    "has_more",
                    "next_cursor",
                    "last_id"
                ],
                "properties": {
                    "limit": {
                        "type": "integer"
                    },
                    "has_more": {
                        "type": "boolean"
                    },
                    "next_cursor": {
                        "type": "string",
                        "nullable": true,
                        "description": "Newest-first pages: pass it back as cursor. Null on the last page."
                    },
                    "last_id": {
                        "type": "integer",
                        "format": "int64",
                        "nullable": true,
                        "description": "Oldest-first tailing: the highest id in this page, pass it back as after_id. Null when the page is empty."
                    }
                }
            },
            "PickResponse": {
                "type": "object",
                "required": [
                    "data"
                ],
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/Pick"
                    }
                }
            },
            "PickList": {
                "type": "object",
                "required": [
                    "data",
                    "meta"
                ],
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Pick"
                        }
                    },
                    "meta": {
                        "$ref": "#/components/schemas/PickListMeta"
                    }
                }
            }
        }
    }
}