openapi: 3.1.0
info:
  title: ScreenshotCenter API
  description: Take screenshots of any website in real time at scale
  version: "1.1.0"
  contact: 
    name: API Support
    email: "support@screenshotcenter.com"
    url: https://screenshotcenter.com/contact
  termsOfService: https://screenshotcenter.com/legal/terms-of-service/
  license:
    name: Proprietary

servers:
  - url: https://api.screenshotcenter.com/api/v1
    description: Production API

x-ui-docs:
  option_groups:
    default_order:
      - App
      - Output & Format
      - Automation
      - Content Blocking
      - Geolocation
      - Device
      - Screenshot
      - PDF Options
      - Video Options
      - Capture Controls
    by_parameter_name:
      cache: Capture Controls
      country: Geolocation
      dark: App
      delay: Automation
      device_landscape: Device
      device_mobile: Device
      device_name: Device
      device_scale: Device
      device_touch: Device
      format: Output & Format
      geo_enable: Geolocation
      geo_latitude: Geolocation
      geo_longitude: Geolocation
      header: App
      height: Output & Format
      hide_ads: Content Blocking
      hide_popups: Content Blocking
      html: Output & Format
      language: Geolocation

      max_wait: Automation
      pdf: PDF Options
      pdf_background: PDF Options
      pdf_format: PDF Options
      pdf_landscape: PDF Options
      pdf_margin: PDF Options
      pdf_margin_bottom: PDF Options
      pdf_margin_left: PDF Options
      pdf_margin_right: PDF Options
      pdf_margin_top: PDF Options
      pdf_one_page: PDF Options
      post_data: App
      referer: App
      screen_height: Device
      screen_width: Device
      script: Automation
      script_inline: Automation
      shot_interval: Capture Controls
      shots: Capture Controls
      size: Device
      step: Automation
      steps: Automation
      strict_ssl: Capture Controls
      tag: Screenshot
      target: Screenshot
      thumbnail: Output & Format
      timezone: Geolocation
      tracker: Automation
      trackers: Automation
      url: App
      user_agent: App
      video: Video Options
      video_colors: Video Options
      video_duration: Video Options
      video_format: Video Options
      video_fps: Video Options
      video_quality: Video Options
      video_scale: Video Options
      video_speed: Video Options
      width: Output & Format
    endpoint_overrides:
      GET /screenshot/create:
        - name: Essential
          options: [url, size, screen_width, screen_height, browser, country, delay, hide_ads, hide_popups]
        - name: Request
          options: [cookie, header, post_data, referer, user_agent]
        - name: Page
          options: [max_wait, script, script_inline, tracker, trackers]
        - name: Browser
          options: [dark, strict_ssl]
        - name: Automation
          options: [steps, step]
        - name: Screenshot
          options: [target, tag, cache, shots, shot_interval]
        - name: PDF Options
          options: [pdf, pdf_background, pdf_format, pdf_landscape, pdf_margin, pdf_margin_bottom, pdf_margin_left, pdf_margin_right, pdf_margin_top, pdf_one_page]
        - name: Video Options
          options: [video, video_format, video_quality, video_speed, video_duration, video_fps, video_colors, video_scale]
      POST /batch/create:
        - name: Essential
          options: [url, size, screen_width, screen_height, browser, country, delay, hide_ads, hide_popups]
        - name: Request
          options: [cookie, header, post_data, referer, user_agent]
        - name: Page
          options: [max_wait, script, script_inline, tracker, trackers]
        - name: Browser
          options: [dark, strict_ssl]
        - name: Automation
          options: [steps, step]
        - name: Screenshot
          options: [target, tag, cache, shots, shot_interval]

components:
  securitySchemes:
    apiKeyQuery:
      type: apiKey
      name: key
      in: query
      description: API key passed as query parameter (alternative to JWT bearer token)
    apiKeyHeader:
      type: apiKey
      name: X-API-KEY
      in: header
      description: API key passed as request header (alternative to JWT bearer token)
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token for dashboard authentication

  parameters:
    ApiKeyQuery:
      name: key
      in: query
      required: false
      schema:
        type: string
      description: API key (optional if using JWT bearer token)
    ApiKeyHeader:
      name: X-API-KEY
      in: header
      required: false
      schema:
        type: string
      description: API key (optional if using JWT bearer token)

  schemas:
    # Error Schemas
    Error:
      type: object
      required:
        - success
      properties:
        success:
          type: boolean
          description: Indicates the request failed
          enum:
            - false
          example: false
        error:
          type: string
          description: Human-readable error description
          example: "Invalid API key"
        code:
          type: string
          description: Machine-readable error code
          example: INVALID_API_KEY
        details:
          type: object
          description: Additional error context
          additionalProperties: true
      example:
        success: false
        error: "Invalid API key"
        code: "INVALID_API_KEY"
        details:
          request_id: "req_123456"
    SuccessResponse:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          enum:
            - true
          example: true
        data:
          description: Response payload
          type: [object, 'null']
      example:
        success: true
        data: {}

    ValidationError:
      type: object
      required:
        - error
        - code
        - fields
      properties:
        error:
          type: string
          description: Validation error message
          example: "Request validation failed"
        code:
          type: string
          enum:
            - VALIDATION_ERROR
          example: VALIDATION_ERROR
        fields:
          type: object
          description: Field-level validation errors
          additionalProperties:
            type: array
            items:
              type: string
          example:
            url: ["URL is required"]
            country: ["Country code must be ISO 3166-1 alpha-2"]
      example:
        error: "Request validation failed"
        code: "VALIDATION_ERROR"
        fields:
          url: ["URL is required"]
          country: ["Country code must be ISO 3166-1 alpha-2"]

    RateLimitError:
      type: object
      required:
        - error
        - code
        - retry_after
      properties:
        error:
          type: string
          example: "Rate limit exceeded"
        code:
          type: string
          enum:
            - RATE_LIMIT_EXCEEDED
        retry_after:
          type: integer
          description: Seconds to wait before retry
          example: 60
      example:
        error: "Rate limit exceeded"
        code: "RATE_LIMIT_EXCEEDED"
        retry_after: 60

    # Screenshot Schemas
    Screenshot:
      type: object
      required:
        - id
        - status
        - url
        - final_url
        - error
        - cost
        - tag
        - created_at
        - finished_at
        - country
        - region
        - language
        - timezone
        - geo_enable
        - geo_latitude
        - geo_longitude
        - size
        - cache
        - delay
        - screen_width
        - screen_height
        - priority
        - referer
        - post_data
        - cookie
        - script
        - html
        - pdf
        - pdf_background
        - pdf_one_page
        - pdf_landscape
        - pdf_format
        - pdf_margin
        - pdf_margin_top
        - pdf_margin_bottom
        - pdf_margin_left
        - pdf_margin_right
        - video
        - video_format
        - video_quality
        - video_speed
        - video_duration
        - max_wait
        - header
        - hide_popups
        - hide_ads
        - dark
        - shots
        - shot_interval
        - strict_ssl
        - target
        - device_name
        - device_scale
        - device_touch
        - device_landscape
      properties:
        id:
          type: integer
          format: int64
          description: Unique screenshot identifier
          example: 12345678
        status:
          type: string
          description: Current screenshot processing status
          enum:
            - processing
            - finished
            - error
          example: finished
        error:
          type: string
          description: Error message if status is 'error' (omitted otherwise)
          example: "Request timeout after 30 seconds"
        url:
          type: string
          format: uri
          description: Original URL requested
          example: "https://example.com"
        country:
          type: string
          description: Country code used for the request
          example: "us"
        final_url:
          type: string
          description: Final URL after redirects (empty string if not available)
          example: "https://www.example.com"
        final_urls:
          type: array
          description: Final URL for each shot (1-based, order of screenshots)
          items:
            type: string
        response_code:
          type: integer
          nullable: true
          description: HTTP response code returned by the final URL (e.g. 200, 404, 301). Null if the page could not be reached.
          example: 200
        apps:
          type: array
          description: Latest status for each configured app
          items:
            $ref: '#/components/schemas/AppStatus'
        cost:
          type: integer
          description: Cost in credits for this screenshot
          example: 1
        size:
          type: string
          description: Screenshot size mode
          enum:
            - screen
            - page
          example: screen
        cache:
          type: integer
          description: Cache duration in seconds
          example: 86400
        delay:
          type: integer
          minimum: 0
          maximum: 60
          description: Seconds waited after page load
          example: 5
        screen_width:
          type: integer
          minimum: 1
          description: Viewport width in pixels
          example: 1024
        screen_height:
          type: integer
          minimum: 1
          description: Viewport height in pixels
          example: 1280
        priority:
          type: integer
          description: Queue priority
          example: 2
        referer:
          type: string
          description: Custom referrer header used
        post_data:
          type: string
          description: POST data sent
        cookie:
          type: string
          description: Custom cookies set
        script:
          type: string
          description: Custom JavaScript URL executed
        header:
          type: string
          description: Custom HTTP header(s)
        html:
          type: boolean
          description: Whether HTML capture was requested
        pdf:
          type: boolean
          description: Whether PDF capture was requested
        pdf_background:
          type: boolean
          description: Include background graphics in PDF output
        pdf_one_page:
          type: boolean
          description: Fit rendered page on a single PDF page
        pdf_landscape:
          type: boolean
          description: Render PDF in landscape mode
        pdf_format:
          type: string
          enum:
            - a4
            - letter
            - legal
          description: PDF paper format
        pdf_margin:
          type: string
          description: 'Default PDF margin — any CSS unit: px, mm, in, cm. Example: 20px, 10mm'
          example: '20px'
        pdf_margin_top:
          type: string
          description: 'Top margin — any CSS unit: px, mm, in, cm.'
          example: '20px'
        pdf_margin_bottom:
          type: string
          description: Bottom margin — any CSS unit.
          example: '20px'
        pdf_margin_left:
          type: string
          description: Left margin — any CSS unit.
          example: '20px'
        pdf_margin_right:
          type: string
          description: Right margin — any CSS unit.
          example: '20px'
        video:
          type: boolean
          description: Whether screencast capture was requested
        video_format:
          type: string
          enum:
            - mp4
            - webm
            - gif
          description: Screencast output format
        video_quality:
          type: integer
          minimum: 0
          maximum: 63
          description: Screencast quality (lower is better quality, CRF style)
        video_speed:
          type: number
          minimum: 0.1
          maximum: 5
          description: Screencast playback speed multiplier
        video_duration:
          type: integer
          minimum: 0
          maximum: 30
          description: Screencast recording duration in seconds (0 = no minimum recording time)
        video_fps:
          type: integer
          minimum: 1
          maximum: 60
          description: Screencast frame rate (frames per second)
        video_colors:
          type: integer
          minimum: 2
          maximum: 256
          description: Number of palette colors for GIF output
        video_scale:
          type: number
          minimum: 0.1
          maximum: 1
          description: Scale factor applied to the output video dimensions
        max_wait:
          type: integer
          description: Max wait time in seconds for elements
        hide_popups:
          type: boolean
          description: Whether popup blocking was enabled
        hide_ads:
          type: boolean
          description: Whether ad blocking was enabled
        dark:
          type: boolean
          description: Whether dark mode emulation was enabled
        shots:
          type: integer
          minimum: 1
          maximum: 10
          default: 1
          description: Number of screenshots requested
        shot_interval:
          type: integer
          description: Delay between shots in seconds
        strict_ssl:
          type: boolean
          description: Whether strict SSL validation was enabled
        target:
          type: string
          description: CSS selector for element screenshot
        geo_enable:
          type: boolean
          description: Whether geolocation emulation was enabled
        geo_latitude:
          type: number
          format: float
          description: Geolocation latitude
        geo_longitude:
          type: number
          format: float
          description: Geolocation longitude
        region:
          type: string
          description: Resolved region for the job
        language:
          type: string
          description: Resolved language/locale
        timezone:
          type: string
          description: Resolved timezone
        device_name:
          type: string
          description: Device name used for emulation
        device_scale:
          type: number
          description: Emulated device scale factor
        device_mobile:
          type: boolean
          description: Whether mobile emulation was enabled
        device_touch:
          type: boolean
          description: Whether touch input was enabled
        device_landscape:
          type: boolean
          description: Whether landscape mode was enabled
        browser:
          type: string
          enum:
            - chrome
            - firefox
            - brave
          description: Browser used for this screenshot
        user_agent:
          type: string
          description: User-Agent header used for HTTP requests
        created_at:
          type: string
          format: date-time
          description: Screenshot creation timestamp
          example: "2026-02-01T10:30:00Z"
        finished_at:
          type: string
          description: Screenshot completion timestamp (empty string if not finished)
          example: "2026-02-01T10:30:05Z"
        tag:
          type: array
          items:
            type: string
          description: Tags associated with the screenshot
        steps:
          type: array
          description: Automation steps (omitted if empty)
          items:
            type: object
        trackers:
          type: array
          description: Array of captured tracker metrics with collected values per shot
          items:
            type: object
            properties:
              id:
                type: string
                description: Tracker identifier
              name:
                type: string
                description: Tracker metric name
              value:
                description: Captured metric value
              input:
                type: string
                description: Associated input
              selector:
                type: string
                description: CSS selector used
              name_type:
                type: string
                description: Tracker name type
              value_type:
                type: string
                description: Tracker value type
              return:
                type: array
                description: Values collected per shot
                items:
                  type: object
                  properties:
                    found:
                      type: integer
                      description: 1 if the tracker matched, 0 if not found
                      example: 1
                    shot:
                      type: integer
                      description: Shot index (1-based)
                      example: 1
                    value:
                      type: string
                      description: Captured value (if found)
                      example: "My Page Title"
                    name:
                      type: string
                      description: Tracker name
                      example: "page title"
          example:
            - id: "test"
              name: "page title"
              value: "document.title"
              name_type: "string"
              input: ""
              value_type: "string"
              selector: ""
              return:
                - found: 1
                  shot: 1
                  value: "My Page Title"
                  name: "page title"
        links:
          type: array
          description: Absolute URLs of links found on the rendered page. Extracted from the live DOM after JavaScript execution, so it includes dynamically generated links.
          items:
            type: string
            format: uri
          example:
            - "https://example.com/about"
            - "https://example.com/contact"
            - "https://example.com/blog"

    ScreenshotList:
      allOf:
        - $ref: '#/components/schemas/Screenshot'

    ScreenshotShort:
      type: object
      required:
        - id
        - status
      properties:
        id:
          type: integer
          format: int64
          example: 12345678
        status:
          type: string
          enum:
            - ok
            - error
          example: ok


    # Batch Schemas
    Batch:
      type: object
      required:
        - id
        - status
      properties:
        id:
          type: integer
          format: int64
          description: Batch identifier
          example: 98765
        status:
          type: string
          description: Batch processing status
          enum:
            - processing
            - finished
            - error
          example: finished
        error:
          type: string
          description: Error message if status is 'error'
          example: "Canceled by user"
        started:
          type: integer
          format: int64
          description: Processing start time (Unix timestamp)
          example: 1706778600
        finished:
          type: integer
          format: int64
          description: Batch completion time (Unix timestamp)
          example: 1706778900
        count:
          type: integer
          minimum: 0
          description: Total unique URLs in batch
          example: 100
        processed:
          type: integer
          minimum: 0
          description: Successfully processed screenshots
          example: 98
        failed:
          type: integer
          minimum: 0
          description: Failed screenshot attempts
          example: 2
        zip_url:
          type: string
          format: uri
          description: Download URL for the batch ZIP archive
          example: "https://screenshotcenter.com/api/v1/batch/download?id=98765"

    Crawl:
      type: object
      required:
        - id
        - status
        - domain
        - start_url
        - max_urls
      properties:
        id:
          type: integer
          format: int64
          description: Crawl identifier
          example: 12345
        status:
          type: string
          description: Crawl processing status
          enum:
            - processing
            - finished
            - cancelled
            - error
          example: finished
        domain:
          type: string
          description: Domain being crawled
          example: "example.com"
        start_url:
          type: string
          format: uri
          description: Starting URL for the crawl
          example: "https://example.com"
        max_urls:
          type: integer
          minimum: 1
          maximum: 1000
          description: Maximum number of pages to screenshot
          example: 100
        total_discovered:
          type: integer
          minimum: 0
          description: Total URLs discovered during crawl
          example: 87
        processed:
          type: integer
          minimum: 0
          description: Successfully processed screenshots
          example: 85
        failed:
          type: integer
          minimum: 0
          description: Failed screenshot attempts
          example: 2
        error:
          type: string
          description: Error message if status is 'error'
        created_at:
          type: string
          format: date-time
          description: Crawl creation time
        started:
          type: integer
          format: int64
          description: Processing start time (Unix timestamp)
        finished:
          type: integer
          format: int64
          description: Crawl completion time (Unix timestamp)
        screenshots:
          type: array
          description: Screenshots taken during the crawl (only in crawl/info)
          items:
            $ref: '#/components/schemas/Screenshot'

    Account:
      type: object
      required:
        - balance
      properties:
        balance:
          type: integer
          minimum: 0
          description: Available credits
          example: 1000

    UserSession:
      type: object
      required:
        - id
        - email
        - email_verified
        - roles
        - company
      properties:
        id:
          type: integer
          example: 12
        email:
          type: string
          format: email
          example: "user@example.com"
        email_verified:
          type: boolean
          description: Whether the user's email has been verified
          example: true
        signup_provider:
          type: string
          description: Provider used to create the account
          example: "GOOGLE"
        name:
          type: [string, 'null']
          example: "Jane Doe"
        roles:
          type: array
          items:
            type: string
          example: ["READ", "WRITE"]
        company:
          type: object
          required:
            - id
            - name
            - email
            - balance
          properties:
            id:
              type: integer
              example: 4
            name:
              type: string
              example: "Acme Corp"
            email:
              type: string
              format: email
              example: "billing@acme.com"
            balance:
              type: integer
              example: 1200

    AuthLoginResponse:
      type: object
      required:
        - token
        - user
      properties:
        token:
          type: string
          description: JWT token for dashboard access
          example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
        user:
          $ref: "#/components/schemas/UserSession"

    AuthSignupResponse:
      type: object
      required:
        - token
        - user
        - api_key
      properties:
        token:
          type: string
          description: JWT token for dashboard access
        user:
          $ref: "#/components/schemas/UserSession"
        api_key:
          type: object
          required:
            - key
          properties:
            key:
              type: string
              example: "api_key_123"
            name:
              type: [string, 'null']
              example: "Default API Key"

    AuthImpersonateResponse:
      type: object
      required:
        - token
        - user
        - impersonated_by
      properties:
        token:
          type: string
        user:
          $ref: "#/components/schemas/UserSession"
        impersonated_by:
          type: [integer, 'null']

    ForgotPasswordRequest:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          format: email
          example: "user@example.com"
        turnstile_token:
          type: string
          description: Turnstile token (required in production)

    ResetPasswordRequest:
      type: object
      required:
        - token
        - password
      properties:
        token:
          type: string
          example: "reset_token"
        password:
          type: string
          example: "NewPassword123!"
        turnstile_token:
          type: string
          description: Turnstile token (required in production)

    VerifyEmailRequest:
      type: object
      required:
        - token
      properties:
        token:
          type: string
          example: "verify_token"

    OkResponse:
      type: object
      required:
        - ok
      properties:
        ok:
          type: boolean
          example: true

    DashboardOverview:
      type: object
      required:
        - account
        - billing
        - usage
        - batches
        - recent_screenshots
      properties:
        account:
          type: object
          required:
            - company_id
            - company_name
            - balance
          properties:
            company_id:
              type: integer
            company_name:
              type: string
            balance:
              type: integer
        billing:
          type: [object, 'null']
          properties:
            plan:
              type: object
              required:
                - id
                - name
                - price_usd
                - monthly_screenshots
                - features
                - public
              properties:
                id:
                  type: string
                name:
                  type: string
                price_usd:
                  type: number
                monthly_screenshots:
                  type: integer
                features:
                  type: array
                  items:
                    type: string
                public:
                  type: boolean
            usage:
              type: object
              required:
                - screenshots_this_month
                - monthly_limit
                - remaining
              properties:
                screenshots_this_month:
                  type: integer
                monthly_limit:
                  type: integer
                remaining:
                  type: integer
        usage:
          type: object
          required:
            - total_screenshots
            - screenshots_this_month
            - processing
            - finished
            - error
          properties:
            total_screenshots:
              type: integer
            screenshots_this_month:
              type: integer
            processing:
              type: integer
            finished:
              type: integer
            error:
              type: integer
        batches:
          type: object
          required:
            - total
            - processing
            - finished
            - error
          properties:
            total:
              type: integer
            processing:
              type: integer
            finished:
              type: integer
            error:
              type: integer
        recent_screenshots:
          type: array
          items:
            type: object
            required:
              - id
              - url
              - status
              - cost
              - created_at
            properties:
              id:
                type: integer
              url:
                type: string
              status:
                type: string
              cost:
                type: integer
              error:
                type: [string, 'null']
              created_at:
                type: string
                format: date-time
              finished_at:
                type: [string, 'null']
                format: date-time

    AdminOverview:
      type: object
      required:
        - totals
        - screenshots
        - top_users
      properties:
        totals:
          type: object
          required:
            - users
            - companies
            - screenshots
            - batches
            - active_clients
          properties:
            users:
              type: integer
            companies:
              type: integer
            screenshots:
              type: integer
            batches:
              type: integer
            active_clients:
              type: integer
        screenshots:
          type: object
          required:
            - last_24h
            - failed_24h
          properties:
            last_24h:
              type: integer
            failed_24h:
              type: integer
        top_users:
          type: array
          items:
            type: object
            required:
              - user_id
              - email
              - company_name
              - screenshots
            properties:
              user_id:
                type: integer
              email:
                type: string
              company_name:
                type: string
              screenshots:
                type: integer

    PlanDefinition:
      type: object
      required:
        - id
        - name
        - price_usd
        - monthly_screenshots
        - features
        - public
      properties:
        id:
          type: string
        name:
          type: string
        price_usd:
          type: number
        monthly_screenshots:
          type: integer
        features:
          type: array
          items:
            type: string
        public:
          type: boolean
        braintree_plan_ids:
          type: object
          properties:
            monthly:
              type: string
            yearly:
              type: string
        addons:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              quantity:
                type: integer
              braintree_addon_ids:
                type: object
                properties:
                  monthly:
                    type: string
                  yearly:
                    type: string

    BillingSubscriptionResponse:
      type: object
      required:
        - subscriptionId
        - status
        - planId
      properties:
        subscriptionId:
          type: string
        status:
          type: string
        planId:
          type: string

    BillingPaymentMethod:
      type: object
      required:
        - token
        - type
      properties:
        token:
          type: string
        type:
          type: string
          enum: [card, paypal]
        brand:
          type: string
        last4:
          type: string
        expirationMonth:
          type: string
        expirationYear:
          type: string
        email:
          type: string
        default:
          type: boolean

    AppStatus:
      type: object
      description: Status and output of a post-screenshot app integration
      properties:
        id:
          type: integer
          format: int64
          description: App configuration ID
        app_id:
          type: string
          description: App ID (user-defined)
        type:
          type: string
          description: App type (e.g. gdrive, dropbox, s3, webhook, slack, onedrive, webcategorize)
        name:
          type: string
          description: App name
        status:
          type: string
          description: App processing status
          enum: [pending, queued, processing, finished, error]
        filename:
          type: string
          description: Optional per-request path or filename template override used for this app upload
        error:
          type: string
          description: Error message if the app failed (empty string otherwise)
        output_url:
          type: string
          description: Output URL if provided by the app
        output_data:
          type: object
          description: Arbitrary structured output returned by the app (shape depends on the app type)
          additionalProperties: true
          nullable: true
        updated_at:
          type: string
          format: date-time
          description: ISO timestamp of last app update

    BillingReceipt:
      type: object
      required:
        - id
        - amount
        - currency
        - status
        - createdAt
      properties:
        id:
          type: string
        amount:
          type: string
        currency:
          type: string
        status:
          type: string
        createdAt:
          type: string
        updatedAt:
          type: string

security:
  - apiKeyQuery: []
  - apiKeyHeader: []
  - bearerAuth: []
paths:
  /screenshot/create:
    get:
      summary: Request a screenshot
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/screenshot/create?key=YOUR_API_KEY&url=https://example.com"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const shot = await client.screenshot.create('https://example.com', {
              country: 'us',
            });
            console.log(shot.id, shot.status);
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            shot = client.screenshot.create("https://example.com", country="us")
            print(shot["id"], shot["status"])
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $shot = $client->screenshot->create('https://example.com', ['country' => 'us']);
            echo $shot['id'] . ' ' . $shot['status'];
        - lang: Go
          label: Go SDK
          source: |
            import (
                sc "github.com/juliensobrier/screenshotcenter-go"
                "os"
            )

            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            shot, err := client.Screenshot.Create("https://example.com", &sc.CreateParams{
                Country: "us",
            })
            if err != nil { panic(err) }
            fmt.Println(shot.ID, shot.Status)
        - lang: Java
          label: Java SDK (Maven)
          source: |
            import com.screenshotcenter.ScreenshotCenterClient;
            import org.json.JSONObject;
            import java.util.Map;

            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            JSONObject shot = client.screenshot().create(
                "https://example.com", Map.of("country", "us"));
            System.out.println(shot.getLong("id") + " " + shot.getString("status"));
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            require "screenshotcenter"

            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            shot = client.screenshot.create("https://example.com", country: "us")
            puts "#{shot['id']} #{shot['status']}"
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            using ScreenshotCenter;

            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            var shot = await client.Screenshot.CreateAsync("https://example.com",
                new Dictionary<string, string> { ["country"] = "us" });
            Console.WriteLine($"{shot.Id} {shot.Status}");
      operationId: createScreenshot
      tags:
        - Screenshot
      description: Submit a screenshot request. Screenshots require a positive account balance.
      parameters:
        # Required
        - name: url
          in: query
          required: true
          schema:
            type: string
            format: uri
            minLength: 1
            maxLength: 2048
          description: URL of the page to screenshot.
          example: "https://example.com"
        
        - name: country
          in: query
          required: false
          schema:
            type: string
            default: "us"
            pattern: '^[a-z]{2}$'
          description: ISO 3166-1 alpha-2 country code for IP geolocation. Defaults to "us" when omitted.
          example: "us"

        - name: language
          in: query
          schema:
            type: string
            pattern: '^[a-z]{2}-[A-Z]{2}$'
          description: Override language/locale for the screenshot job (e.g., en-US, fr-FR)

        - name: geo_latitude
          in: query
          schema:
            type: number
            format: float
          description: Override latitude for geolocation (decimal degrees)

        - name: geo_longitude
          in: query
          schema:
            type: number
            format: float
          description: Override longitude for geolocation (decimal degrees)

        - name: timezone
          in: query
          schema:
            type: string
          description: Override timezone for geolocation (e.g., America/New_York)

        - name: geo_enable
          in: query
          schema:
            type: boolean
            default: false
          description: Enable geolocation emulation in the browser for this request
        
        
        # Common parameters
        - name: size
          in: query
          schema:
            type: string
            enum: [screen, page]
            default: screen
          description: "Screenshot size mode: viewport ('screen') or full page ('page')"
        
        - name: cache
          in: query
          schema:
            type: integer
            minimum: 0
            default: 86400
          description: Cache duration in seconds. 0 = always fresh, 86400 = 24 hours
        
        - name: delay
          in: query
          schema:
            type: integer
            minimum: 0
            maximum: 60
            default: 5
          description: Seconds to wait after page load for JavaScript execution
        
        - name: screen_width
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 5000
            default: 1024
          description: Browser viewport width in pixels
        
        - name: screen_height
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 10000
            default: 1280
          description: Browser viewport height in pixels

        - name: apps
          in: query
          schema:
            oneOf:
              - type: array
                items:
                  type: string
              - type: object
                additionalProperties:
                  type: string
          description: |
            Apps to run after the screenshot is finished.
            You can pass a list of app IDs, for example `apps=google-drive&apps=dropbox`,
            or a deep object that maps each app ID to an optional path or filename template override,
            for example `apps[google-drive]=` or `apps[google-drive]={yyyy}/{mm}/{dd}/{domain}.png`.

        - name: device_name
          in: query
          schema:
            type: string
          description: Device name to emulate (e.g., iphone_15_pro or iphone_15_pro_landscape). If provided and found, other device_* parameters are ignored.

        - name: device_scale
          in: query
          schema:
            type: number
            minimum: 0.1
            maximum: 10
          description: Device scale factor (used with screen_width/screen_height when device_name is not set)

        - name: device_mobile
          in: query
          schema:
            type: boolean
          description: Enable mobile emulation (used with screen_width/screen_height when device_name is not set)

        - name: device_touch
          in: query
          schema:
            type: boolean
          description: Enable touch input for device emulation (used with screen_width/screen_height when device_name is not set)

        - name: device_landscape
          in: query
          schema:
            type: boolean
          description: Use landscape orientation for device emulation (used with screen_width/screen_height when device_name is not set)
        
        - name: referer
          in: query
          schema:
            type: string
            maxLength: 2048
          description: Custom HTTP Referer header
        
        - name: post_data
          in: query
          schema:
            type: string
          description: POST data for form submission (URL-encoded)
        
        - name: cookie
          in: query
          schema:
            type: string
          description: Cookies as semicolon-separated key=value pairs
        
        - name: script
          in: query
          style: form
          explode: true
          schema:
            type: array
            items:
              type: string
              format: uri
          description: URL(s) of JavaScript file(s) to execute after page load. Can specify multiple scripts that will be executed in order.
        
        - name: script_inline
          in: query
          schema:
            type: string
          description: Inline JavaScript code to execute after page load
        
        - name: html
          in: query
          schema:
            type: boolean
            default: false
          description: Save rendered HTML

        - name: pdf
          in: query
          schema:
            type: boolean
            default: false
          description: Save rendered PDF

        - name: pdf_background
          in: query
          schema:
            type: boolean
            default: false
          description: Include background graphics in PDF

        - name: pdf_one_page
          in: query
          schema:
            type: boolean
            default: false
          description: Fit rendered page on a single PDF page

        - name: pdf_landscape
          in: query
          schema:
            type: boolean
            default: false
          description: Render PDF in landscape mode

        - name: pdf_format
          in: query
          schema:
            type: string
            enum: [a4, letter, legal]
            default: letter
          description: PDF paper format

        - name: pdf_margin
          in: query
          schema:
            type: string
            example: '20px'
          description: 'Default PDF margin applied to all sides — any CSS unit: px, mm, in, cm. Overridden per-side by pdf_margin_top/right/bottom/left.'

        - name: pdf_margin_top
          in: query
          schema:
            type: string
            example: '20px'
          description: 'Top margin — any CSS unit: px, mm, in, cm.'

        - name: pdf_margin_bottom
          in: query
          schema:
            type: string
            example: '20px'
          description: Bottom margin — any CSS unit.

        - name: pdf_margin_left
          in: query
          schema:
            type: string
            example: '20px'
          description: Left margin — any CSS unit.

        - name: pdf_margin_right
          in: query
          schema:
            type: string
            example: '20px'
          description: Right margin — any CSS unit.

        - name: video
          in: query
          schema:
            type: boolean
            default: false
          description: Save a screencast video of the page loading

        - name: video_format
          in: query
          schema:
            type: string
            enum: [webm, mp4, gif]
            default: webm
          description: Screencast output format

        - name: video_quality
          in: query
          schema:
            type: integer
            minimum: 0
            maximum: 63
            default: 30
          description: Screencast quality (0-63, lower is better quality)

        - name: video_speed
          in: query
          schema:
            type: number
            minimum: 0.1
            maximum: 5
            default: 1
          description: Screencast playback speed multiplier

        - name: video_duration
          in: query
          schema:
            type: integer
            minimum: 0
            maximum: 30
            default: 15
          description: Screencast recording duration in seconds (0 = no minimum recording time)

        - name: video_fps
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 60
          description: "Screencast frame rate (frames per second). Defaults to 20 for GIF, 30 for WebM/MP4. Lower values produce smaller GIF files."

        - name: video_colors
          in: query
          schema:
            type: integer
            minimum: 2
            maximum: 256
          description: "Number of palette colors for GIF output (2-256). Fewer colors produce smaller files with some quality loss. Has no effect on WebM/MP4."

        - name: video_scale
          in: query
          schema:
            type: number
            minimum: 0.1
            maximum: 1
          description: "Scale factor applied to the output video dimensions (0.1-1.0). For example, 0.5 halves both width and height, reducing file size by ~75%."

        - name: max_wait
          in: query
          schema:
            type: integer
            minimum: 0
            maximum: 60
            default: 0
          description: Maximum seconds to wait for page load (0 = disabled)
        
        - name: header
          in: query
          style: form
          explode: true
          schema:
            type: array
            items:
              type: string
          description: Custom HTTP headers. Each item should be a JSON object string. Can specify multiple header sets.
        
        - name: hide_popups
          in: query
          schema:
            type: boolean
            default: false
          description: Hide popups and overlays

        - name: hide_ads
          in: query
          schema:
            type: boolean
            default: false
          description: Block ads using network filtering (disabled for Brave)
        
        - name: dark
          in: query
          schema:
            type: boolean
            default: false
          description: Enable dark mode rendering
        
        - name: browser
          in: query
          schema:
            type: string
            enum: [chrome, firefox, brave]
            default: chrome
          description: Browser to use for screenshot (chrome, firefox, or brave)
        
        - name: user_agent
          in: query
          schema:
            type: string
            maxLength: 2048
          description: Custom User-Agent header to use for HTTP requests
        
        - name: shots
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 10
            default: 1
          description: Number of sequential screenshots
        
        - name: shot_interval
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 10
            default: 5
          description: Seconds between sequential shots
        
        - name: strict_ssl
          in: query
          schema:
            type: boolean
            default: false
          description: Enforce strict SSL certificate validation
        
        - name: target
          in: query
          schema:
            type: string
          description: CSS selector. If provided, take a screenshot of the element. If not found within 30 seconds or max_wait, fall back to page/window screenshot.
        
        - name: steps
          in: query
          schema:
            type: array
            items:
              type: object
              properties:
                command:
                  type: string
                  enum: [type, click, navigate, screenshot, sleep, javascript, scroll, for, end]
                  description: Command to execute
                value:
                  type: string
                  description: Value for the command (e.g., text to type, URL to navigate, sleep duration)
                element:
                  type: string
                  description: CSS selector or XPath for the element to interact with
              required:
                - command
          description: Array of automation commands to execute before/after screenshot
          example:
            - command: navigate
              value: "https://example.com/login"
            - command: type
              element: "input[name='username']"
              value: "testuser"
            - command: click
              element: "button[type='submit']"
            - command: sleep
              value: "2000"
            - command: screenshot

        - name: step
          in: query
          schema:
            type: array
            items:
              type: object
              properties:
                command:
                  type: string
                  enum: [type, click, navigate, screenshot, sleep, javascript, scroll, for, end]
                  description: Command to execute
                value:
                  type: string
                  description: Value for the command (e.g., text to type, URL to navigate, sleep duration)
                element:
                  type: string
                  description: CSS selector or XPath for the element to interact with
              required:
                - command
          description: Alternative steps array notation (step[0][command], step[0][value], etc.). Cannot be used with steps.
        
        - name: trackers
          in: query
          schema:
            type: array
            items:
              type: object
              properties:
                id:
                  type: string
                  description: Unique identifier for the tracker
                name:
                  type: string
                  description: Name of the metric to track
                value:
                  description: Value to track (can be any type - string, number, boolean, etc)
                input:
                  type: string
                  description: Optional input selector or value
                selector:
                  type: string
                  description: CSS selector or XPath for the element to track
                name_type:
                  type: string
                  description: Optional type designation for the tracker name
              required:
                - id
                - name
                - value
          description: Array of trackers to capture metrics during screenshot execution
          example:
            - id: "tracker1"
              name: "page_title"
              value: "title"
              selector: "title"
            - id: "tracker2"
              name: "form_fields"
              value: "count"
              selector: ".form-field"

        - name: tracker
          in: query
          schema:
            type: array
            items:
              type: object
              properties:
                id:
                  type: string
                  description: Unique identifier for the tracker
                name:
                  type: string
                  description: Name of the metric to track
                value:
                  description: Value to track (can be any type - string, number, boolean, etc)
                input:
                  type: string
                  description: Optional input selector or value
                selector:
                  type: string
                  description: CSS selector or XPath for the element to track
                name_type:
                  type: string
                  description: Optional type designation for the tracker name
              required:
                - id
                - name
                - value
          description: Alternative trackers array notation (tracker[0][id], tracker[0][name], etc.). Cannot be used with trackers.
        
        - name: tag
          in: query
          style: form
          explode: true
          schema:
            type: array
            items:
              type: string
              maxLength: 50
          description: Tags for organizing screenshots. Can specify multiple tags as tag=one&tag=two or comma-separated as tag=one,two
      
      responses:
        '200':
          description: Screenshot request accepted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Screenshot'
              example:
                success: true
                data:
                  id: 12345678
                  status: processing
                  url: "https://example.com"
                  final_url: "https://example.com"
                  response_code: null
                  cost: 1
                  tag: []
                  created_at: "2026-02-06T05:34:02.730Z"
                  finished_at: ""
                  country: "us"
                  region: "America"
                  language: "en-US"
                  timezone: "America/New_York"
                  geo_enable: false
                  geo_latitude: 40.7128
                  geo_longitude: -74.006
                  size: "screen"
                  cache: 86400
                  delay: 5
                  screen_width: 1024
                  screen_height: 1280
                  priority: 2
                  referer: ""
                  post_data: ""
                  cookie: ""
                  script: ""
                  html: false
                  pdf: false
                  pdf_background: false
                  pdf_one_page: false
                  pdf_landscape: false
                  pdf_format: letter
                  pdf_margin: '0px'
                  pdf_margin_top: '0px'
                  pdf_margin_bottom: '0px'
                  pdf_margin_left: '0px'
                  pdf_margin_right: '0px'
                  video: false
                  video_format: webm
                  video_quality: 30
                  video_speed: 1
                  video_duration: 15
                  video_fps: null
                  video_colors: null
                  video_scale: null
                  max_wait: 0
                  header: ""
                  hide_popups: false
                  hide_ads: false
                  dark: false
                  shots: 1
                  shot_interval: 5
                  strict_ssl: false
                  target: ""
                  device_name: ""
                  device_scale: 3
                  device_touch: true
                  device_landscape: false
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Insufficient balance or account limitations
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: "Insufficient credit balance"
                status: error
                code: INSUFFICIENT_BALANCE
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retry
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: Service temporarily unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /screenshot/info:
    get:
      summary: Query screenshot status
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/screenshot/info?key=YOUR_API_KEY&id=1001"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const shot = await client.screenshot.info(1001);
            console.log(shot.status, shot.url);
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            shot = client.screenshot.info(1001)
            print(shot["status"], shot["url"])
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $shot = $client->screenshot->info(1001);
            echo $shot['status'] . ' ' . $shot['url'];
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            shot, err := client.Screenshot.Info(1001)
            if err != nil { panic(err) }
            fmt.Println(shot.Status, shot.URL)
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            JSONObject shot = client.screenshot().info(1001);
            System.out.println(shot.getString("status") + " " + shot.getString("url"));
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            shot = client.screenshot.info(1001)
            puts "#{shot['status']} #{shot['url']}"
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            var shot = await client.Screenshot.InfoAsync(1001);
            Console.WriteLine($"{shot.Status} {shot.Url}");
      operationId: getScreenshotInfo
      tags:
        - Screenshot
      description: Get current status and details of a screenshot request
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
          description: Screenshot ID from /screenshot/create
      
      responses:
        '200':
          description: Screenshot found
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Screenshot'
              example:
                success: true
                data:
                  id: 12345678
                  status: processing
                  url: "https://example.com"
                  final_url: "https://example.com"
                  response_code: null
                  cost: 1
                  tag: []
                  created_at: "2026-02-06T05:34:02.730Z"
                  finished_at: ""
                  country: "us"
                  region: "America"
                  language: "en-US"
                  timezone: "America/New_York"
                  geo_enable: false
                  geo_latitude: 40.7128
                  geo_longitude: -74.006
                  size: "screen"
                  cache: 86400
                  delay: 5
                  screen_width: 1024
                  screen_height: 1280
                  priority: 2
                  referer: ""
                  post_data: ""
                  cookie: ""
                  script: ""
                  html: false
                  pdf: false
                  pdf_background: false
                  pdf_one_page: false
                  pdf_landscape: false
                  pdf_format: letter
                  pdf_margin: '0px'
                  pdf_margin_top: '0px'
                  pdf_margin_bottom: '0px'
                  pdf_margin_left: '0px'
                  pdf_margin_right: '0px'
                  video: false
                  video_format: webm
                  video_quality: 30
                  video_speed: 1
                  video_duration: 15
                  max_wait: 0
                  header: ""
                  hide_popups: false
                  hide_ads: false
                  dark: false
                  shots: 1
                  shot_interval: 5
                  strict_ssl: false
                  target: ""
                  device_name: ""
                  device_scale: 3
                  device_touch: true
                  device_landscape: false
        '400':
          description: Invalid screenshot ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Screenshot not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /screenshot/list:
    get:
      summary: List recent screenshots
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/screenshot/list?key=YOUR_API_KEY"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const shots = await client.screenshot.list({ limit: 20, offset: 0 });
            shots.forEach(s => console.log(s.id, s.status));
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            shots = client.screenshot.list(limit=20, offset=0)
            for s in shots:
                print(s["id"], s["status"])
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $shots = $client->screenshot->list(['limit' => 20, 'offset' => 0]);
            foreach ($shots as $shot) {
                echo $shot['id'] . ' ' . $shot['status'] . PHP_EOL;
            }
        - lang: Go
          label: Go SDK
          source: |
            limit, offset := 20, 0
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            shots, err := client.Screenshot.List(&sc.ListParams{Limit: &limit, Offset: &offset})
            if err != nil { panic(err) }
            for _, s := range shots {
                fmt.Println(s.ID, s.Status)
            }
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            org.json.JSONArray list = client.screenshot().list(
                Map.of("limit", "20", "offset", "0"));
            for (int i = 0; i < list.length(); i++) {
                System.out.println(list.getJSONObject(i).getLong("id"));
            }
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            shots = client.screenshot.list(limit: 20, offset: 0)
            shots.each { |s| puts "#{s['id']} #{s['status']}" }
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            var shots = await client.Screenshot.ListAsync(
                new Dictionary<string, string> { ["limit"] = "20", ["offset"] = "0" });
            foreach (var s in shots) Console.WriteLine($"{s.Id} {s.Status}");
      operationId: listScreenshots
      tags:
        - Screenshot
      description: Get information about the last N screenshots
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 100
          description: Maximum results to return
        
        - name: status
          in: query
          schema:
            type: string
            enum: [error, finished, processing]
          description: Filter by status

      
      responses:
        '200':
          description: Screenshot list
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/ScreenshotList'
              example:
                success: true
                data:
                  - id: 12345678
                    status: finished
                    url: "https://example.com"
                    final_url: "https://example.com"
                    response_code: 200
                    cost: 1
                    tag: []
                    created_at: "2026-02-06T05:34:02.730Z"
                    finished_at: "2026-02-06T05:34:07.120Z"
                    country: "us"
                    region: "America"
                    language: "en-US"
                    timezone: "America/New_York"
                    geo_enable: false
                    geo_latitude: 40.7128
                    geo_longitude: -74.006
                    size: "screen"
                    cache: 86400
                    delay: 5
                    screen_width: 1024
                    screen_height: 1280
                    priority: 2
                    referer: ""
                    post_data: ""
                    cookie: ""
                    script: ""
                    html: false
                    pdf: false
                    pdf_background: false
                    pdf_one_page: false
                    pdf_landscape: false
                    pdf_format: letter
                    pdf_margin: '0px'
                    pdf_margin_top: '0px'
                    pdf_margin_bottom: '0px'
                    pdf_margin_left: '0px'
                    pdf_margin_right: '0px'
                    video: false
                    video_format: webm
                    video_quality: 30
                    video_speed: 1
                    video_duration: 15
                    max_wait: 0
                    header: ""
                    hide_popups: false
                    hide_ads: false
                    dark: false
                    shots: 1
                    shot_interval: 5
                    strict_ssl: false
                    target: ""
                    device_name: ""
                    device_scale: 3
                    device_touch: true
                    device_landscape: false
        '400':
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /screenshot/search:
    get:
      summary: Search screenshots by URL
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/screenshot/search?key=YOUR_API_KEY&url=https://example.com"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const results = await client.screenshot.search({ url: 'example.com', limit: 10 });
            results.forEach(s => console.log(s.id, s.url));
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            results = client.screenshot.search("example.com", limit=10)
            for s in results:
                print(s["id"], s["url"])
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $results = $client->screenshot->search('example.com', ['limit' => 10]);
            foreach ($results as $shot) {
                echo $shot['id'] . ' ' . $shot['url'] . PHP_EOL;
            }
        - lang: Go
          label: Go SDK
          source: |
            limit := 10
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            results, err := client.Screenshot.Search(sc.SearchParams{
                URL:   "example.com",
                Limit: &limit,
            })
            if err != nil { panic(err) }
            for _, s := range results { fmt.Println(s.ID, s.URL) }
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            org.json.JSONArray results = client.screenshot().search(
                "example.com", Map.of("limit", "10"));
            for (int i = 0; i < results.length(); i++) {
                System.out.println(results.getJSONObject(i).getString("url"));
            }
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            results = client.screenshot.search("example.com", limit: 10)
            results.each { |s| puts "#{s['id']} #{s['url']}" }
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            var results = await client.Screenshot.SearchAsync("example.com",
                new Dictionary<string, string> { ["limit"] = "10" });
            foreach (var s in results) Console.WriteLine($"{s.Id} {s.Url}");
      operationId: searchScreenshots
      tags:
        - Screenshot
      description: Find screenshots matching a URL pattern
      parameters:
        - name: url
          in: query
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 2048
          description: URL search pattern
        
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
          description: Maximum results
        
        - name: status
          in: query
          schema:
            type: string
            enum: [error, finished, processing]
          description: Filter by status

        - name: tag
          in: query
          style: form
          explode: true
          schema:
            type: array
            items:
              type: string
              maxLength: 50
          description: Filter by tags (comma-separated or multiple parameters)
      
      responses:
        '200':
          description: Search results
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/ScreenshotList'
              example:
                success: true
                data:
                  - id: 12345678
                    status: finished
                    url: "https://example.com"
                    final_url: "https://example.com"
                    response_code: 200
                    cost: 1
                    tag: []
                    created_at: "2026-02-06T05:34:02.730Z"
                    finished_at: "2026-02-06T05:34:07.120Z"
                    country: "us"
                    region: "America"
                    language: "en-US"
                    timezone: "America/New_York"
                    geo_enable: false
                    geo_latitude: 40.7128
                    geo_longitude: -74.006
                    size: "screen"
                    cache: 86400
                    delay: 5
                    screen_width: 1024
                    screen_height: 1280
                    priority: 2
                    referer: ""
                    post_data: ""
                    cookie: ""
                    script: ""
                    html: false
                    pdf: false
                    pdf_background: false
                    pdf_one_page: false
                    pdf_landscape: false
                    pdf_format: letter
                    pdf_margin: '0px'
                    pdf_margin_top: '0px'
                    pdf_margin_bottom: '0px'
                    pdf_margin_left: '0px'
                    pdf_margin_right: '0px'
                    video: false
                    video_format: webm
                    video_quality: 30
                    video_speed: 1
                    video_duration: 15
                    max_wait: 0
                    header: ""
                    hide_popups: false
                    hide_ads: false
                    dark: false
                    shots: 1
                    shot_interval: 5
                    strict_ssl: false
                    target: ""
                    device_name: ""
                    device_scale: 3
                    device_touch: true
                    device_landscape: false
        '400':
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /screenshot/thumbnail:
    get:
      summary: Retrieve thumbnail image
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/screenshot/thumbnail?key=YOUR_API_KEY&id=1001" --output thumbnail.png
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            // Fetch raw bytes
            const bytes = await client.screenshot.thumbnail(1001, { width: 800 });
            // Or save directly to disk
            await client.screenshot.saveImage(1001, './screenshot.png', { width: 800 });
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            # Save directly to disk
            client.screenshot.save_image(1001, "./screenshot.png", width=800)
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            // Save directly to disk
            $client->screenshot->saveImage(1001, './screenshot.png', ['width' => 800]);
        - lang: Go
          label: Go SDK
          source: |
            width := 800
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            // Save directly to disk
            err := client.Screenshot.SaveImage(1001, "./screenshot.png",
                &sc.ThumbnailParams{Width: &width})
            if err != nil { panic(err) }
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            // Save directly to disk
            client.screenshot().saveImage(1001, "./screenshot.png",
                Map.of("width", "800"));
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            # Save directly to disk
            client.screenshot.save_image(1001, "./screenshot.png", width: 800)
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            // Save directly to disk
            await client.Screenshot.SaveImageAsync(1001, "./screenshot.png",
                new Dictionary<string, string> { ["width"] = "800" });
      operationId: getThumbnail
      tags:
        - Screenshot
      description: Download screenshot as PNG or JPEG thumbnail with optional cropping
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
          description: Screenshot ID

        - name: filename
          in: query
          schema:
            type: string
          description: Optional filename for Content-Disposition attachment
        
        - name: width
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 5000
          description: Thumbnail width in pixels
        
        - name: height
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 15000
          description: Thumbnail height in pixels
        
        - name: scale
          in: query
          schema:
            type: number
            format: double
            minimum: 0.1
            maximum: 3.0
            default: 1.0
          description: Scale factor
        
        - name: zoom
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 100
          description: Zoom percentage
        
        - name: ratio
          in: query
          schema:
            type: string
            enum: [fit, fill]
            default: fit
          description: "Aspect ratio mode: fit (preserve) or fill (crop)"
        
        - name: left
          in: query
          schema:
            type: integer
            minimum: 0
            default: 0
          description: Left crop edge in pixels
        
        - name: top
          in: query
          schema:
            type: integer
            minimum: 0
            default: 0
          description: Top crop edge in pixels
        
        - name: right
          in: query
          schema:
            type: integer
            minimum: 0
            default: 0
          description: Right crop edge in pixels
        
        - name: bottom
          in: query
          schema:
            type: integer
            minimum: 0
            default: 0
          description: Bottom crop edge in pixels
        
        - name: format
          in: query
          schema:
            type: string
            enum: [png, jpeg, webp]
            default: png
          description: Image format (`webmp` alias is accepted and normalized to `webp`)
        
        - name: quality
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 100
          description: JPEG/WEBP quality (1-100)
        
        - name: shot
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 10
            default: 1
          description: Which screenshot if multiple requested
      
      responses:
        '200':
          description: Thumbnail image
          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 parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Screenshot not found or not ready
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /screenshot/delete:
    get:
      summary: Delete screenshot data
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/screenshot/delete?key=YOUR_API_KEY&id=1001"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            await client.screenshot.delete(1001);
            console.log('Deleted');
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            client.screenshot.delete(1001)
            print("Deleted")
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $client->screenshot->delete(1001);
            echo 'Deleted';
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            if err := client.Screenshot.Delete(1001, "all"); err != nil {
                panic(err)
            }
            fmt.Println("Deleted")
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            client.screenshot().delete(1001, "all");
            System.out.println("Deleted");
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            client.screenshot.delete(1001)
            puts "Deleted"
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            await client.Screenshot.DeleteAsync(1001);
            Console.WriteLine("Deleted");
      operationId: deleteScreenshot
      tags:
        - Screenshot
      description: Permanently delete screenshot files and metadata
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
          description: Screenshot ID
        
        - name: data
          in: query
          schema:
            type: string
            enum: [image, url, metadata, all]
            default: image
          description: "Data to delete: image, url, metadata, or all"
      
      responses:
        '200':
          description: Deletion successful
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/ScreenshotShort'
              example:
                success: true
                data:
                  id: 12345678
                  status: ok
        '400':
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Unauthorized
                code: UNAUTHORIZED
        '404':
          description: Screenshot not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Screenshot not found
                code: NOT_FOUND
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /screenshot/html:
    get:
      summary: Retrieve rendered HTML
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/screenshot/html?key=YOUR_API_KEY&id=1001"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            await client.screenshot.saveHtml(1001, './page.html');
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            client.screenshot.save_html(1001, "./page.html")
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $client->screenshot->saveHtml(1001, './page.html');
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            if err := client.Screenshot.SaveHTML(1001, "./page.html"); err != nil {
                panic(err)
            }
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            client.screenshot().saveHtml(1001, "./page.html");
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            client.screenshot.save_html(1001, "./page.html")
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            await client.Screenshot.SaveHtmlAsync(1001, "./page.html");
      operationId: getHTML
      tags:
        - Screenshot
      description: Get HTML of rendered page (requires html=true in creation)
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
          description: Screenshot ID
      
      responses:
        '200':
          description: HTML content
          content:
            text/html:
              schema:
                type: string
                format: html
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Unauthorized
                code: UNAUTHORIZED
        '404':
          description: Screenshot or HTML not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: HTML not found for screenshot
                code: NOT_FOUND
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /screenshot/pdf:
    get:
      summary: Retrieve rendered PDF
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/screenshot/pdf?key=YOUR_API_KEY&id=1001" --output page.pdf
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            await client.screenshot.savePdf(1001, './page.pdf');
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            client.screenshot.save_pdf(1001, "./page.pdf")
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $client->screenshot->savePdf(1001, './page.pdf');
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            if err := client.Screenshot.SavePDF(1001, "./page.pdf"); err != nil {
                panic(err)
            }
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            client.screenshot().savePdf(1001, "./page.pdf");
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            client.screenshot.save_pdf(1001, "./page.pdf")
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            await client.Screenshot.SavePdfAsync(1001, "./page.pdf");
      operationId: getPDF
      tags:
        - Screenshot
      description: Get PDF of rendered page (requires pdf=true in creation)
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
          description: Screenshot ID
        - name: filename
          in: query
          required: false
          schema:
            type: string
          description: Optional filename for Content-Disposition attachment

      responses:
        '200':
          description: PDF content
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Unauthorized
                code: UNAUTHORIZED
        '404':
          description: Screenshot or PDF not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: PDF not found for screenshot
                code: NOT_FOUND
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /screenshot/video:
    get:
      summary: Retrieve rendered video
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/screenshot/video?key=YOUR_API_KEY&id=1001" --output page.webm
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            await client.screenshot.saveVideo(1001, './recording.webm');
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            client.screenshot.save_video(1001, "./recording.webm")
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $client->screenshot->saveVideo(1001, './recording.webm');
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            if err := client.Screenshot.SaveVideo(1001, "./recording.webm"); err != nil {
                panic(err)
            }
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            client.screenshot().saveVideo(1001, "./recording.webm");
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            client.screenshot.save_video(1001, "./recording.webm")
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            await client.Screenshot.SaveVideoAsync(1001, "./recording.webm");
      operationId: getVideo
      tags:
        - Screenshot
      description: Get screencast video of page loading (requires video=true in creation)
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
          description: Screenshot ID
        - name: filename
          in: query
          required: false
          schema:
            type: string
          description: Optional filename for Content-Disposition attachment

      responses:
        '200':
          description: Video content
          content:
            video/mp4:
              schema:
                type: string
                format: binary
            video/webm:
              schema:
                type: string
                format: binary
            image/gif:
              schema:
                type: string
                format: binary
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Unauthorized
                code: UNAUTHORIZED
        '404':
          description: Screenshot or video not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Video not found for screenshot
                code: NOT_FOUND
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /batch/create:
    post:
      summary: Create batch screenshot job
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl -X POST "https://api.screenshotcenter.com/api/v1/batch/create?key=YOUR_API_KEY" \\
              -H "Content-Type: application/json" \\
              -d '{"urls": ["https://example.com", "https://example.org"]}'
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const urls = ['https://example.com', 'https://example.org', 'https://example.net'];
            const batch = await client.batch.create(urls, 'us');
            // Poll until complete, then download
            const result = await client.batch.waitFor(batch.id, { timeout: 120000 });
            await client.batch.saveZip(result.id, './screenshots.zip');
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            urls = ["https://example.com", "https://example.org", "https://example.net"]
            batch = client.batch.create(urls, country="us")
            result = client.batch.wait_for(batch["id"], timeout=120)
            client.batch.save_zip(result["id"], "./screenshots.zip")
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $urls = ['https://example.com', 'https://example.org', 'https://example.net'];
            $batch = $client->batch->create($urls, 'us');
            $result = $client->batch->waitFor($batch['id']);
            $client->batch->saveZip($result['id'], './screenshots.zip');
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            urls := []string{"https://example.com", "https://example.org", "https://example.net"}
            batch, err := client.Batch.Create(urls, "us", nil)
            if err != nil { panic(err) }
            result, err := client.Batch.WaitFor(batch.ID, &sc.WaitForOptions{Timeout: 120000})
            if err != nil { panic(err) }
            client.Batch.SaveZip(result.ID, "./screenshots.zip")
        - lang: Java
          label: Java SDK (Maven)
          source: |
            import java.util.List;

            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            List<String> urls = List.of(
                "https://example.com", "https://example.org", "https://example.net");
            JSONObject batch = client.batch().create(urls, "us", null);
            JSONObject result = client.batch().waitFor(batch.getLong("id"), null, 120000L);
            client.batch().saveZip(result.getLong("id"), "./screenshots.zip");
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            require "screenshotcenter"

            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            urls = ["https://example.com", "https://example.org", "https://example.net"]
            batch = client.batch.create(urls, "us")
            result = client.batch.wait_for(batch["id"], timeout: 120)
            client.batch.save_zip(result["id"], "./screenshots.zip")
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            var urls = new[] { "https://example.com", "https://example.org", "https://example.net" };
            var batch = await client.Batch.CreateAsync(urls, "us");
            var result = await client.Batch.WaitForAsync(batch.Id, timeoutMs: 120000);
            await client.Batch.SaveZipAsync(result.Id, "./screenshots.zip");
      operationId: createBatch
      tags:
        - Batch
      description: Submit hundreds or thousands of URLs for batch processing
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: Text file with one URL per line
                country:
                  type: string
                  default: us
                  description: ISO country code. Defaults to "us" when omitted.
                apps:
                  type: array
                  description: App configuration IDs to run after each screenshot is finished
                  items:
                    type: integer
                    format: int64
                language:
                  type: string
                  description: Override language/locale (e.g., en-US)
                geo_latitude:
                  type: number
                  format: float
                  description: Override latitude for geolocation
                geo_longitude:
                  type: number
                  format: float
                  description: Override longitude for geolocation
                timezone:
                  type: string
                  description: Override timezone (e.g., America/New_York)
                geo_enable:
                  type: boolean
                  default: false
                  description: Enable geolocation emulation
                size:
                  type: string
                  enum: [screen, page]
                  default: screen
                browser:
                  type: string
                  enum: [chrome, firefox, brave]
                  default: chrome
                  description: Browser to use for screenshot (chrome, firefox, or brave)
                name:
                  type: string
                  maxLength: 255
                  description: Batch name for reference
                cache:
                  type: integer
                  minimum: 0
                  default: 86400
                  description: Cache duration in seconds
                screen_width:
                  type: integer
                  minimum: 1
                  maximum: 5000
                  default: 1024
                screen_height:
                  type: integer
                  minimum: 1
                  maximum: 10000
                  default: 1280
                device_name:
                  type: string
                  description: Device name to emulate (e.g., iphone_15_pro)
                device_scale:
                  type: number
                  minimum: 0.1
                  maximum: 10
                  description: Device scale factor
                device_mobile:
                  type: boolean
                  description: Enable mobile emulation
                device_touch:
                  type: boolean
                  description: Enable touch input
                device_landscape:
                  type: boolean
                  description: Use landscape orientation
                delay:
                  type: integer
                  minimum: 0
                  maximum: 60
                  default: 5
                priority:
                  type: integer
                  minimum: 1
                  maximum: 3
                referer:
                  type: string
                post_data:
                  type: string
                cookie:
                  type: string
                script:
                  type: string
                  format: uri
                header:
                  type: string
                  description: Custom HTTP header(s)
                html:
                  type: boolean
                  default: false
                pdf:
                  type: boolean
                  default: false
                pdf_background:
                  type: boolean
                  default: false
                pdf_one_page:
                  type: boolean
                  default: false
                pdf_landscape:
                  type: boolean
                  default: false
                pdf_format:
                  type: string
                  enum: [a4, letter, legal]
                  default: letter
                pdf_margin:
                  type: string
                  example: '0px'
                pdf_margin_top:
                  type: string
                  example: '0px'
                pdf_margin_bottom:
                  type: string
                  example: '0px'
                pdf_margin_left:
                  type: string
                  example: '0px'
                pdf_margin_right:
                  type: string
                  example: '0px'
                max_wait:
                  type: integer
                  minimum: 0
                  maximum: 60
                  default: 0
                hide_popups:
                  type: boolean
                  default: false
                hide_ads:
                  type: boolean
                  default: false
                dark:
                  type: boolean
                  default: false
                shots:
                  type: integer
                  minimum: 1
                  maximum: 10
                  default: 1
                shot_interval:
                  type: integer
                  minimum: 0
                  maximum: 60
                  default: 0
                strict_ssl:
                  type: boolean
                  default: true
                target:
                  type: string
                  description: CSS selector to capture an element
                steps:
                  type: string
                  description: JSON-encoded steps array
                trackers:
                  type: string
                  description: JSON-encoded trackers array
                filename_template:
                  type: string
                  maxLength: 500
                  description: |
                    Template for output filenames inside the ZIP archive.
                    Supports variables: {id}, {domain}, {shot}, {browser}, {country}, {yyyy}, {mm}, {dd}, {date}, {random}, {tags}, {url}.
                    If {id} is absent, it is injected automatically to guarantee unique filenames.
                    The filename column in the CSV/TSV file overrides this template per row.
                  example: "{domain}/{yyyy}{mm}{dd}-{id}.png"
      
      responses:
        '200':
          description: Batch created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Batch'
              example:
                success: true
                data:
                  - id: 98765
                    status: processing
                    count: 150
                    processed: 0
                    failed: 0
                    error: ""
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Insufficient balance
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: File too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /batch/info:
    get:
      summary: Get batch status
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/batch/info?key=YOUR_API_KEY&id=2001"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const batch = await client.batch.info(2001);
            console.log(batch.status, batch.processed, '/', batch.count);
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            batch = client.batch.info(2001)
            print(batch["status"], batch["processed"], "/", batch["count"])
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $batch = $client->batch->info(2001);
            echo $batch['status'] . ' ' . $batch['processed'] . '/' . $batch['count'];
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            batch, err := client.Batch.Info(2001)
            if err != nil { panic(err) }
            fmt.Printf("%s %d/%d\n", batch.Status, batch.Processed, batch.Count)
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            JSONObject batch = client.batch().info(2001);
            System.out.printf("%s %d/%d%n",
                batch.getString("status"),
                batch.getInt("processed"),
                batch.getInt("count"));
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            batch = client.batch.info(2001)
            puts "#{batch['status']} #{batch['processed']}/#{batch['count']}"
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            var batch = await client.Batch.InfoAsync(2001);
            Console.WriteLine($"{batch.Status} {batch.Processed}/{batch.Count}");
      operationId: getBatchInfo
      tags:
        - Batch
      description: Check processing status and progress of a batch job
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
          description: Batch ID
      
      responses:
        '200':
          description: Batch information
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Batch'
              example:
                success: true
                data:
                  id: 98765
                  status: processing
                  count: 150
                  processed: 42
                  failed: 1
                  error: ""
        '400':
          description: Invalid batch ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Batch not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /batch/list:
    get:
      summary: List recent batches
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/batch/list?key=YOUR_API_KEY"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const batches = await client.batch.list({ limit: 10 });
            batches.forEach(b => console.log(b.id, b.status));
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            batches = client.batch.list(limit=10)
            for b in batches:
                print(b["id"], b["status"])
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $batches = $client->batch->list(['limit' => 10]);
            foreach ($batches as $batch) {
                echo $batch['id'] . ' ' . $batch['status'] . PHP_EOL;
            }
        - lang: Go
          label: Go SDK
          source: |
            limit := 10
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            batches, err := client.Batch.List(&sc.ListParams{Limit: &limit})
            if err != nil { panic(err) }
            for _, b := range batches { fmt.Println(b.ID, b.Status) }
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            org.json.JSONArray list = client.batch().list(Map.of("limit", "10"));
            for (int i = 0; i < list.length(); i++) {
                System.out.println(list.getJSONObject(i).getLong("id"));
            }
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            batches = client.batch.list(limit: 10)
            batches.each { |b| puts "#{b['id']} #{b['status']}" }
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            var batches = await client.Batch.ListAsync(
                new Dictionary<string, string> { ["limit"] = "10" });
            foreach (var b in batches) Console.WriteLine($"{b.Id} {b.Status}");
      operationId: listBatches
      tags:
        - Batch
      description: List recent batch jobs for the authenticated user. Supports API key or JWT auth.
      parameters:
        - $ref: '#/components/parameters/ApiKeyQuery'
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
          description: Maximum number of batches to return
      responses:
        '200':
          description: Batch list
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Batch'
              example:
                success: true
                data:
                  - id: 98765
                    status: finished
                    count: 150
                    processed: 148
                    failed: 2
                    error: ""
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /batch/cancel:
    post:
      summary: Cancel batch job
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl -X POST "https://api.screenshotcenter.com/api/v1/batch/cancel?key=YOUR_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{"id": 2001}'
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            await client.batch.cancel(2001);
            console.log('Batch cancelled');
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $client->batch->cancel(2001);
            echo 'Batch cancelled';
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            if err := client.Batch.Cancel(2001); err != nil {
                panic(err)
            }
            fmt.Println("Batch cancelled")
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            req = urllib.request.Request(
                f"https://api.screenshotcenter.com/api/v1/batch/cancel?key={api_key}",
                data=json.dumps({"id": 2001}).encode(),
                headers={"Content-Type": "application/json"},
                method="POST",
            )
            urllib.request.urlopen(req)
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            require "json"

            uri = URI("https://api.screenshotcenter.com/api/v1/batch/cancel?key=#{ENV['SCREENSHOTCENTER_API_KEY']}")
            Net::HTTP.post(uri, { id: 2001 }.to_json, "Content-Type" => "application/json")
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            await http.PostAsync(
                $"https://api.screenshotcenter.com/api/v1/batch/cancel?key={Environment.GetEnvironmentVariable(\"SCREENSHOTCENTER_API_KEY\")}",
                new StringContent("{\"id\":2001}", System.Text.Encoding.UTF8, "application/json"));
      operationId: cancelBatch
      tags:
        - Batch
      description: Best-effort cancellation of a batch and its screenshots
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: integer
          description: Batch ID
      responses:
        '200':
          description: Batch canceled
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Batch'
              example:
                success: true
                data:
                  id: 98765
                  status: error
                  count: 150
                  processed: 42
                  failed: 108
                  error: Canceled by user
        '400':
          description: Invalid batch ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Batch not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /batch/download:
    get:
      summary: Download batch ZIP archive
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/batch/download?key=YOUR_API_KEY&id=2001" --output screenshots.zip
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            await client.batch.saveZip(2001, './batch-screenshots.zip');
            console.log('Saved to batch-screenshots.zip');
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            client.batch.save_zip(2001, "./batch-screenshots.zip")
            print("Saved to batch-screenshots.zip")
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $client->batch->saveZip(2001, './batch-screenshots.zip');
            echo 'Saved to batch-screenshots.zip';
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            if err := client.Batch.SaveZip(2001, "./batch-screenshots.zip"); err != nil {
                panic(err)
            }
            fmt.Println("Saved to batch-screenshots.zip")
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            client.batch().saveZip(2001, "./batch-screenshots.zip");
            System.out.println("Saved to batch-screenshots.zip");
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            client.batch.save_zip(2001, "./batch-screenshots.zip")
            puts "Saved to batch-screenshots.zip"
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            await client.Batch.SaveZipAsync(2001, "./batch-screenshots.zip");
            Console.WriteLine("Saved to batch-screenshots.zip");
      operationId: downloadBatch
      tags:
        - Batch
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: integer
          description: Batch ID
      responses:
        '200':
          description: Batch ZIP file
          content:
            application/zip:
              schema:
                type: string
                format: binary
        '404':
          description: Batch results not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Batch not found
                code: NOT_FOUND
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Internal server error
                code: INTERNAL_ERROR

  /crawl/create:
    post:
      summary: Start a website crawl
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl -X POST "https://api.screenshotcenter.com/api/v1/crawl/create?key=YOUR_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{"url": "https://example.com", "domain": "example.com", "max_urls": 100}'
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const crawl = await client.crawl.create('https://example.com', 'example.com', 100);
            console.log(crawl);
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $crawl = $client->crawl->create('https://example.com', 'example.com', 100);
            print_r($crawl);
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            crawl, err := client.Crawl.Create("https://example.com", "example.com", 100, nil)
            if err != nil { panic(err) }
            fmt.Println(crawl)
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            data = json.dumps({"url": "https://example.com", "domain": "example.com", "max_urls": 100}).encode()
            req = urllib.request.Request(
                f"https://api.screenshotcenter.com/api/v1/crawl/create?key={api_key}",
                data=data,
                headers={"Content-Type": "application/json"},
                method="POST",
            )
            resp = json.loads(urllib.request.urlopen(req).read())
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            require "json"

            uri = URI("https://api.screenshotcenter.com/api/v1/crawl/create?key=#{ENV['SCREENSHOTCENTER_API_KEY']}")
            resp = Net::HTTP.post(uri, { url: "https://example.com", domain: "example.com", max_urls: 100 }.to_json, "Content-Type" => "application/json")
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            var resp = await http.PostAsync(
                $"https://api.screenshotcenter.com/api/v1/crawl/create?key={Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")}",
                new StringContent("{\"url\":\"https://example.com\",\"domain\":\"example.com\",\"max_urls\":100}", System.Text.Encoding.UTF8, "application/json"));
        - lang: Java
          label: Java HttpClient
          source: |
            var client = java.net.http.HttpClient.newHttpClient();
            var request = java.net.http.HttpRequest.newBuilder()
                .uri(URI.create("https://api.screenshotcenter.com/api/v1/crawl/create?key=" + System.getenv("SCREENSHOTCENTER_API_KEY")))
                .header("Content-Type", "application/json")
                .POST(java.net.http.HttpRequest.BodyPublishers.ofString("{\"url\":\"https://example.com\",\"domain\":\"example.com\",\"max_urls\":100}"))
                .build();
      operationId: createCrawl
      tags:
        - Crawl
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - url
                - domain
                - max_urls
              properties:
                url:
                  type: string
                  format: uri
                  description: Starting URL for the crawl
                  example: "https://example.com"
                domain:
                  type: string
                  description: Domain being crawled
                  example: "example.com"
                max_urls:
                  type: integer
                  minimum: 1
                  maximum: 1000
                  description: Maximum number of pages to screenshot
                  example: 100
                country:
                  type: string
                  description: ISO country code for browser location
                  example: "us"
      parameters:
        - $ref: '#/components/parameters/ApiKeyQuery'
      responses:
        '200':
          description: Crawl created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Crawl'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /crawl/info:
    get:
      summary: Get crawl status and screenshots
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/crawl/info?key=YOUR_API_KEY&id=12345"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const crawl = await client.crawl.info(12345);
            console.log(crawl);
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $crawl = $client->crawl->info(12345);
            print_r($crawl);
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            crawl, err := client.Crawl.Info(12345)
            if err != nil { panic(err) }
            fmt.Println(crawl)
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            req = urllib.request.Request(
                f"https://api.screenshotcenter.com/api/v1/crawl/info?key={api_key}&id=12345",
                method="GET",
            )
            resp = json.loads(urllib.request.urlopen(req).read())
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            require "json"

            uri = URI("https://api.screenshotcenter.com/api/v1/crawl/info?key=#{ENV['SCREENSHOTCENTER_API_KEY']}&id=12345")
            resp = Net::HTTP.get_response(uri)
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            var resp = await http.GetAsync(
                $"https://api.screenshotcenter.com/api/v1/crawl/info?key={Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")}&id=12345");
        - lang: Java
          label: Java HttpClient
          source: |
            var client = java.net.http.HttpClient.newHttpClient();
            var request = java.net.http.HttpRequest.newBuilder()
                .uri(URI.create("https://api.screenshotcenter.com/api/v1/crawl/info?key=" + System.getenv("SCREENSHOTCENTER_API_KEY") + "&id=12345"))
                .GET()
                .build();
      operationId: getCrawlInfo
      tags:
        - Crawl
      parameters:
        - $ref: '#/components/parameters/ApiKeyQuery'
        - name: id
          in: query
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
          description: Crawl ID
      responses:
        '200':
          description: Crawl information with screenshots
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Crawl'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Crawl not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /crawl/list:
    get:
      summary: List crawls
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/crawl/list?key=YOUR_API_KEY&limit=25&offset=0"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const crawls = await client.crawl.list(25, 0);
            console.log(crawls);
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $crawls = $client->crawl->list(['limit' => 25, 'offset' => 0]);
            print_r($crawls);
        - lang: Go
          label: Go SDK
          source: |
            limit := 25
            offset := 0
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            crawls, err := client.Crawl.List(&limit, &offset)
            if err != nil { panic(err) }
            fmt.Println(crawls)
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            req = urllib.request.Request(
                f"https://api.screenshotcenter.com/api/v1/crawl/list?key={api_key}&limit=25&offset=0",
                method="GET",
            )
            resp = json.loads(urllib.request.urlopen(req).read())
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            require "json"

            uri = URI("https://api.screenshotcenter.com/api/v1/crawl/list?key=#{ENV['SCREENSHOTCENTER_API_KEY']}&limit=25&offset=0")
            resp = Net::HTTP.get_response(uri)
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            var resp = await http.GetAsync(
                $"https://api.screenshotcenter.com/api/v1/crawl/list?key={Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")}&limit=25&offset=0");
        - lang: Java
          label: Java HttpClient
          source: |
            var client = java.net.http.HttpClient.newHttpClient();
            var request = java.net.http.HttpRequest.newBuilder()
                .uri(URI.create("https://api.screenshotcenter.com/api/v1/crawl/list?key=" + System.getenv("SCREENSHOTCENTER_API_KEY") + "&limit=25&offset=0"))
                .GET()
                .build();
      operationId: listCrawls
      tags:
        - Crawl
      parameters:
        - $ref: '#/components/parameters/ApiKeyQuery'
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
          description: Maximum number of crawls to return
        - name: offset
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
          description: Number of crawls to skip
      responses:
        '200':
          description: List of crawls
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Crawl'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /crawl/cancel:
    post:
      summary: Cancel a crawl (preserves completed screenshots)
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl -X POST "https://api.screenshotcenter.com/api/v1/crawl/cancel?key=YOUR_API_KEY&id=12345"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const crawl = await client.crawl.cancel(12345);
            console.log(crawl);
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $crawl = $client->crawl->cancel(12345);
            print_r($crawl);
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            crawl, err := client.Crawl.Cancel(12345)
            if err != nil { panic(err) }
            fmt.Println(crawl)
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            req = urllib.request.Request(
                f"https://api.screenshotcenter.com/api/v1/crawl/cancel?key={api_key}&id=12345",
                method="POST",
            )
            urllib.request.urlopen(req)
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            require "json"

            uri = URI("https://api.screenshotcenter.com/api/v1/crawl/cancel?key=#{ENV['SCREENSHOTCENTER_API_KEY']}&id=12345")
            Net::HTTP.post(uri, "", "Content-Type" => "application/json")
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            await http.PostAsync(
                $"https://api.screenshotcenter.com/api/v1/crawl/cancel?key={Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")}&id=12345",
                new StringContent("", System.Text.Encoding.UTF8, "application/json"));
        - lang: Java
          label: Java HttpClient
          source: |
            var client = java.net.http.HttpClient.newHttpClient();
            var request = java.net.http.HttpRequest.newBuilder()
                .uri(URI.create("https://api.screenshotcenter.com/api/v1/crawl/cancel?key=" + System.getenv("SCREENSHOTCENTER_API_KEY") + "&id=12345"))
                .header("Content-Type", "application/json")
                .POST(java.net.http.HttpRequest.BodyPublishers.noBody())
                .build();
      operationId: cancelCrawl
      tags:
        - Crawl
      parameters:
        - $ref: '#/components/parameters/ApiKeyQuery'
        - name: id
          in: query
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
          description: Crawl ID
      responses:
        '200':
          description: Crawl cancelled
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Crawl'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Crawl not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /account/info:
    get:
      summary: Get account information
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/account/info?key=YOUR_API_KEY"
        - lang: JavaScript
          label: JS SDK (npm)
          source: |
            import { ScreenshotCenterClient } from 'screenshotcenter';

            const client = new ScreenshotCenterClient(process.env.SCREENSHOTCENTER_API_KEY);
            const account = await client.account.info();
            console.log('Balance:', account.balance, 'credits');
        - lang: Python
          label: Python SDK (PyPI)
          source: |
            import os
            from screenshotcenter import ScreenshotCenterClient

            client = ScreenshotCenterClient(os.environ["SCREENSHOTCENTER_API_KEY"])
            account = client.account.info()
            print(f"Balance: {account['balance']} credits")
        - lang: PHP
          label: PHP SDK (Packagist)
          source: |
            <?php
            use ScreenshotCenter\Client;

            $client = new Client($_ENV['SCREENSHOTCENTER_API_KEY']);
            $account = $client->account->info();
            echo 'Balance: ' . $account['balance'] . ' credits';
        - lang: Go
          label: Go SDK
          source: |
            client := sc.New(os.Getenv("SCREENSHOTCENTER_API_KEY"))
            account, err := client.Account.Info()
            if err != nil { panic(err) }
            fmt.Printf("Balance: %.0f credits\n", account.Balance)
        - lang: Java
          label: Java SDK (Maven)
          source: |
            ScreenshotCenterClient client = new ScreenshotCenterClient(
                System.getenv("SCREENSHOTCENTER_API_KEY"));
            JSONObject account = client.account().info();
            System.out.printf("Balance: %.0f credits%n", account.getDouble("balance"));
        - lang: Ruby
          label: Ruby SDK (RubyGems)
          source: |
            client = ScreenshotCenter::Client.new(ENV["SCREENSHOTCENTER_API_KEY"])
            account = client.account.info
            puts "Balance: #{account['balance']} credits"
        - lang: C#
          label: .NET SDK (NuGet)
          source: |
            var client = new ScreenshotCenterClient(
                Environment.GetEnvironmentVariable("SCREENSHOTCENTER_API_KEY")!);
            var account = await client.Account.InfoAsync();
            Console.WriteLine($"Balance: {account.Balance} credits");
      operationId: getAccountInfo
      tags:
        - Account
      description: Retrieve account balance, limits, and configuration
      parameters:
        - name: details
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 3
            default: 1
          description: "Detail level: 1=basic, 3=with recent screenshots"
      
      responses:
        '200':
          description: Account information
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Account'
              example:
                success: true
                data:
                  balance: 5000
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Unauthorized
                code: UNAUTHORIZED
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Internal server error
                code: INTERNAL_ERROR

  /device/list:
    get:
      summary: List available device emulations
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/device/list?key=YOUR_API_KEY"
        - lang: JavaScript
          label: fetch
          source: |
            const res = await fetch(
              `https://api.screenshotcenter.com/api/v1/device/list?key=${process.env.SCREENSHOTCENTER_API_KEY}`
            );
            const { data } = await res.json();
            console.log(data);
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            url = f"https://api.screenshotcenter.com/api/v1/device/list?key={api_key}"
            with urllib.request.urlopen(url) as r:
                print(json.loads(r.read())["data"])
        - lang: PHP
          label: file_get_contents
          source: |
            <?php
            $key  = $_ENV['SCREENSHOTCENTER_API_KEY'];
            $data = json_decode(file_get_contents(
                "https://api.screenshotcenter.com/api/v1/device/list?key={$key}"
            ), true)['data'];
            print_r($data);
        - lang: Go
          label: net/http
          source: |
            resp, _ := http.Get(
                "https://api.screenshotcenter.com/api/v1/device/list?key=" +
                os.Getenv("SCREENSHOTCENTER_API_KEY"))
            defer resp.Body.Close()
            body, _ := io.ReadAll(resp.Body)
            fmt.Println(string(body))
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            uri = URI("https://api.screenshotcenter.com/api/v1/device/list?key=#{ENV['SCREENSHOTCENTER_API_KEY']}")
            puts Net::HTTP.get(uri)
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            var json = await http.GetStringAsync(
                $"https://api.screenshotcenter.com/api/v1/device/list?key={Environment.GetEnvironmentVariable(\"SCREENSHOTCENTER_API_KEY\")}");
            Console.WriteLine(json);
      operationId: listDevices
      tags:
        - Device
      description: Retrieve the list of device names available for device emulation. Supports API key or JWT auth.
      parameters:
        - $ref: '#/components/parameters/ApiKeyQuery'
      responses:
        '200':
          description: Device list
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        device_name:
                          type: string
                          example: iphone_15_pro
                        name:
                          type: string
                          example: iPhone 15 Pro
                        user_agent:
                          type: string
                        screen_width:
                          type: integer
                          example: 393
                        screen_height:
                          type: integer
                          example: 852
                        device_scale:
                          type: number
                          example: 3
                        device_mobile:
                          type: boolean
                          example: true
                        device_touch:
                          type: boolean
                          example: true
                        device_landscape:
                          type: boolean
                          example: false
              examples:
                success:
                  value:
                    success: true
                    data:
                      - device_name: iphone_15_pro
                        name: iPhone 15 Pro
                        user_agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)
                        screen_width: 393
                        screen_height: 852
                        device_scale: 3
                        device_mobile: true
                        device_touch: true
                        device_landscape: false
                      - device_name: iphone_15_pro_landscape
                        name: iPhone 15 Pro Landscape
                        user_agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)
                        screen_width: 852
                        screen_height: 393
                        device_scale: 3
                        device_mobile: true
                        device_touch: true
                        device_landscape: true
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /app/list:
    get:
      summary: List user apps
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/app/list?key=YOUR_API_KEY"
        - lang: JavaScript
          label: fetch
          source: |
            const res = await fetch(
              `https://api.screenshotcenter.com/api/v1/app/list?key=${process.env.SCREENSHOTCENTER_API_KEY}`
            );
            const { data } = await res.json();
            console.log(data);
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            url = f"https://api.screenshotcenter.com/api/v1/app/list?key={api_key}"
            with urllib.request.urlopen(url) as r:
                print(json.loads(r.read())["data"])
        - lang: PHP
          label: file_get_contents
          source: |
            <?php
            $key  = $_ENV['SCREENSHOTCENTER_API_KEY'];
            $data = json_decode(file_get_contents(
                "https://api.screenshotcenter.com/api/v1/app/list?key={$key}"
            ), true)['data'];
            print_r($data);
        - lang: Go
          label: net/http
          source: |
            resp, _ := http.Get(
                "https://api.screenshotcenter.com/api/v1/app/list?key=" +
                os.Getenv("SCREENSHOTCENTER_API_KEY"))
            defer resp.Body.Close()
            body, _ := io.ReadAll(resp.Body)
            fmt.Println(string(body))
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            uri = URI("https://api.screenshotcenter.com/api/v1/app/list?key=#{ENV['SCREENSHOTCENTER_API_KEY']}")
            puts Net::HTTP.get(uri)
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            var json = await http.GetStringAsync(
                $"https://api.screenshotcenter.com/api/v1/app/list?key={Environment.GetEnvironmentVariable(\"SCREENSHOTCENTER_API_KEY\")}");
            Console.WriteLine(json);
      operationId: listApps
      tags:
        - App
      description: List configured apps for the authenticated user. Supports API key or JWT auth.
      parameters:
        - $ref: '#/components/parameters/ApiKeyQuery'
      responses:
        '200':
          description: App list
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      default_path_template:
                        type: string
                      apps:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              format: int64
                            app_id:
                              type: string
                            type:
                              type: string
                            name:
                              type: string
                            status:
                              type: string
                            isActive:
                              type: boolean
                            createdAt:
                              type: string
                            updatedAt:
                              type: string
                            lastVerifiedAt:
                              type: [string, 'null']
                            lastError:
                              type: string
              example:
                success: true
                data:
                  default_path_template: screenshotCenter/{domain}/{yyyy}{mm}{dd}-{id}.png
                  apps:
                    - id: 12
                      app_id: marketing-drive
                      type: gdrive
                      name: Marketing Drive
                      status: active
                      isActive: true
                      createdAt: "2026-02-01T12:00:00.000Z"
                      updatedAt: "2026-02-01T12:00:00.000Z"
                      lastVerifiedAt: "2026-02-01T12:01:00.000Z"
                      lastError: ""

  /app/info:
    get:
      summary: Get app configuration
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/app/info?key=YOUR_API_KEY&id=APP_ID"
        - lang: JavaScript
          label: fetch
          source: |
            const res = await fetch(
              `https://api.screenshotcenter.com/api/v1/app/info?key=${process.env.SCREENSHOTCENTER_API_KEY}&id=APP_ID`
            );
            const { data } = await res.json();
            console.log(data);
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            url = f"https://api.screenshotcenter.com/api/v1/app/info?key={api_key}&id=APP_ID"
            with urllib.request.urlopen(url) as r:
                print(json.loads(r.read())["data"])
        - lang: PHP
          label: file_get_contents
          source: |
            <?php
            $key  = $_ENV['SCREENSHOTCENTER_API_KEY'];
            $data = json_decode(file_get_contents(
                "https://api.screenshotcenter.com/api/v1/app/info?key={$key}&id=APP_ID"
            ), true)['data'];
            print_r($data);
        - lang: Go
          label: net/http
          source: |
            resp, _ := http.Get(
                "https://api.screenshotcenter.com/api/v1/app/info?key=" +
                os.Getenv("SCREENSHOTCENTER_API_KEY") + "&id=APP_ID")
            defer resp.Body.Close()
            body, _ := io.ReadAll(resp.Body)
            fmt.Println(string(body))
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            uri = URI("https://api.screenshotcenter.com/api/v1/app/info?key=#{ENV['SCREENSHOTCENTER_API_KEY']}&id=APP_ID")
            puts Net::HTTP.get(uri)
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            var json = await http.GetStringAsync(
                $"https://api.screenshotcenter.com/api/v1/app/info?key={Environment.GetEnvironmentVariable(\"SCREENSHOTCENTER_API_KEY\")}&id=APP_ID");
            Console.WriteLine(json);
      operationId: getApp
      tags:
        - App
      description: Retrieve a single app configuration. Requires JWT auth.
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: App configuration
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                        format: int64
                      app_id:
                        type: string
                      type:
                        type: string
                      name:
                        type: string
                      status:
                        type: string
                      isActive:
                        type: boolean
                      lastError:
                        type: [string, 'null']
                      lastVerifiedAt:
                        type: [string, 'null']
                      createdAt:
                        type: string
                      updatedAt:
                        type: string
                      config:
                        type: object
              example:
                success: true
                data:
                  id: 12
                  app_id: marketing-drive
                  type: gdrive
                  name: Marketing Drive
                  status: active
                  isActive: true
                  lastError: null
                  lastVerifiedAt: "2026-02-01T12:01:00.000Z"
                  createdAt: "2026-02-01T12:00:00.000Z"
                  updatedAt: "2026-02-01T12:00:00.000Z"
                  config:
                    pathTemplate: screenshotCenter/{domain}/{yyyy}{mm}{dd}-{id}.png

  /app/test:
    post:
      summary: Test an app configuration
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl -X POST "https://api.screenshotcenter.com/api/v1/app/test?key=YOUR_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{"id": "APP_ID"}'
        - lang: JavaScript
          label: fetch
          source: |
            const res = await fetch(
              `https://api.screenshotcenter.com/api/v1/app/test?key=${process.env.SCREENSHOTCENTER_API_KEY}`,
              {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ id: 'APP_ID' }),
              }
            );
            const { data } = await res.json();
            console.log(data);
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            req = urllib.request.Request(
                f"https://api.screenshotcenter.com/api/v1/app/test?key={api_key}",
                data=json.dumps({"id": "APP_ID"}).encode(),
                headers={"Content-Type": "application/json"},
                method="POST",
            )
            with urllib.request.urlopen(req) as r:
                print(json.loads(r.read())["data"])
        - lang: PHP
          label: file_get_contents
          source: |
            <?php
            $key = $_ENV['SCREENSHOTCENTER_API_KEY'];
            $ctx = stream_context_create(['http' => [
                'method'  => 'POST',
                'header'  => 'Content-Type: application/json',
                'content' => json_encode(['id' => 'APP_ID']),
            ]]);
            $data = json_decode(file_get_contents(
                "https://api.screenshotcenter.com/api/v1/app/test?key={$key}", false, $ctx
            ), true)['data'];
            print_r($data);
        - lang: Go
          label: net/http
          source: |
            body := strings.NewReader(`{"id":"APP_ID"}`)
            resp, _ := http.Post(
                "https://api.screenshotcenter.com/api/v1/app/test?key="+os.Getenv("SCREENSHOTCENTER_API_KEY"),
                "application/json", body)
            defer resp.Body.Close()
            b, _ := io.ReadAll(resp.Body)
            fmt.Println(string(b))
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            require "json"

            uri = URI("https://api.screenshotcenter.com/api/v1/app/test?key=#{ENV['SCREENSHOTCENTER_API_KEY']}")
            res = Net::HTTP.post(uri, { id: "APP_ID" }.to_json, "Content-Type" => "application/json")
            puts res.body
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            var res = await http.PostAsync(
                $"https://api.screenshotcenter.com/api/v1/app/test?key={Environment.GetEnvironmentVariable(\"SCREENSHOTCENTER_API_KEY\")}",
                new StringContent("{\"id\":\"APP_ID\"}", System.Text.Encoding.UTF8, "application/json"));
            Console.WriteLine(await res.Content.ReadAsStringAsync());
      operationId: testApp
      tags:
        - App
      description: Queue a test for an app configuration. Requires JWT auth.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [id]
              properties:
                id:
                  type: integer
                  format: int64
      responses:
        '200':
          description: App test queued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              example:
                success: true
                data:
                  ok: true

  /app/default-template:
    get:
      summary: Get default app path template
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/app/default-template?key=YOUR_API_KEY"
        - lang: JavaScript
          label: fetch
          source: |
            const res = await fetch(
              `https://api.screenshotcenter.com/api/v1/app/default-template?key=${process.env.SCREENSHOTCENTER_API_KEY}`
            );
            const { data } = await res.json();
            console.log(data.template);
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            url = f"https://api.screenshotcenter.com/api/v1/app/default-template?key={api_key}"
            with urllib.request.urlopen(url) as r:
                print(json.loads(r.read())["data"]["template"])
        - lang: PHP
          label: file_get_contents
          source: |
            <?php
            $key  = $_ENV['SCREENSHOTCENTER_API_KEY'];
            $data = json_decode(file_get_contents(
                "https://api.screenshotcenter.com/api/v1/app/default-template?key={$key}"
            ), true)['data'];
            echo $data['template'];
        - lang: Go
          label: net/http
          source: |
            resp, _ := http.Get(
                "https://api.screenshotcenter.com/api/v1/app/default-template?key=" +
                os.Getenv("SCREENSHOTCENTER_API_KEY"))
            defer resp.Body.Close()
            body, _ := io.ReadAll(resp.Body)
            fmt.Println(string(body))
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            uri = URI("https://api.screenshotcenter.com/api/v1/app/default-template?key=#{ENV['SCREENSHOTCENTER_API_KEY']}")
            puts Net::HTTP.get(uri)
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            var json = await http.GetStringAsync(
                $"https://api.screenshotcenter.com/api/v1/app/default-template?key={Environment.GetEnvironmentVariable(\"SCREENSHOTCENTER_API_KEY\")}");
            Console.WriteLine(json);
      operationId: getAppDefaultTemplate
      tags:
        - App
      description: Retrieve default path template. Requires JWT auth.
      responses:
        '200':
          description: Default path template
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              example:
                success: true
                data:
                  default_path_template: screenshotCenter/{domain}/{yyyy}{mm}{dd}-{id}.png
    post:
      summary: Update default app path template
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl -X POST "https://api.screenshotcenter.com/api/v1/app/default-template?key=YOUR_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{"template": "{id}/{url}.png"}'
        - lang: JavaScript
          label: fetch
          source: |
            const res = await fetch(
              `https://api.screenshotcenter.com/api/v1/app/default-template?key=${process.env.SCREENSHOTCENTER_API_KEY}`,
              {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ template: '{id}/{url}.png' }),
              }
            );
            const { data } = await res.json();
            console.log(data);
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            req = urllib.request.Request(
                f"https://api.screenshotcenter.com/api/v1/app/default-template?key={api_key}",
                data=json.dumps({"template": "{id}/{url}.png"}).encode(),
                headers={"Content-Type": "application/json"},
                method="POST",
            )
            with urllib.request.urlopen(req) as r:
                print(json.loads(r.read())["data"])
        - lang: PHP
          label: file_get_contents
          source: |
            <?php
            $key = $_ENV['SCREENSHOTCENTER_API_KEY'];
            $ctx = stream_context_create(['http' => [
                'method'  => 'POST',
                'header'  => 'Content-Type: application/json',
                'content' => json_encode(['template' => '{id}/{url}.png']),
            ]]);
            $data = json_decode(file_get_contents(
                "https://api.screenshotcenter.com/api/v1/app/default-template?key={$key}",
                false, $ctx
            ), true)['data'];
            print_r($data);
        - lang: Go
          label: net/http
          source: |
            body := strings.NewReader(`{"template":"{id}/{url}.png"}`)
            resp, _ := http.Post(
                "https://api.screenshotcenter.com/api/v1/app/default-template?key="+os.Getenv("SCREENSHOTCENTER_API_KEY"),
                "application/json", body)
            defer resp.Body.Close()
            b, _ := io.ReadAll(resp.Body)
            fmt.Println(string(b))
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            require "json"

            uri = URI("https://api.screenshotcenter.com/api/v1/app/default-template?key=#{ENV['SCREENSHOTCENTER_API_KEY']}")
            res = Net::HTTP.post(uri, { template: "{id}/{url}.png" }.to_json,
                "Content-Type" => "application/json")
            puts res.body
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            var res = await http.PostAsync(
                $"https://api.screenshotcenter.com/api/v1/app/default-template?key={Environment.GetEnvironmentVariable(\"SCREENSHOTCENTER_API_KEY\")}",
                new StringContent("{\"template\":\"{id}/{url}.png\"}", System.Text.Encoding.UTF8, "application/json"));
            Console.WriteLine(await res.Content.ReadAsStringAsync());
      operationId: updateAppDefaultTemplate
      tags:
        - App
      description: Update default path template. Requires JWT auth.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [default_path_template]
              properties:
                default_path_template:
                  type: string
      responses:
        '200':
          description: Default path template updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
              example:
                success: true
                data:
                  ok: true

  /country/list:
    get:
      summary: List available countries
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl "https://api.screenshotcenter.com/api/v1/country/list?key=YOUR_API_KEY"
        - lang: JavaScript
          label: fetch
          source: |
            const res = await fetch(
              `https://api.screenshotcenter.com/api/v1/country/list?key=${process.env.SCREENSHOTCENTER_API_KEY}`
            );
            const { data } = await res.json();
            console.log(data);
        - lang: Python
          label: urllib
          source: |
            import os, urllib.request, json

            api_key = os.environ["SCREENSHOTCENTER_API_KEY"]
            url = f"https://api.screenshotcenter.com/api/v1/country/list?key={api_key}"
            with urllib.request.urlopen(url) as r:
                print(json.loads(r.read())["data"])
        - lang: PHP
          label: file_get_contents
          source: |
            <?php
            $key  = $_ENV['SCREENSHOTCENTER_API_KEY'];
            $data = json_decode(file_get_contents(
                "https://api.screenshotcenter.com/api/v1/country/list?key={$key}"
            ), true)['data'];
            print_r($data);
        - lang: Go
          label: net/http
          source: |
            resp, _ := http.Get(
                "https://api.screenshotcenter.com/api/v1/country/list?key=" +
                os.Getenv("SCREENSHOTCENTER_API_KEY"))
            defer resp.Body.Close()
            body, _ := io.ReadAll(resp.Body)
            fmt.Println(string(body))
        - lang: Ruby
          label: Net::HTTP
          source: |
            require "net/http"
            uri = URI("https://api.screenshotcenter.com/api/v1/country/list?key=#{ENV['SCREENSHOTCENTER_API_KEY']}")
            puts Net::HTTP.get(uri)
        - lang: C#
          label: HttpClient
          source: |
            using var http = new HttpClient();
            var json = await http.GetStringAsync(
                $"https://api.screenshotcenter.com/api/v1/country/list?key={Environment.GetEnvironmentVariable(\"SCREENSHOTCENTER_API_KEY\")}");
            Console.WriteLine(json);
      operationId: listCountries
      tags:
        - Country
      description: Retrieve the list of countries available for screenshots. Supports API key or JWT auth.
      parameters:
        - $ref: '#/components/parameters/ApiKeyQuery'
      responses:
        '200':
          description: Country list
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                          example: us
                        display_name:
                          type: string
                          example: United States
                        region:
                          type: string
                          example: America
              example:
                success: true
                data:
                  - name: us
                    display_name: United States
                    region: America
                  - name: gb
                    display_name: United Kingdom
                    region: Europe
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Unauthorized
                code: UNAUTHORIZED
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Forbidden
                code: FORBIDDEN
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                success: false
                error: Internal server error
                code: INTERNAL_ERROR
