openapi: 3.0.3
info:
  title: YTDL.my public API
  version: 0.1.0
  description: |
    YouTube download API. Authenticate with an API key from your account dashboard.
    Create a job with POST /api/v1/jobs, then download from the signed URL in the response.
    The raw extractor is not exposed; file delivery uses GET /api/v1/d with query parameters from the job result.
servers:
  - url: https://ytdl.my
    description: Production (replace with your `NEXT_PUBLIC_APP_URL`)
paths:
  /healthz:
    get:
      summary: Health check (alias)
      responses:
        "200":
          description: OK
  /api/healthz:
    get:
      summary: Health check
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    example: true
  /api/v1/jobs:
    post:
      summary: Create download job (blocking until complete upstream)
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - url
              properties:
                url:
                  type: string
                  minLength: 10
                  maxLength: 2000
                  description: YouTube watch or youtu.be URL
                minutes:
                  type: integer
                  minimum: 0
                  maximum: 43200
                  description: 0 = full video; else clip first N minutes
      responses:
        "200":
          description: Job finished (success or handled failure shape from upstream)
        "401":
          description: Missing or invalid API key
        "402":
          description: Inactive subscription or quota exceeded
        "502":
          description: Upstream worker error
  /api/v1/jobs/{job_id}:
    get:
      summary: Poll job status
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Job view
        "401":
          description: Unauthorized
  /api/v1/d:
    get:
      summary: Download file (signed query from job result)
      parameters:
        - name: job_id
          in: query
          required: true
          schema:
            type: string
        - name: e
          in: query
          required: true
          schema:
            type: integer
        - name: s
          in: query
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Binary stream
        "403":
          description: Bad or expired signature
        "404":
          description: File not found
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    BearerAuth:
      type: http
      scheme: bearer
