openapi: 3.0.3
info:
  title: ScreenshotAPI
  version: 1.0.0
  description: >
    ScreenshotAPI captures web pages and raw HTML as PNG, JPEG, WebP, or PDF
    output. It supports full-page capture, custom viewports, dark/light mode,
    wait strategies, ad blocking, cookie banner removal, popup cleanup,
    response caching, HTML rendering, CSS/JavaScript injection, stealth mode,
    Retina/HiDPI capture, timezone and locale emulation, and device mockup
    frames.
  contact:
    name: ScreenshotAPI Support
    email: support@screenshotapi.to
    url: https://screenshotapi.to/docs
  termsOfService: https://screenshotapi.to/terms
  license:
    name: Proprietary
    url: https://screenshotapi.to/terms
servers:
  - url: https://screenshotapi.to
    description: Production
tags:
  - name: Screenshots
    description: Capture URLs or raw HTML as images or PDF files.
  - name: Pricing
    description: Public plan and credit-pack metadata.
paths:
  /api/health:
    get:
      summary: Health check
      operationId: getHealth
      tags:
        - Pricing
      security: []
      responses:
        "200":
          description: Service health status.
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                  - timestamp
                properties:
                  status:
                    type: string
                    example: ok
                  timestamp:
                    type: string
                    format: date-time
  /api/v1/screenshot:
    get:
      summary: Capture a web page screenshot
      operationId: getScreenshot
      tags:
        - Screenshots
      description: >
        Captures the requested URL and returns binary image or PDF data
        directly in the response body. Use POST for raw HTML rendering.
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/Url"
        - $ref: "#/components/parameters/WidthQuery"
        - $ref: "#/components/parameters/HeightQuery"
        - $ref: "#/components/parameters/FullPageQuery"
        - $ref: "#/components/parameters/TypeQuery"
        - $ref: "#/components/parameters/QualityQuery"
        - $ref: "#/components/parameters/ColorSchemeQuery"
        - $ref: "#/components/parameters/WaitUntilQuery"
        - $ref: "#/components/parameters/WaitForSelectorQuery"
        - $ref: "#/components/parameters/DelayQuery"
        - $ref: "#/components/parameters/BlockAdsQuery"
        - $ref: "#/components/parameters/RemoveCookieBannersQuery"
        - $ref: "#/components/parameters/CssInjectQuery"
        - $ref: "#/components/parameters/JsInjectQuery"
        - $ref: "#/components/parameters/StealthModeQuery"
        - $ref: "#/components/parameters/DevicePixelRatioQuery"
        - $ref: "#/components/parameters/TimezoneQuery"
        - $ref: "#/components/parameters/LocaleQuery"
        - $ref: "#/components/parameters/CacheTtlQuery"
        - $ref: "#/components/parameters/PreloadFontsQuery"
        - $ref: "#/components/parameters/RemoveElementsQuery"
        - $ref: "#/components/parameters/RemovePopupsQuery"
        - $ref: "#/components/parameters/MockupDeviceQuery"
        - $ref: "#/components/parameters/GeoLatitudeQuery"
        - $ref: "#/components/parameters/GeoLongitudeQuery"
        - $ref: "#/components/parameters/GeoAccuracyQuery"
      responses:
        "200":
          $ref: "#/components/responses/ScreenshotResponse"
        "400":
          $ref: "#/components/responses/InvalidOptions"
        "401":
          $ref: "#/components/responses/ApiKeyRequired"
        "402":
          $ref: "#/components/responses/InsufficientQuota"
        "403":
          $ref: "#/components/responses/InvalidApiKey"
        "500":
          $ref: "#/components/responses/ScreenshotFailed"
    post:
      summary: Capture a URL or raw HTML screenshot
      operationId: postScreenshot
      tags:
        - Screenshots
      description: >
        Captures a URL or renders raw HTML and returns binary image or PDF data
        directly in the response body. Provide either url or html in the JSON
        body.
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScreenshotRequest"
            examples:
              urlCapture:
                summary: URL capture
                value:
                  url: https://example.com
                  width: 1440
                  height: 900
                  type: webp
                  fullPage: true
                  blockAds: true
                  removeCookieBanners: true
              htmlCapture:
                summary: Raw HTML capture
                value:
                  html: "<main><h1>Hello from ScreenshotAPI</h1></main>"
                  width: 1200
                  height: 630
                  type: png
      responses:
        "200":
          $ref: "#/components/responses/ScreenshotResponse"
        "400":
          $ref: "#/components/responses/InvalidOptions"
        "401":
          $ref: "#/components/responses/ApiKeyRequired"
        "402":
          $ref: "#/components/responses/InsufficientQuota"
        "403":
          $ref: "#/components/responses/InvalidApiKey"
        "500":
          $ref: "#/components/responses/ScreenshotFailed"
  /api/v1/subscription/plans:
    get:
      summary: List subscription plans
      operationId: getSubscriptionPlans
      tags:
        - Pricing
      security: []
      description: Returns public subscription plan metadata.
      responses:
        "200":
          description: Subscription plans.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/SubscriptionPlan"
  /api/v1/credits/packs:
    get:
      summary: List credit packs
      operationId: getCreditPacks
      tags:
        - Pricing
      security: []
      description: Returns public credit-pack metadata.
      responses:
        "200":
          description: Credit packs.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CreditPack"
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: ScreenshotAPI key, for example sk_live_your_key_here.
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: "ScreenshotAPI key sent as Authorization: Bearer <key>."
  parameters:
    Url:
      name: url
      in: query
      required: true
      schema:
        type: string
        format: uri
      example: https://example.com
      description: Fully qualified http or https URL to capture.
    WidthQuery:
      name: width
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 1920
        default: 1440
      description: Viewport width in pixels.
    HeightQuery:
      name: height
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 10000
        default: 900
      description: Viewport height in pixels.
    FullPageQuery:
      name: fullPage
      in: query
      required: false
      schema:
        type: string
        enum:
          - "true"
          - "false"
        default: "false"
      description: Set to true to capture the full scrollable page.
    TypeQuery:
      name: type
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/OutputType"
      description: Output format.
    QualityQuery:
      name: quality
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 100
      description: JPEG/WebP quality from 1 to 100.
    ColorSchemeQuery:
      name: colorScheme
      in: query
      required: false
      schema:
        type: string
        enum:
          - light
          - dark
      description: Force prefers-color-scheme.
    WaitUntilQuery:
      name: waitUntil
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/WaitUntil"
      description: Page load event to wait for before capture.
    WaitForSelectorQuery:
      name: waitForSelector
      in: query
      required: false
      schema:
        type: string
        maxLength: 500
      description: CSS selector to wait for before capture.
    DelayQuery:
      name: delay
      in: query
      required: false
      schema:
        type: integer
        minimum: 0
        maximum: 30000
        default: 0
      description: Extra delay in milliseconds before capture.
    BlockAdsQuery:
      name: blockAds
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/BooleanString"
      description: Remove ads before capture.
    RemoveCookieBannersQuery:
      name: removeCookieBanners
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/BooleanString"
      description: Auto-remove cookie consent dialogs.
    CssInjectQuery:
      name: cssInject
      in: query
      required: false
      schema:
        type: string
        maxLength: 10000
      description: CSS to inject before capture.
    JsInjectQuery:
      name: jsInject
      in: query
      required: false
      schema:
        type: string
        maxLength: 10000
      description: JavaScript to inject before capture.
    StealthModeQuery:
      name: stealthMode
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/BooleanString"
      description: Enable anti-bot-detection mode.
    DevicePixelRatioQuery:
      name: devicePixelRatio
      in: query
      required: false
      schema:
        type: integer
        enum:
          - 1
          - 2
          - 3
        default: 1
      description: Device pixel ratio for Retina/HiDPI capture.
    TimezoneQuery:
      name: timezone
      in: query
      required: false
      schema:
        type: string
      example: America/New_York
      description: IANA timezone to emulate.
    LocaleQuery:
      name: locale
      in: query
      required: false
      schema:
        type: string
      example: en-US
      description: BCP 47 locale and Accept-Language value to emulate.
    CacheTtlQuery:
      name: cacheTtl
      in: query
      required: false
      schema:
        type: integer
        minimum: 0
        maximum: 604800
        default: 0
      description: Cache TTL in seconds. Max 7 days.
    PreloadFontsQuery:
      name: preloadFonts
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/BooleanString"
      description: Preload discovered Google Fonts before capture.
    RemoveElementsQuery:
      name: removeElements
      in: query
      required: false
      schema:
        type: string
      example: ".popup,#banner,.newsletter"
      description: Comma-separated CSS selectors to remove before capture.
    RemovePopupsQuery:
      name: removePopups
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/BooleanString"
      description: Automatically remove common popups and overlays.
    MockupDeviceQuery:
      name: mockupDevice
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/MockupDevice"
      description: Wrap the screenshot in a device frame. Output is PNG.
    GeoLatitudeQuery:
      name: geoLatitude
      in: query
      required: false
      schema:
        type: number
        minimum: -90
        maximum: 90
      description: Browser geolocation latitude. Use with geoLongitude.
    GeoLongitudeQuery:
      name: geoLongitude
      in: query
      required: false
      schema:
        type: number
        minimum: -180
        maximum: 180
      description: Browser geolocation longitude. Use with geoLatitude.
    GeoAccuracyQuery:
      name: geoAccuracy
      in: query
      required: false
      schema:
        type: number
        minimum: 0
        maximum: 100000
        default: 100
      description: Browser geolocation accuracy in meters.
  responses:
    ScreenshotResponse:
      description: Binary image or PDF response.
      headers:
        x-credits-remaining:
          description: Remaining plan quota plus credit balance.
          schema:
            type: string
        x-screenshot-id:
          description: Screenshot identifier useful for support.
          schema:
            type: string
        x-duration-ms:
          description: Capture duration in milliseconds.
          schema:
            type: string
        x-cache:
          description: Cache status.
          schema:
            type: string
            enum:
              - HIT
              - MISS
        x-usage-source:
          description: Usage source when returned.
          schema:
            type: string
            enum:
              - subscription
              - credits
              - overage
              - cache
      content:
        image/png:
          schema:
            type: string
            format: binary
        image/jpeg:
          schema:
            type: string
            format: binary
        image/webp:
          schema:
            type: string
            format: binary
        application/pdf:
          schema:
            type: string
            format: binary
    InvalidOptions:
      description: Invalid screenshot parameters.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            error: Invalid screenshot options
            message: type must be one of png, jpeg, webp, or pdf.
    ApiKeyRequired:
      description: API key was not provided.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            error: "API key required. Pass via x-api-key header or Authorization: Bearer <key>"
    InsufficientQuota:
      description: Account does not have remaining monthly quota or credits.
      content:
        application/json:
          schema:
            allOf:
              - $ref: "#/components/schemas/ErrorResponse"
              - type: object
                properties:
                  remainingInPlan:
                    type: integer
                    example: 0
                  creditBalance:
                    type: integer
                    example: 0
          example:
            error: Insufficient quota
            message: Purchase more credits or upgrade your plan.
            remainingInPlan: 0
            creditBalance: 0
    InvalidApiKey:
      description: API key is invalid or revoked.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            error: Invalid or revoked API key
    ScreenshotFailed:
      description: Screenshot capture failed after validation.
      content:
        application/json:
          schema:
            allOf:
              - $ref: "#/components/schemas/ErrorResponse"
              - type: object
                properties:
                  fix:
                    type: string
          example:
            error: Screenshot failed
            message: Navigation timeout.
            fix: Check that the URL is accessible and try again.
  schemas:
    BooleanString:
      type: string
      enum:
        - "true"
        - "false"
    OutputType:
      type: string
      enum:
        - png
        - jpeg
        - webp
        - pdf
      default: png
    WaitUntil:
      type: string
      enum:
        - load
        - domcontentloaded
        - networkidle0
        - networkidle2
      default: networkidle2
    MockupDevice:
      type: string
      enum:
        - browser
        - iphone
        - macbook
    GeoLocation:
      type: object
      required:
        - latitude
        - longitude
      properties:
        latitude:
          type: number
          minimum: -90
          maximum: 90
        longitude:
          type: number
          minimum: -180
          maximum: 180
        accuracy:
          type: number
          minimum: 0
          maximum: 100000
          default: 100
    ScreenshotRequest:
      type: object
      description: Provide either url or html. Raw HTML rendering requires POST.
      properties:
        url:
          type: string
          format: uri
          description: Fully qualified http or https URL to capture.
        html:
          type: string
          description: Raw HTML to render instead of navigating to a URL.
        width:
          type: integer
          minimum: 1
          maximum: 1920
          default: 1440
        height:
          type: integer
          minimum: 1
          maximum: 10000
          default: 900
        fullPage:
          type: boolean
          default: false
        type:
          $ref: "#/components/schemas/OutputType"
        quality:
          type: integer
          minimum: 1
          maximum: 100
          default: 100
        colorScheme:
          type: string
          enum:
            - light
            - dark
        waitUntil:
          $ref: "#/components/schemas/WaitUntil"
        waitForSelector:
          type: string
          maxLength: 500
        delay:
          type: integer
          minimum: 0
          maximum: 30000
          default: 0
        blockAds:
          type: boolean
          default: false
        removeCookieBanners:
          type: boolean
          default: false
        cssInject:
          type: string
          maxLength: 10000
        jsInject:
          type: string
          maxLength: 10000
        stealthMode:
          type: boolean
          default: false
        devicePixelRatio:
          type: integer
          enum:
            - 1
            - 2
            - 3
          default: 1
        timezone:
          type: string
          example: America/New_York
        locale:
          type: string
          example: en-US
        cacheTtl:
          type: integer
          minimum: 0
          maximum: 604800
          default: 0
        preloadFonts:
          type: boolean
          default: false
        removeElements:
          type: array
          maxItems: 25
          items:
            type: string
            maxLength: 500
        removePopups:
          type: boolean
          default: false
        mockupDevice:
          $ref: "#/components/schemas/MockupDevice"
        geoLocation:
          $ref: "#/components/schemas/GeoLocation"
    SubscriptionPlan:
      type: object
      required:
        - id
        - name
        - screenshotsPerMonth
        - monthlyPriceCents
        - annualPriceCents
        - perScreenshot
        - overageRateCents
        - features
      properties:
        id:
          type: string
          enum:
            - free
            - starter
            - growth
            - scale
        name:
          type: string
        screenshotsPerMonth:
          type: integer
        monthlyPriceCents:
          type: integer
        annualPriceCents:
          type: integer
          description: Monthly equivalent when billed annually.
        perScreenshot:
          type: number
          nullable: true
        overageRateCents:
          type: number
        features:
          type: array
          items:
            type: string
    CreditPack:
      type: object
      required:
        - id
        - name
        - credits
        - priceCents
        - isPopular
      properties:
        id:
          type: string
        name:
          type: string
        credits:
          type: integer
        priceCents:
          type: integer
        isPopular:
          type: boolean
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
        message:
          type: string
