openapi: 3.0.3
info:
  title: Lottery Analytics API
  version: 1.2.0
  description: >
    Lottery Analytics API provides derived lottery analytics built on official state draw records.
    This API is analytical, not predictive. It exposes reproducible metrics such as combo frequencies,
    drought/gap behavior, positional statistics, historical draws, and Oracle-routed natural language analytics.
    No numerology, lucky-number generation, or speculative prediction outputs are provided.
servers:
  - url: https://lotteryanalytics.app/api/v1
    description: Production API v1
tags:
  - name: Games
  - name: Draws
  - name: Analytics
  - name: Oracle
paths:
  /games:
    get:
      tags: [Games]
      summary: List supported games
      description: Returns supported games and canonical game identifiers.
      operationId: listGames
      responses:
        "200":
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  games:
                    type: array
                    items:
                      $ref: "#/components/schemas/Game"
                required: [games]
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /games/{game_id}/draws:
    get:
      tags: [Draws]
      summary: List draws for a game
      description: Returns historical draw records for a specific game within optional date boundaries.
      operationId: getGameDraws
      parameters:
        - $ref: "#/components/parameters/GameId"
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
            default: 30
          description: Maximum number of draws to return.
        - name: from
          in: query
          required: false
          schema:
            type: string
            format: date
          description: Inclusive start date in YYYY-MM-DD.
        - name: to
          in: query
          required: false
          schema:
            type: string
            format: date
          description: Inclusive end date in YYYY-MM-DD.
      responses:
        "200":
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  game:
                    $ref: "#/components/schemas/Game"
                  filters:
                    $ref: "#/components/schemas/DateWindowFilters"
                  draws:
                    type: array
                    items:
                      $ref: "#/components/schemas/Draw"
                  meta:
                    type: object
                    properties:
                      count:
                        type: integer
                        minimum: 0
                required: [game, filters, draws, meta]
        "400":
          $ref: "#/components/responses/BadRequest"
        "404":
          $ref: "#/components/responses/GameNotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /games/{game_id}/latest:
    get:
      tags: [Draws]
      summary: Get latest draw for a game
      description: Returns the latest available draw constrained by configured historical boundaries.
      operationId: getLatestDraw
      parameters:
        - $ref: "#/components/parameters/GameId"
      responses:
        "200":
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LatestDraw"
        "404":
          $ref: "#/components/responses/GameNotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /games/{game_id}/hot-combos:
    get:
      tags: [Analytics]
      summary: Get combo frequency analytics
      description: >
        Returns derived combo frequency analytics for a game over a selected analysis window.
        Metrics are computed from official historical draw records.
      operationId: getHotCombos
      parameters:
        - $ref: "#/components/parameters/GameId"
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
            default: 30
          description: Analysis window size in draws.
        - name: from
          in: query
          required: false
          schema:
            type: string
            format: date
          description: Inclusive start date in YYYY-MM-DD.
        - name: to
          in: query
          required: false
          schema:
            type: string
            format: date
          description: Inclusive end date in YYYY-MM-DD.
      responses:
        "200":
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HotCombosAnalysis"
        "400":
          $ref: "#/components/responses/BadRequest"
        "404":
          $ref: "#/components/responses/GameNotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /games/{game_id}/positional-stats:
    get:
      tags: [Analytics]
      summary: Get positional digit analytics
      description: >
        Returns derived digit-frequency analytics by position for a game,
        computed from official historical draw records.
      operationId: getPositionalStats
      parameters:
        - $ref: "#/components/parameters/GameId"
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
            default: 30
          description: Analysis window size in draws.
        - name: from
          in: query
          required: false
          schema:
            type: string
            format: date
          description: Inclusive start date in YYYY-MM-DD.
        - name: to
          in: query
          required: false
          schema:
            type: string
            format: date
          description: Inclusive end date in YYYY-MM-DD.
      responses:
        "200":
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PositionalStats"
        "400":
          $ref: "#/components/responses/BadRequest"
        "404":
          $ref: "#/components/responses/GameNotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

  /ask:
    get:
      tags: [Oracle]
      summary: Natural language analytics query
      description: >
        Canonical AI-facing endpoint. Accepts a natural language lottery analytics question,
        routes it to the appropriate capability, and returns both structured data and an
        answer string. Analytical only: no predictions or numerology.
      operationId: askOracle
      parameters:
        - name: q
          in: query
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 500
          description: Natural language question.
      responses:
        "200":
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AskResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "404":
          $ref: "#/components/responses/GameNotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"

components:
  parameters:
    GameId:
      name: game_id
      in: path
      required: true
      description: Canonical game identifier, for example FL-PICK3 or NY-WIN4.
      schema:
        type: string

  responses:
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
    GameNotFound:
      description: Unknown or unsupported game identifier
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
    RateLimited:
      description: Rate limit exceeded
      headers:
        X-RateLimit-Limit:
          schema: { type: integer }
        X-RateLimit-Remaining:
          schema: { type: integer }
        X-RateLimit-Reset:
          schema: { type: integer, description: Unix timestamp }
        Retry-After:
          schema: { type: integer, description: Seconds until retry }
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
    InternalError:
      description: Unexpected server error
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"

  schemas:
    Game:
      type: object
      description: Canonical game metadata used for routing and analytics.
      properties:
        game_id:
          type: string
          description: Canonical identifier used in endpoint paths.
        name:
          type: string
        jurisdiction:
          type: string
          description: Jurisdiction code such as FL or NY.
        game_type:
          type: string
          description: Game family such as pick3 or pick4.
      required: [game_id, name, jurisdiction, game_type]

    Draw:
      type: object
      description: Single official draw record used as analytical input.
      properties:
        draw_date:
          type: string
          format: date
        draw_time:
          type: string
          description: Draw session indicator, for example evening or midday.
        result:
          type: string
          description: Draw result string.
      required: [draw_date, draw_time, result]

    LatestDraw:
      type: object
      description: Latest draw response bounded by configured historical limits.
      properties:
        game_id:
          type: string
        latest_draw:
          type: object
          properties:
            draw_id:
              type: string
            draw_date:
              type: string
              format: date
            draw_time:
              type: string
            result:
              type: string
            updated_at:
              type: string
              format: date-time
          required: [draw_id, draw_date, draw_time, result, updated_at]
        meta:
          type: object
          properties:
            config_start_date:
              type: string
              nullable: true
            config_end_date:
              type: string
              nullable: true
            total_draws:
              type: integer
              minimum: 0
          required: [config_start_date, config_end_date, total_draws]
      required: [game_id, latest_draw, meta]

    HotCombo:
      type: object
      description: Derived combo-level analytics over a selected window.
      properties:
        combo:
          type: string
        count:
          type: integer
          minimum: 0
        frequency:
          type: number
          format: float
          description: Relative frequency within the analysis window.
        draws_since:
          type: integer
          minimum: 0
          description: Draws since last occurrence.
        avg_gap:
          type: number
          format: float
          description: Average draw gap between occurrences.
        last_seen:
          type: object
          properties:
            draw_date:
              type: string
              format: date
            draw_time:
              type: string
          required: [draw_date, draw_time]
      required: [combo, count, frequency, draws_since, avg_gap, last_seen]

    HotCombosAnalysis:
      type: object
      description: Derived combo frequency analysis from official historical draws.
      properties:
        game:
          $ref: "#/components/schemas/Game"
        filters:
          $ref: "#/components/schemas/DateWindowFilters"
        analysis:
          type: object
          properties:
            total_draws:
              type: integer
              minimum: 0
            total_combos:
              type: integer
              minimum: 0
            hottest_combo:
              $ref: "#/components/schemas/HotCombo"
            combos:
              type: array
              items:
                $ref: "#/components/schemas/HotCombo"
          required: [total_draws, total_combos, hottest_combo, combos]
      required: [game, filters, analysis]

    PositionalStats:
      type: object
      description: Derived digit-frequency analytics by position.
      properties:
        game:
          $ref: "#/components/schemas/Game"
        filters:
          $ref: "#/components/schemas/DateWindowFilters"
        analysis:
          type: object
          properties:
            total_draws:
              type: integer
              minimum: 0
            positions:
              type: array
              items:
                type: object
                properties:
                  position:
                    type: integer
                    minimum: 1
                  hottest_digit:
                    type: string
                  hottest_count:
                    type: integer
                    minimum: 0
                  frequencies:
                    type: array
                    items:
                      type: object
                      properties:
                        digit:
                          type: string
                        count:
                          type: integer
                          minimum: 0
                      required: [digit, count]
                required: [position, hottest_digit, hottest_count, frequencies]
          required: [total_draws, positions]
      required: [game, filters, analysis]

    AskResponse:
      type: object
      description: >
        Oracle-routed natural language analytics response.
        Returns structured analytical data and an answer text, with capability and endpoint metadata.
      properties:
        query:
          type: string
        intent:
          type: string
          description: Capability-oriented intent classification.
        gameId:
          type: string
          nullable: true
        data:
          type: object
          additionalProperties: true
          description: Capability-specific structured analytics payload.
        answer:
          type: string
        canonicalEndpoint:
          type: string
          description: Canonical endpoint route corresponding to this answer.
        capabilityId:
          type: string
          description: Executed analytical capability identifier.
        timeScope:
          type: object
          properties:
            kind:
              type: string
            days:
              type: integer
              nullable: true
            draws:
              type: integer
              nullable: true
            from:
              type: string
              nullable: true
            to:
              type: string
              nullable: true
          required: [kind]
        timestamp:
          type: string
          format: date-time
      required:
        - query
        - intent
        - data
        - answer
        - canonicalEndpoint
        - capabilityId
        - timestamp

    DateWindowFilters:
      type: object
      properties:
        from:
          type: string
          nullable: true
        to:
          type: string
          nullable: true
        limit:
          type: integer
          minimum: 1
      required: [from, to, limit]

    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
          required: [code, message]
      required: [error]
