Sahifa Screenshots API
Screenshots of a URL or HTML, ScreenshotOne compatible
Screenshots of a URL or HTML, ScreenshotOne compatible
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/sahifa:sahifa-screenshots-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Sahifa Screenshots API
version: 1.0.0
summary: HTML to PDF and screenshot API hosted in Saudi Arabia
description: HTML to PDF and screenshot API hosted in Jeddah, Saudi Arabia.
termsOfService: https://sahifa.dev/en/terms
contact:
name: Sahifa support
email: support@sahifa.dev
url: https://sahifa.dev/en/contact
license:
name: Proprietary
url: https://sahifa.dev/en/terms
x-provider: Yimello LLC (United Arab Emirates)
x-data-residency:
country: SA
region: me-jeddah-1
storage: none
frameworks:
- SAMA Cyber Security Framework
- Saudi PDPL
dpa: https://sahifa.dev/en/dpa
details: https://sahifa.dev/en/data-residency
x-pricing: https://sahifa.dev/en/pricing
x-changelog: https://sahifa.dev/en/docs/changelog
x-status: https://stats.uptimerobot.com/5fFpK4UvT9
servers:
- url: https://api.sahifa.dev
description: Production, Jeddah, Saudi Arabia (me-jeddah-1)
security:
- apiKeyHeader: []
tags:
- name: Screenshots
description: Screenshots of a URL or HTML, ScreenshotOne compatible
externalDocs:
url: https://sahifa.dev/en/docs/screenshot
paths:
/take:
get:
operationId: takeScreenshot
tags:
- Screenshots
summary: Screenshot of a URL or HTML (ScreenshotOne compatible)
description: 'Captures a public URL or an HTML document and returns the image (or PDF). Nothing is stored. Retrying is safe: a render has no side effects and nothing is stored, so a repeated request never creates a duplicate. Retry 408, 429 and 503 with an increasing wait (for example 2, 4 and 8 seconds); do not retry other 4xx errors.'
security:
- apiKeyHeader: []
- accessKey: []
x-idempotent: true
parameters:
- name: url
in: query
required: false
schema:
type: string
format: uri
description: Public http(s) address to capture. Send exactly one of url and html.
description: Public http(s) address to capture. Send exactly one of url and html.
example: https://example.com
- name: html
in: query
required: false
schema:
type: string
description: HTML document to capture.
description: HTML document to capture.
- name: format
in: query
required: false
schema:
type: string
enum:
- png
- jpeg
- jpg
- webp
- pdf
default: png
description: ''
example: png
- name: image_quality
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
description: For jpeg and webp.
description: For jpeg and webp.
- name: omit_background
in: query
required: false
schema:
type: boolean
description: ''
- name: full_page
in: query
required: false
schema:
type: boolean
description: ''
example: true
- name: viewport_width
in: query
required: false
schema:
type: integer
default: 1280
maximum: 10000
description: ''
- name: viewport_height
in: query
required: false
schema:
type: integer
default: 720
maximum: 10000
description: ''
- name: device_scale_factor
in: query
required: false
schema:
type: number
default: 1
minimum: 0.1
maximum: 4
description: ''
- name: selector
in: query
required: false
schema:
type: string
description: CSS selector of one element to capture; 404 if nothing matches.
description: CSS selector of one element to capture; 404 if nothing matches.
- name: clip_x
in: query
required: false
schema:
type: integer
description: ''
- name: clip_y
in: query
required: false
schema:
type: integer
description: ''
- name: clip_width
in: query
required: false
schema:
type: integer
description: ''
- name: clip_height
in: query
required: false
schema:
type: integer
description: ''
- name: dark_mode
in: query
required: false
schema:
type: boolean
description: ''
- name: reduced_motion
in: query
required: false
schema:
type: boolean
description: ''
- name: user_agent
in: query
required: false
schema:
type: string
description: ''
- name: authorization
in: query
required: false
schema:
type: string
description: Authorization header sent to the page.
description: Authorization header sent to the page.
- name: headers
in: query
required: false
schema:
type: array
items:
type: string
description: Name=value pairs.
description: Name=value pairs.
- name: cookies
in: query
required: false
schema:
type: array
items:
type: string
description: name=value pairs.
description: name=value pairs.
- name: delay
in: query
required: false
schema:
type: number
minimum: 0
maximum: 30
description: Seconds.
description: Seconds.
- name: timeout
in: query
required: false
schema:
type: number
minimum: 1
maximum: 100
description: Seconds; capped at 30.
description: Seconds; capped at 30.
- name: wait_until
in: query
required: false
schema:
type: string
enum:
- load
- domcontentloaded
- networkidle
- commit
default: load
description: ''
- name: wait_for_selector
in: query
required: false
schema:
type: string
description: ''
- name: response_type
in: query
required: false
schema:
type: string
enum:
- by_format
- json
default: by_format
description: ''
- name: cache
in: query
required: false
schema:
type: boolean
description: Accepted and ignored.
description: Accepted and ignored.
- name: block_ads
in: query
required: false
schema:
type: boolean
description: ''
- name: block_trackers
in: query
required: false
schema:
type: boolean
description: ''
- name: block_cookie_banners
in: query
required: false
schema:
type: boolean
description: ''
- name: block_chats
in: query
required: false
schema:
type: boolean
description: ''
- name: hide_selectors
in: query
required: false
schema:
type: array
items:
type: string
description: ''
- name: block_requests
in: query
required: false
schema:
type: array
items:
type: string
description: URL patterns, * as wildcard.
description: URL patterns, * as wildcard.
- name: block_resources
in: query
required: false
schema:
type: array
items:
type: string
enum:
- image
- font
- media
- script
- stylesheet
- xhr
- fetch
- websocket
- other
- document
description: ''
responses:
'200':
$ref: '#/components/responses/Screenshot'
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Selector not found
'400':
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: source is required
'401':
description: Missing or invalid API key
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Invalid or missing API key
'402':
description: Monthly render allowance used up
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Monthly render allowance used up
'408':
description: 'Rendering timed out. Retrying is safe: a render has no side effects and nothing is stored, so a repeated request never creates a duplicate. Retry 408, 429 and 503 with an increasing wait (for example 2, 4 and 8 seconds); do not retry other 4xx errors.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Rendering timed out
'413':
description: Request body over 10 MB
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Request body too large
'429':
description: 'Render queue full. Retrying is safe: a render has no side effects and nothing is stored, so a repeated request never creates a duplicate. Retry 408, 429 and 503 with an increasing wait (for example 2, 4 and 8 seconds); do not retry other 4xx errors.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Render queue full, retry shortly
'500':
description: Rendering error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Rendering failed
'503':
description: 'Temporarily unavailable. Retrying is safe: a render has no side effects and nothing is stored, so a repeated request never creates a duplicate. Retry 408, 429 and 503 with an increasing wait (for example 2, 4 and 8 seconds); do not retry other 4xx errors.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Service temporarily unavailable
post:
operationId: takeScreenshotPost
tags:
- Screenshots
summary: Screenshot with a JSON body
description: 'Same as GET /take, with the options in a JSON body; use it for long HTML. Retrying is safe: a render has no side effects and nothing is stored, so a repeated request never creates a duplicate. Retry 408, 429 and 503 with an increasing wait (for example 2, 4 and 8 seconds); do not retry other 4xx errors.'
security:
- apiKeyHeader: []
- accessKey: []
x-idempotent: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
url:
type: string
format: uri
description: Public http(s) address to capture. Send exactly one of url and html.
html:
type: string
description: HTML document to capture.
format:
type: string
enum:
- png
- jpeg
- jpg
- webp
- pdf
default: png
image_quality:
type: integer
minimum: 1
maximum: 100
description: For jpeg and webp.
omit_background:
type: boolean
full_page:
type: boolean
viewport_width:
type: integer
default: 1280
maximum: 10000
viewport_height:
type: integer
default: 720
maximum: 10000
device_scale_factor:
type: number
default: 1
minimum: 0.1
maximum: 4
selector:
type: string
description: CSS selector of one element to capture; 404 if nothing matches.
clip_x:
type: integer
clip_y:
type: integer
clip_width:
type: integer
clip_height:
type: integer
dark_mode:
type: boolean
reduced_motion:
type: boolean
user_agent:
type: string
authorization:
type: string
description: Authorization header sent to the page.
headers:
type: array
items:
type: string
description: Name=value pairs.
cookies:
type: array
items:
type: string
description: name=value pairs.
delay:
type: number
minimum: 0
maximum: 30
description: Seconds.
timeout:
type: number
minimum: 1
maximum: 100
description: Seconds; capped at 30.
wait_until:
type: string
enum:
- load
- domcontentloaded
- networkidle
- commit
default: load
wait_for_selector:
type: string
response_type:
type: string
enum:
- by_format
- json
default: by_format
cache:
type: boolean
description: Accepted and ignored.
block_ads:
type: boolean
block_trackers:
type: boolean
block_cookie_banners:
type: boolean
block_chats:
type: boolean
hide_selectors:
type: array
items:
type: string
block_requests:
type: array
items:
type: string
description: URL patterns, * as wildcard.
block_resources:
type: array
items:
type: string
enum:
- image
- font
- media
- script
- stylesheet
- xhr
- fetch
- websocket
- other
- document
examples:
url:
summary: Full-page PNG of a web page, cookie banners hidden
value:
url: https://example.com
format: png
viewport_width: 1280
viewport_height: 720
full_page: true
block_cookie_banners: true
html:
summary: HTML to JPEG, JSON response
value:
html: <h1 dir="rtl">مرحبًا</h1>
format: jpeg
image_quality: 85
response_type: json
responses:
'200':
$ref: '#/components/responses/Screenshot'
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Selector not found
'400':
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: source is required
'401':
description: Missing or invalid API key
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Invalid or missing API key
'402':
description: Monthly render allowance used up
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Monthly render allowance used up
'408':
description: 'Rendering timed out. Retrying is safe: a render has no side effects and nothing is stored, so a repeated request never creates a duplicate. Retry 408, 429 and 503 with an increasing wait (for example 2, 4 and 8 seconds); do not retry other 4xx errors.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Rendering timed out
'413':
description: Request body over 10 MB
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Request body too large
'429':
description: 'Render queue full. Retrying is safe: a render has no side effects and nothing is stored, so a repeated request never creates a duplicate. Retry 408, 429 and 503 with an increasing wait (for example 2, 4 and 8 seconds); do not retry other 4xx errors.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Render queue full, retry shortly
'500':
description: Rendering error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Rendering failed
'503':
description: 'Temporarily unavailable. Retrying is safe: a render has no side effects and nothing is stored, so a repeated request never creates a duplicate. Retry 408, 429 and 503 with an increasing wait (for example 2, 4 and 8 seconds); do not retry other 4xx errors.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: Service temporarily unavailable
components:
responses:
Screenshot:
description: The image or PDF, or JSON when response_type=json
headers:
X-Response-Duration:
schema:
type: integer
description: Render time in milliseconds
X-Quota-Limit:
schema:
type: integer
description: Monthly render allowance of the key
X-Quota-Remaining:
schema:
type: integer
description: Renders left this month before this request
X-Quota-Daily-Limit:
schema:
type: integer
description: 'Sandbox keys only: daily render allowance'
X-Quota-Daily-Remaining:
schema:
type: integer
description: 'Sandbox keys only: renders left today'
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:
type: object
properties:
success:
type: boolean
content_type:
type: string
data:
type: string
contentEncoding: base64
size:
type: integer
example:
success: true
content_type: image/png
data: iVBORw0KGgoAAAANSUhEUgAA...
size: 48211
schemas:
Error:
type: object
required:
- success
- error
properties:
success:
type: boolean
const: false
error:
type: string
description: Human-readable reason
securitySchemes:
apiKeyHeader:
type: apiKey
in: header
name: X-API-Key
description: Your API key, from https://sahifa.dev/en/account. Works on every endpoint.
basicAuth:
type: http
scheme: basic
description: 'PDFShift compatibility, /v3/convert/pdf only: user ''api'', password = your API key.'
accessKey:
type: apiKey
in: query
name: access_key
description: ScreenshotOne compatibility, /take only.
externalDocs:
description: Documentation
url: https://sahifa.dev/en/docs
x-provenance:
method: harvested
publisher: Sahifa
source: https://sahifa.dev/docs/openapi.json
note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
stamped by stamp-openapi-provenance.py (roadmap#793)