OpenAPI Specification
openapi: 3.1.0
info:
title: SnapAPI - & Web Data Analyze Screenshot API
version: 2.0.0
description: 'Professional screenshot, PDF, video, scraping, content extraction, and AI analysis API. Convert any URL into structured data or visual captures with a single API call. Powered by headless Chromium.
## Authentication
All API endpoints (except Auth and Health) require one of:
- `X-Api-Key: sk_live_xxx` header (recommended for server-side)
- `Authorization: Bearer sk_live_xxx` header
- `?access_key=sk_live_xxx` query parameter (for GET endpoints)
Dashboard endpoints use JWT Bearer tokens obtained from `/auth/login`.
## Rate Limits
| Plan | Requests/month | Rate |
|------|---------------|------|
| Free | 100 | 10/min |
| Starter | 5,000 | 60/min |
| Pro | 50,000 | 300/min |
Rate limit headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`'
contact:
email: support@snapapi.pics
url: https://snapapi.pics
servers:
- url: https://api.snapapi.pics
description: Production
security:
- ApiKeyAuth: []
tags:
- name: Screenshot
description: Screenshot, PDF, and batch capture
paths:
/v1/screenshot:
post:
operationId: takeScreenshot
summary: Take Screenshot
description: Capture a screenshot of any URL, HTML, or Markdown. Supports full-page, device emulation, dark mode, ad blocking, custom CSS/JS, caching, async processing, webhooks, and cloud storage.
tags:
- Screenshot
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ScreenshotRequest'
examples:
simple:
summary: Basic screenshot
value:
url: https://example.com
format: png
fullPage:
summary: Full page + dark mode
value:
url: https://example.com
fullPage: true
darkMode: true
blockAds: true
mobile:
summary: iPhone 15 Pro
value:
url: https://example.com
device: iphone-15-pro
html:
summary: Render HTML
value:
html: <h1>Hello World</h1><p>Rendered by SnapAPI</p>
format: png
width: 800
height: 600
responses:
'200':
description: Screenshot captured successfully
headers:
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
X-RateLimit-Limit:
$ref: '#/components/headers/X-RateLimit-Limit'
X-RateLimit-Remaining:
$ref: '#/components/headers/X-RateLimit-Remaining'
X-RateLimit-Reset:
$ref: '#/components/headers/X-RateLimit-Reset'
content:
image/png:
schema:
type: string
format: binary
image/jpeg:
schema:
type: string
format: binary
image/webp:
schema:
type: string
format: binary
application/pdf:
schema:
type: string
format: binary
application/json:
schema:
$ref: '#/components/schemas/ScreenshotJsonResponse'
'202':
description: Async job accepted
content:
application/json:
schema:
$ref: '#/components/schemas/AsyncJobResponse'
'400':
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Invalid or missing API key
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Feature not available on your plan
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limit or quota exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
get:
operationId: takeScreenshotGet
summary: Take Screenshot (GET)
description: Simple GET endpoint for screenshots via query parameters.
tags:
- Screenshot
parameters:
- name: url
in: query
required: true
schema:
type: string
format: uri
- name: format
in: query
schema:
type: string
enum:
- png
- jpeg
- webp
- avif
- pdf
default: png
- name: quality
in: query
schema:
type: integer
- name: width
in: query
schema:
type: integer
default: 1280
- name: height
in: query
schema:
type: integer
default: 800
- name: full_page
in: query
schema:
type: string
enum:
- 'true'
- 'false'
- name: dark_mode
in: query
schema:
type: string
enum:
- 'true'
- 'false'
- name: block_ads
in: query
schema:
type: string
enum:
- 'true'
- 'false'
- name: block_cookie_banners
in: query
schema:
type: string
enum:
- 'true'
- 'false'
- name: cache
in: query
schema:
type: string
enum:
- 'true'
- 'false'
- name: response_type
in: query
schema:
type: string
enum:
- binary
- base64
- json
default: binary
responses:
'200':
description: Screenshot captured
'400':
description: Validation error
'401':
description: Invalid API key
/v1/screenshot/batch:
post:
operationId: batchScreenshots
summary: Batch Screenshots
description: Submit up to 100 URLs for batch processing. Returns a job ID to poll for results.
tags:
- Screenshot
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BatchRequest'
example:
urls:
- https://example.com
- https://google.com
format: png
width: 1280
responses:
'202':
description: Batch job accepted
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
jobId:
type: string
status:
type: string
total:
type: integer
message:
type: string
'429':
description: Quota exceeded
/v1/screenshot/batch/{jobId}:
get:
operationId: getBatchStatus
summary: Get Batch Job Status
tags:
- Screenshot
parameters:
- name: jobId
in: path
required: true
schema:
type: string
responses:
'200':
description: Batch job status with results
'404':
description: Job not found or expired
/v1/screenshot/async/{jobId}:
get:
operationId: getAsyncStatus
summary: Get Async Screenshot Status
tags:
- Screenshot
parameters:
- name: jobId
in: path
required: true
schema:
type: string
- name: includeData
in: query
schema:
type: string
enum:
- 'true'
- 'false'
description: Include base64 data in response
responses:
'200':
description: Async job status
'404':
description: Job not found or expired
components:
schemas:
ScreenshotJsonResponse:
type: object
properties:
success:
type: boolean
example: true
cached:
type: boolean
data:
type: string
description: Base64-encoded image data
format:
type: string
example: png
width:
type: integer
example: 1280
height:
type: integer
example: 800
fileSize:
type: integer
took:
type: integer
description: Response time in ms
metadata:
type: object
storage:
type: object
properties:
id:
type: string
url:
type: string
BatchRequest:
type: object
required:
- urls
properties:
urls:
type: array
items:
type: string
format: uri
minItems: 1
maxItems: 100
format:
type: string
enum:
- png
- jpeg
- webp
- avif
- pdf
default: png
quality:
type: integer
default: 80
width:
type: integer
default: 1280
height:
type: integer
default: 800
fullPage:
type: boolean
default: false
darkMode:
type: boolean
default: false
blockAds:
type: boolean
default: false
blockCookieBanners:
type: boolean
default: false
webhookUrl:
type: string
format: uri
ScreenshotRequest:
type: object
properties:
url:
type: string
format: uri
example: https://example.com
html:
type: string
maxLength: 5000000
description: Raw HTML to render
markdown:
type: string
maxLength: 1000000
description: Markdown to render
format:
type: string
enum:
- png
- jpeg
- webp
- avif
- pdf
default: png
quality:
type: integer
minimum: 1
maximum: 100
default: 80
device:
type: string
enum:
- desktop-1080p
- desktop-1440p
- desktop-4k
- macbook-pro-13
- macbook-pro-16
- imac-24
- iphone-12
- iphone-13
- iphone-14
- iphone-14-pro
- iphone-15
- iphone-15-pro
- iphone-15-pro-max
- iphone-se
- ipad
- ipad-mini
- ipad-air
- ipad-pro-11
- ipad-pro-12.9
- pixel-7
- pixel-8
- pixel-8-pro
- samsung-galaxy-s23
- samsung-galaxy-s24
- samsung-galaxy-tab-s9
width:
type: integer
minimum: 100
maximum: 3840
default: 1280
height:
type: integer
minimum: 100
maximum: 2160
default: 800
deviceScaleFactor:
type: number
minimum: 1
maximum: 3
default: 1
isMobile:
type: boolean
default: false
hasTouch:
type: boolean
default: false
isLandscape:
type: boolean
default: false
fullPage:
type: boolean
default: false
fullPageScrollDelay:
type: integer
default: 400
fullPageMaxHeight:
type: integer
maximum: 50000
selector:
type: string
description: CSS selector to capture specific element
clipX:
type: integer
clipY:
type: integer
clipWidth:
type: integer
clipHeight:
type: integer
delay:
type: integer
minimum: 0
maximum: 30000
default: 0
timeout:
type: integer
minimum: 1000
maximum: 60000
default: 30000
waitUntil:
type: string
enum:
- load
- domcontentloaded
- networkidle
default: load
waitForSelector:
type: string
darkMode:
type: boolean
default: false
reducedMotion:
type: boolean
default: false
css:
type: string
maxLength: 100000
description: Custom CSS (Starter+)
javascript:
type: string
maxLength: 100000
description: Custom JS (Pro+)
hideSelectors:
type: array
items:
type: string
maxItems: 50
clickSelector:
type: string
clickDelay:
type: integer
blockAds:
type: boolean
default: false
description: Block ads (Starter+)
blockTrackers:
type: boolean
default: false
description: Block trackers (Pro+)
blockCookieBanners:
type: boolean
default: false
blockChatWidgets:
type: boolean
default: false
blockResources:
type: array
items:
type: string
enum:
- document
- stylesheet
- image
- media
- font
- script
- xhr
- fetch
- websocket
userAgent:
type: string
extraHeaders:
type: object
additionalProperties:
type: string
cookies:
type: array
items:
type: object
properties:
name:
type: string
value:
type: string
domain:
type: string
path:
type: string
httpAuth:
type: object
properties:
username:
type: string
password:
type: string
proxy:
type: object
properties:
server:
type: string
format: uri
username:
type: string
password:
type: string
geolocation:
type: object
properties:
latitude:
type: number
longitude:
type: number
accuracy:
type: number
timezone:
type: string
example: America/New_York
locale:
type: string
example: en-US
pdfOptions:
type: object
properties:
pageSize:
type: string
enum:
- a4
- a3
- a5
- letter
- legal
- tabloid
- custom
landscape:
type: boolean
printBackground:
type: boolean
scale:
type: number
minimum: 0.1
maximum: 2
marginTop:
type: string
marginBottom:
type: string
marginLeft:
type: string
marginRight:
type: string
headerTemplate:
type: string
footerTemplate:
type: string
displayHeaderFooter:
type: boolean
pageRanges:
type: string
thumbnail:
type: object
properties:
enabled:
type: boolean
width:
type: integer
height:
type: integer
fit:
type: string
enum:
- cover
- contain
- fill
failOnHttpError:
type: boolean
default: false
failIfContentMissing:
type: array
items:
type: string
failIfContentContains:
type: array
items:
type: string
cache:
type: boolean
default: false
description: Enable caching (Pro+)
cacheTtl:
type: integer
minimum: 60
maximum: 2592000
default: 86400
responseType:
type: string
enum:
- binary
- base64
- json
default: binary
includeMetadata:
type: boolean
default: false
extractMetadata:
type: object
properties:
fonts:
type: boolean
colors:
type: boolean
links:
type: boolean
httpStatusCode:
type: boolean
storage:
type: object
properties:
enabled:
type: boolean
destination:
type: string
enum:
- snapapi
- user_s3
async:
type: boolean
default: false
webhookUrl:
type: string
format: uri
webhookHeaders:
type: object
additionalProperties:
type: string
AsyncJobResponse:
type: object
properties:
success:
type: boolean
async:
type: boolean
jobId:
type: string
status:
type: string
enum:
- pending
- processing
- completed
- failed
statusUrl:
type: string
Error:
type: object
properties:
statusCode:
type: integer
error:
type: string
message:
type: string
headers:
X-RateLimit-Reset:
schema:
type: integer
description: Window reset time (unix ms)
X-Request-Id:
schema:
type: string
description: Unique request identifier for debugging
X-RateLimit-Limit:
schema:
type: integer
description: Max requests per window
X-RateLimit-Remaining:
schema:
type: integer
description: Remaining requests
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: x-api-key
description: Your SnapAPI API key
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: JWT access token obtained from /auth/login or /auth/refresh