openapi: 3.0.3
info:
  title: HTML to Image API
  description: |
    Convert HTML and CSS to PNG, JPEG, or WebP images. Render any HTML content
    in a real Chromium browser engine and get back an image. Perfect for generating
    OG images, social cards, certificates, invoices, email previews, and charts.
    Supports custom viewport sizes, retina scaling (2x/3x), dark mode, and quality control.

    **Authentication (optional):** Add an `X-API-Key` header for higher limits (5 req/min, 50/day vs anonymous 10/day cap).
    Get a free API key instantly at https://51-68-119-197.sslip.io/tools/html2image or POST to `/api/keys` with `{}` (anonymous, 20/day) or `{"email": "you@example.com"}` (50/day).

    Without a key: 5 requests per minute per IP. With a free key: 5 req/min, 50/day, 500/month.
  version: "1.0.0"
  contact:
    name: Hermes Agent
    email: hermes-agent@agentmail.to
    url: https://51-68-119-197.sslip.io/

externalDocs:
  description: Try this tool in the browser
  url: https://51-68-119-197.sslip.io/tools/html2image

servers:
  - url: https://51-68-119-197.sslip.io

paths:
  /api/html2image:
    post:
      operationId: renderHtmlToImage
      summary: Convert HTML/CSS to an image
      description: |
        Renders the provided HTML content in a headless Chromium browser and returns
        the result as a PNG, JPEG, or WebP image. Two body formats are supported:
        1. Raw HTML with Content-Type: text/html
        2. JSON with Content-Type: application/json: {"html": "...", "width": 1200, "height": 630, "format": "png", "scale": 2, "quality": 90}
        JSON body parameters are merged with query string parameters (query string takes precedence).
        Rate limited to 5 requests per minute per IP.
      parameters:
        - name: width
          in: query
          required: false
          description: Viewport width in pixels.
          schema:
            type: integer
            default: 800
            maximum: 1920
            example: 1200
        - name: height
          in: query
          required: false
          description: Viewport height in pixels.
          schema:
            type: integer
            default: 600
            maximum: 1080
            example: 630
        - name: format
          in: query
          required: false
          description: "Output image format: png (lossless), jpeg (smaller, supports quality), webp (modern, smallest)."
          schema:
            type: string
            enum: ["png", "jpeg", "webp"]
            default: "png"
        - name: scale
          in: query
          required: false
          description: "Device scale factor for retina output. 1 = standard, 2 = retina, 3 = 3x."
          schema:
            type: integer
            default: 1
            minimum: 1
            maximum: 3
        - name: quality
          in: query
          required: false
          description: Image quality (1-100). Applies to format=jpeg and format=webp only.
          schema:
            type: integer
            default: 80
            minimum: 1
            maximum: 100
        - name: dark_mode
          in: query
          required: false
          description: Emulate dark color scheme (prefers-color-scheme dark).
          schema:
            type: string
            enum: ["true", "false"]
            default: "false"
      requestBody:
        required: true
        description: |
          HTML content to render. Maximum 50KB. Two formats accepted:
          - Raw HTML body (Content-Type: text/html)
          - JSON object with "html" field and optional parameters (Content-Type: application/json)
        content:
          text/html:
            schema:
              type: string
              example: '<div style="background:linear-gradient(135deg,#667eea,#764ba2);padding:60px 40px;text-align:center"><h1 style="color:white;font-size:48px;margin:0">My Blog Post</h1><p style="color:#ddd;font-size:20px;margin-top:16px">Published March 2026</p></div>'
          application/json:
            schema:
              type: object
              required: [html]
              properties:
                html:
                  type: string
                  description: HTML content to render
                  example: '<div style="background:#1a1a2e;color:white;padding:60px;font-size:48px">Hello World</div>'
                width:
                  type: integer
                  description: Viewport width in pixels (max 1920)
                  example: 1200
                height:
                  type: integer
                  description: Viewport height in pixels (max 1080)
                  example: 630
                format:
                  type: string
                  enum: [png, jpeg, webp]
                  example: png
                scale:
                  type: integer
                  minimum: 1
                  maximum: 3
                  example: 2
                quality:
                  type: integer
                  minimum: 1
                  maximum: 100
                  example: 85
      responses:
        "200":
          description: Image rendered successfully.
          content:
            image/png:
              schema:
                type: string
                format: binary
            image/jpeg:
              schema:
                type: string
                format: binary
            image/webp:
              schema:
                type: string
                format: binary
        "400":
          description: Invalid request (missing HTML body or content too large).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Render failed.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: Server busy — too many concurrent render requests. Retry after a few seconds.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

security:
  - ApiKeyAuth: []
  - {}

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: |
        Optional API key for higher rate limits. Get one free at
        https://51-68-119-197.sslip.io/tools/html2image or POST /api/keys with {} (anonymous, 20/day) or {"email": "you@example.com"} (50/day).
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
          example: "HTML content too large (max 50KB)"
