{
  "openapi": "3.0.3",
  "info": {
    "title": "GoScreenAPI",
    "description": "Fast, reliable screenshot API powered by Playwright. Capture any webpage as PNG, JPG, WebP or PDF with full control over viewport, rendering, and output.",
    "version": "1.0.0",
    "contact": {
      "name": "GoScreenAPI Support",
      "url": "https://goscreenapi.com/contact",
      "email": "support@goscreenapi.com"
    },
    "termsOfService": "https://goscreenapi.com/terms",
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://goscreenapi.com/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "tags": [
    { "name": "Screenshot", "description": "Capture webpages as images or PDFs" },
    { "name": "Batch", "description": "Submit multiple screenshot requests at once" },
    { "name": "Diff", "description": "Compare two screenshots visually" },
    { "name": "OG Image", "description": "Generate Open Graph images" },
    { "name": "Account", "description": "Account info and quota" }
  ],
  "paths": {
    "/screenshot": {
      "post": {
        "operationId": "createScreenshot",
        "tags": ["Screenshot"],
        "summary": "Create a screenshot",
        "description": "Capture a webpage or raw HTML as an image (PNG, JPG, WebP) or PDF. Supports sync and async modes, full-page capture, element selection, custom CSS, JavaScript execution, and more.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ScreenshotRequest" },
              "examples": {
                "simple": {
                  "summary": "Simple screenshot",
                  "value": { "url": "https://example.com", "format": "png" }
                },
                "fullPage": {
                  "summary": "Full page screenshot",
                  "value": { "url": "https://example.com", "full_page": true, "format": "png", "async": false }
                },
                "mobile": {
                  "summary": "Mobile screenshot",
                  "value": { "url": "https://example.com", "device": "mobile", "format": "jpg", "quality": 90 }
                },
                "element": {
                  "summary": "Element capture",
                  "value": { "url": "https://example.com", "selector": "#hero", "format": "png" }
                },
                "pdf": {
                  "summary": "PDF export",
                  "value": { "url": "https://example.com", "format": "pdf", "full_page": true }
                },
                "advanced": {
                  "summary": "Advanced with dark mode + custom CSS",
                  "value": { "url": "https://example.com", "theme": "dark", "css": "body { font-size: 18px; }", "block_ads": true, "block_cookies": true, "delay": 2000 }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Screenshot completed (sync mode)",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ScreenshotResponse" }
              }
            }
          },
          "202": {
            "description": "Screenshot queued (async mode)",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AsyncResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/screenshot/{requestId}": {
      "get": {
        "operationId": "getScreenshot",
        "tags": ["Screenshot"],
        "summary": "Get screenshot status",
        "description": "Poll the status of an async screenshot request. Returns the result when completed.",
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "responses": {
          "200": {
            "description": "Screenshot status",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ScreenshotResponse" }
              }
            }
          },
          "404": { "description": "Screenshot not found" }
        }
      }
    },
    "/screenshots": {
      "get": {
        "operationId": "listScreenshots",
        "tags": ["Screenshot"],
        "summary": "List screenshot history",
        "description": "Get paginated list of your screenshot requests with filtering options.",
        "parameters": [
          { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
          { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["queued", "processing", "completed", "failed"] } }
        ],
        "responses": {
          "200": {
            "description": "Paginated screenshot list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/ScreenshotResponse" } },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/batch": {
      "post": {
        "operationId": "createBatch",
        "tags": ["Batch"],
        "summary": "Create batch screenshots",
        "description": "Submit up to 50 screenshot requests in a single API call. Each request is processed independently.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/BatchRequest" }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Batch created",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BatchResponse" }
              }
            }
          }
        }
      }
    },
    "/batch/{batchId}": {
      "get": {
        "operationId": "getBatch",
        "tags": ["Batch"],
        "summary": "Get batch status",
        "parameters": [
          { "name": "batchId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "Batch status with all items",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BatchResponse" }
              }
            }
          }
        }
      }
    },
    "/diff": {
      "post": {
        "operationId": "compareScreenshots",
        "tags": ["Diff"],
        "summary": "Visual diff between two screenshots",
        "description": "Compare two completed screenshots pixel-by-pixel. Returns a diff percentage and diff image URL.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/DiffRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Diff result",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/DiffResponse" }
              }
            }
          }
        }
      }
    },
    "/og-image": {
      "post": {
        "operationId": "generateOgImage",
        "tags": ["OG Image"],
        "summary": "Generate an OG image",
        "description": "Generate a customizable Open Graph image with title, description, and branding.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/OgImageRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OG image generated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "example": "completed" },
                    "image_url": { "type": "string", "format": "uri" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/me": {
      "get": {
        "operationId": "getAccount",
        "tags": ["Account"],
        "summary": "Get account info",
        "description": "Returns your account details, current plan, quota usage, and wallet balance.",
        "responses": {
          "200": {
            "description": "Account info",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AccountInfo" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key from your dashboard. Pass as: Authorization: Bearer YOUR_API_KEY"
      }
    },
    "schemas": {
      "ScreenshotRequest": {
        "type": "object",
        "properties": {
          "url":               { "type": "string", "format": "uri", "description": "URL to capture. Required if html is not set.", "example": "https://example.com" },
          "html":              { "type": "string", "description": "Raw HTML to render. Required if url is not set.", "maxLength": 500000 },
          "async":             { "type": "boolean", "default": true, "description": "false = sync (wait for result). true = async (returns poll URL)." },
          "device":            { "type": "string", "enum": ["desktop", "mobile", "tablet"], "default": "desktop" },
          "width":             { "type": "integer", "minimum": 100, "maximum": 4000, "description": "Viewport width in pixels." },
          "height":            { "type": "integer", "minimum": 100, "maximum": 4000, "description": "Viewport height in pixels." },
          "format":            { "type": "string", "enum": ["png", "jpg", "jpeg", "webp", "pdf"], "default": "png" },
          "quality":           { "type": "integer", "minimum": 1, "maximum": 100, "default": 80, "description": "JPEG/WebP quality." },
          "full_page":         { "type": "boolean", "default": false, "description": "Capture full scrollable page." },
          "selector":          { "type": "string", "description": "CSS selector to capture a specific element.", "example": "#hero" },
          "block_ads":         { "type": "boolean", "default": false, "description": "Block ad networks and trackers." },
          "block_cookies":     { "type": "boolean", "default": false, "description": "Dismiss cookie consent banners." },
          "stealth":           { "type": "boolean", "default": false, "description": "Enable stealth mode to bypass bot detection." },
          "delay":             { "type": "integer", "minimum": 0, "maximum": 10000, "description": "Wait N ms after page load before capture." },
          "timeout":           { "type": "integer", "minimum": 1000, "maximum": 60000, "default": 30000, "description": "Page load timeout in ms." },
          "scroll_to":         { "type": "integer", "description": "Scroll to Y position before capture." },
          "wait_for":          { "type": "string", "description": "CSS selector or ms to wait before capture." },
          "css":               { "type": "string", "maxLength": 65535, "description": "Custom CSS to inject." },
          "theme":             { "type": "string", "enum": ["light", "dark"], "default": "light", "description": "Color scheme preference." },
          "headers":           { "type": "string", "description": "JSON object of custom HTTP headers (max 10 keys)." },
          "js_scenario":       { "type": "string", "maxLength": 4096, "description": "JavaScript to execute before capture." },
          "proxy_country":     { "type": "string", "description": "ISO 3166-1 alpha-2 country code for geo-routing.", "example": "US" },
          "cache_ttl":         { "type": "integer", "minimum": 60, "maximum": 2592000, "description": "Cache result for N seconds." },
          "webhook_url":       { "type": "string", "format": "uri", "description": "URL to POST result to on completion." },
          "webhook_secret":    { "type": "string", "description": "Secret for HMAC-SHA256 webhook signature." },
          "signed_link":       { "type": "boolean", "default": false, "description": "Generate a signed time-limited public link." },
          "signed_link_expires_in": { "type": "integer", "minimum": 60, "maximum": 604800, "default": 3600, "description": "Signed link TTL in seconds." }
        }
      },
      "ScreenshotResponse": {
        "type": "object",
        "properties": {
          "status":       { "type": "string", "enum": ["queued", "processing", "completed", "failed"] },
          "request_id":   { "type": "string", "format": "uuid" },
          "image_url":    { "type": "string", "format": "uri", "nullable": true },
          "signed_url":   { "type": "string", "format": "uri", "nullable": true },
          "duration_ms":  { "type": "integer", "nullable": true },
          "format":       { "type": "string" },
          "width":        { "type": "integer" },
          "height":       { "type": "integer" },
          "file_size":    { "type": "integer", "nullable": true },
          "error":        { "type": "string", "nullable": true },
          "created_at":   { "type": "string", "format": "date-time" }
        }
      },
      "AsyncResponse": {
        "type": "object",
        "properties": {
          "status":     { "type": "string", "example": "queued" },
          "request_id": { "type": "string", "format": "uuid" },
          "poll_url":   { "type": "string", "format": "uri" },
          "stream_url": { "type": "string", "format": "uri" }
        }
      },
      "BatchRequest": {
        "type": "object",
        "required": ["requests"],
        "properties": {
          "callback_url": { "type": "string", "format": "uri", "description": "URL to POST batch results to on completion." },
          "requests": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "type": "object",
              "properties": {
                "url":       { "type": "string", "format": "uri" },
                "html":      { "type": "string" },
                "device":    { "type": "string", "enum": ["desktop", "mobile", "tablet"] },
                "width":     { "type": "integer" },
                "height":    { "type": "integer" },
                "full_page": { "type": "boolean" },
                "format":    { "type": "string", "enum": ["png", "jpg", "webp", "pdf"] }
              }
            }
          }
        }
      },
      "BatchResponse": {
        "type": "object",
        "properties": {
          "batch_id":    { "type": "string", "format": "uuid" },
          "status":      { "type": "string", "enum": ["processing", "completed", "partial", "failed"] },
          "total":       { "type": "integer" },
          "completed":   { "type": "integer" },
          "failed":      { "type": "integer" },
          "items":       { "type": "array", "items": { "$ref": "#/components/schemas/ScreenshotResponse" } }
        }
      },
      "DiffRequest": {
        "type": "object",
        "required": ["request_id_1", "request_id_2"],
        "properties": {
          "request_id_1": { "type": "string", "format": "uuid", "description": "First screenshot request ID." },
          "request_id_2": { "type": "string", "format": "uuid", "description": "Second screenshot request ID." },
          "threshold":    { "type": "number", "minimum": 0, "maximum": 1, "default": 0.1, "description": "Pixel difference threshold (0-1)." },
          "force":        { "type": "boolean", "default": false, "description": "Force recalculation, skip cache." }
        }
      },
      "DiffResponse": {
        "type": "object",
        "properties": {
          "status":          { "type": "string" },
          "diff_percentage": { "type": "number" },
          "diff_pixels":     { "type": "integer" },
          "total_pixels":    { "type": "integer" },
          "diff_image_url":  { "type": "string", "format": "uri" },
          "is_identical":    { "type": "boolean" },
          "threshold":       { "type": "number" }
        }
      },
      "OgImageRequest": {
        "type": "object",
        "required": ["title"],
        "properties": {
          "title":       { "type": "string", "maxLength": 200 },
          "description": { "type": "string", "maxLength": 500 },
          "theme":       { "type": "string", "enum": ["light", "dark", "gradient"], "default": "gradient" },
          "logo_url":    { "type": "string", "format": "uri" },
          "format":      { "type": "string", "enum": ["png", "jpg", "webp"], "default": "png" }
        }
      },
      "AccountInfo": {
        "type": "object",
        "properties": {
          "name":           { "type": "string" },
          "email":          { "type": "string", "format": "email" },
          "plan":           { "type": "string" },
          "monthly_quota":  { "type": "integer" },
          "monthly_used":   { "type": "integer" },
          "remaining":      { "type": "integer" },
          "wallet_balance": { "type": "number" },
          "period_start":   { "type": "string", "format": "date" },
          "period_end":     { "type": "string", "format": "date" }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "current_page": { "type": "integer" },
          "last_page":    { "type": "integer" },
          "per_page":     { "type": "integer" },
          "total":        { "type": "integer" }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": { "type": "string", "example": "error" },
                "message": { "type": "string", "example": "Invalid API key." }
              }
            }
          }
        }
      },
      "ValidationError": {
        "description": "Validation error",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": { "type": "string", "example": "error" },
                "message": { "type": "string" },
                "errors": { "type": "object" }
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": { "type": "string", "example": "error" },
                "message": { "type": "string" },
                "retry_after": { "type": "integer" }
              }
            }
          }
        }
      }
    }
  }
}
