openapi: 3.1.0
info:
  title: Base64 Image Encoder API
  description: REST API to convert images to base64 encoding programmatically. Supports single and batch image encoding with optional optimization.
  version: "1.0"
  contact:
    name: Geek Cell GmbH
    url: https://www.base64-image.de
  termsOfService: https://www.base64-image.de/terms-of-use

servers:
  - url: https://www.base64-image.de/api/v1
    description: Production

security:
  - bearerAuth: []

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API token from your dashboard

  headers:
    X-RateLimit-Limit:
      description: Maximum requests per minute
      schema:
        type: integer
        example: 60
    X-RateLimit-Remaining:
      description: Requests remaining in the current window
      schema:
        type: integer
        example: 57
    Retry-After:
      description: Seconds to wait before retrying (only on 429)
      schema:
        type: integer
        example: 42

  schemas:
    EncodedImage:
      type: object
      properties:
        name:
          type: string
          example: photo.jpg
        extension:
          type: string
          example: jpg
        size:
          type: integer
          description: Original file size in bytes
          example: 45231
        size_encoded:
          type: integer
          description: Base64 encoded size in bytes
          example: 60308
        mime_type:
          type: string
          example: image/jpeg
        width:
          type: integer
          example: 800
        height:
          type: integer
          example: 600
        convert_time:
          type: number
          format: float
          description: Processing time in seconds
          example: 0.042
        optimized:
          type: integer
          enum: [0, 1]
          description: Whether the image was optimized before encoding
          example: 0
        output:
          type: string
          description: "Encoded image data. Format depends on the `format` parameter: raw base64 (default), data URI, HTML img tag, CSS background, Markdown, or JSON."
          example: "/9j/4AAQSkZJRg..."
        tokens_used:
          type: integer
          description: Tokens consumed for this conversion
          example: 1
        resized:
          type: boolean
          description: Whether the image was resized or transformed before encoding. Only present when true.
          example: true
        original_width:
          type: integer
          description: Original image width before resize. Only present when resized.
          example: 1920
        original_height:
          type: integer
          description: Original image height before resize. Only present when resized.
          example: 1080
        original_size:
          type: integer
          description: Original file size in bytes before resize. Only present when resized.
          example: 245000
        resize_warning:
          type: string
          description: Warning about the resize operation (e.g. GIF animation loss). Only present when applicable.
          example: "GIF animation is lost when resizing."

    Error:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
          description: Machine-readable error code
          example: no_file
        message:
          type: string
          description: Human-readable error message
          example: No valid file upload given.
        purchase_url:
          type: string
          description: URL to purchase more tokens (included on 402 responses)
          example: https://www.base64-image.de/dashboard

    TokenTier:
      type: object
      properties:
        up_to_mb:
          type: integer
          example: 1
        tokens:
          type: integer
          example: 1

    ApiToken:
      type: object
      properties:
        id:
          type: string
          example: 01jq7x8k9m2n3p4r5s6t7v8w
        name:
          type: string
          example: My Project
        is_enabled:
          type: boolean
          example: true
        last_used_at:
          type: string
          format: date-time
          nullable: true
          example: "2026-03-27T14:30:00+00:00"
        created_at:
          type: string
          format: date-time
          example: "2026-03-01T10:00:00+00:00"

paths:
  /encode:
    post:
      summary: Encode single image
      description: Upload a single image file and receive its encoded representation. Use the `format` parameter to control the output format (raw base64, data URI, HTML img tag, CSS background, Markdown, or JSON).
      operationId: encode
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - image
              properties:
                image:
                  type: string
                  format: binary
                  description: "Image file. Accepted formats: jpg, jpeg, jfif, png, gif, bmp, svg, webp, ico, tiff, tif, avif, heic, heif. Max 5 MB."
                optimize-images:
                  type: string
                  enum: ["true", "false"]
                  description: Set to "true" to optimize JPEG/PNG before encoding.
                  default: "false"
                format:
                  type: string
                  enum: [raw, data_uri, image, css, css_full, markdown, json]
                  description: "Controls the format of the `output` field. Default: `raw` (plain base64 string)."
                  default: "raw"
                max_width:
                  type: integer
                  minimum: 1
                  maximum: 4096
                  description: "Resize image to fit within this width (in pixels), maintaining aspect ratio. Not applicable to SVG."
                max_height:
                  type: integer
                  minimum: 1
                  maximum: 4096
                  description: "Resize image to fit within this height (in pixels), maintaining aspect ratio. Not applicable to SVG."
                quality:
                  type: integer
                  minimum: 1
                  maximum: 100
                  description: "Output quality for lossy formats (JPEG, WebP). Default: 80. Lower values produce smaller base64 strings."
                output_format:
                  type: string
                  enum: [jpeg, jpg, png, webp]
                  description: "Convert image to this format before encoding. Useful for reducing base64 size (e.g. PNG to WebP)."
      responses:
        "200":
          description: Image encoded successfully
          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/EncodedImage"
        "400":
          description: No file provided
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: no_file
                message: No valid file upload given.
        "402":
          description: Insufficient tokens
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: insufficient_tokens
                message: This file costs 1 token but you only have 0 remaining.
                purchase_url: https://www.base64-image.de/dashboard
        "413":
          description: File too large
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: file_too_large
                message: This file is too large. Try reducing the image dimensions or quality before uploading.
        "422":
          description: Unsupported file type
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: unsupported_format
                message: Unsupported file type.
        "429":
          description: Rate limit exceeded
          headers:
            Retry-After:
              $ref: "#/components/headers/Retry-After"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: rate_limit_exceeded
                message: Too Many Attempts.

  /encode/batch:
    post:
      summary: Encode batch (up to 20 images)
      description: Upload multiple image files. Each file is processed individually and deducts tokens separately. If a single file fails, its entry contains error fields while other files are still processed.
      operationId: encodeBatch
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - "images[]"
              properties:
                "images[]":
                  type: array
                  items:
                    type: string
                    format: binary
                  maxItems: 20
                  description: Array of image files. Maximum 20 files per request.
                optimize-images:
                  type: string
                  enum: ["true", "false"]
                  description: Set to "true" to optimize all images before encoding.
                  default: "false"
                format:
                  type: string
                  enum: [raw, data_uri, image, css, css_full, markdown, json]
                  description: "Controls the format of the `output` field in each result. Default: `raw` (plain base64 string)."
                  default: "raw"
                max_width:
                  type: integer
                  minimum: 1
                  maximum: 4096
                  description: "Resize all images to fit within this width (in pixels), maintaining aspect ratio."
                max_height:
                  type: integer
                  minimum: 1
                  maximum: 4096
                  description: "Resize all images to fit within this height (in pixels), maintaining aspect ratio."
                quality:
                  type: integer
                  minimum: 1
                  maximum: 100
                  description: "Output quality for lossy formats (JPEG, WebP). Default: 80."
                output_format:
                  type: string
                  enum: [jpeg, jpg, png, webp]
                  description: "Convert all images to this format before encoding."
      responses:
        "200":
          description: All images encoded successfully
          headers:
            X-RateLimit-Limit:
              $ref: "#/components/headers/X-RateLimit-Limit"
            X-RateLimit-Remaining:
              $ref: "#/components/headers/X-RateLimit-Remaining"
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      allOf:
                        - $ref: "#/components/schemas/EncodedImage"
                        - type: object
                          properties:
                            status:
                              type: string
                              enum: [success, error]
        "207":
          description: Partial success (some files failed)
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      oneOf:
                        - allOf:
                            - $ref: "#/components/schemas/EncodedImage"
                            - type: object
                              properties:
                                status:
                                  type: string
                                  const: success
                        - allOf:
                            - $ref: "#/components/schemas/Error"
                            - type: object
                              properties:
                                status:
                                  type: string
                                  const: error
        "402":
          description: Insufficient tokens for entire batch
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: insufficient_tokens
                message: This batch requires 5 tokens but you only have 2 remaining.
                purchase_url: https://www.base64-image.de/dashboard
        "422":
          description: Too many files in batch
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              example:
                error: too_many_files
                message: Maximum 20 files per batch request.

  /usage:
    get:
      summary: Check usage
      description: Returns your current token balance, usage stats, and pricing tiers.
      operationId: getUsage
      responses:
        "200":
          description: Usage statistics
          headers:
            X-RateLimit-Limit:
              $ref: "#/components/headers/X-RateLimit-Limit"
            X-RateLimit-Remaining:
              $ref: "#/components/headers/X-RateLimit-Remaining"
          content:
            application/json:
              schema:
                type: object
                properties:
                  total_remaining:
                    type: integer
                    example: 9587
                  api_calls_this_month:
                    type: integer
                    example: 13
                  tokens_used_this_month:
                    type: integer
                    example: 18
                  token_tiers:
                    type: array
                    items:
                      $ref: "#/components/schemas/TokenTier"
                  max_file_size_mb:
                    type: integer
                    example: 5
                  rate_limit:
                    type: object
                    properties:
                      requests_per_minute:
                        type: integer
                        example: 60
                      note:
                        type: string
                        example: Check X-RateLimit-Limit and X-RateLimit-Remaining headers on every response.

  /tokens:
    get:
      summary: List API keys
      description: Returns all API keys for the authenticated user.
      operationId: listTokens
      responses:
        "200":
          description: List of API keys
          headers:
            X-RateLimit-Limit:
              $ref: "#/components/headers/X-RateLimit-Limit"
            X-RateLimit-Remaining:
              $ref: "#/components/headers/X-RateLimit-Remaining"
          content:
            application/json:
              schema:
                type: object
                properties:
                  tokens:
                    type: array
                    items:
                      $ref: "#/components/schemas/ApiToken"
