Screenshot — Getting Started
Prerequisites: Make sure you have created an account and API key first.
Introduction
Nodium Screenshot API is a high-performance web capture service that converts any URL, raw HTML, or Markdown into pixel-perfect screenshots, PDFs, and videos via a simple REST API.
What you can do:
- Capture any public or authenticated web page as PNG, JPEG, WebP, AVIF, or other image formats
- Render raw HTML or Markdown content into images
- Generate PDFs with full control over paper size, margins, and orientation
- Record animated scroll videos as MP4, WebM, or GIF
- Extract page metadata (Open Graph, fonts, favicon, HTTP headers)
- Analyze screenshots with OpenAI Vision
Base URL:
https://api.nodium.io/api/v1/screenshotAuthentication
Every request requires an API key. Obtain your key from the Nodium Dashboard under API Keys. Enable the screenshot scope when creating or editing the key.
There are three ways to provide your API key:
1. Query parameter
?access_key=YOUR_API_KEY2. HTTP header
X-Access-Key: YOUR_API_KEY3. JSON body (POST only)
{
"access_key": "YOUR_API_KEY",
"url": "https://example.com"
}Security recommendation: Use the HTTP header method for production applications. Avoid placing your API key in query strings that may appear in server logs or browser history. For public-facing integrations, use signed URLs.
Your First Screenshot
Capture a screenshot of example.com in one line:
curl "https://api.nodium.io/api/v1/screenshot/take?access_key=YOUR_API_KEY&url=https://example.com&format=png" \
-o screenshot.pngThe API returns the raw image bytes. Open screenshot.png to see the result.
Code Examples
cURL
# Basic screenshot
curl "https://api.nodium.io/api/v1/screenshot/take?access_key=YOUR_API_KEY&url=https://example.com&format=png" \
-o screenshot.png
# Full-page screenshot with custom viewport
curl -X POST "https://api.nodium.io/api/v1/screenshot/take" \
-H "Content-Type: application/json" \
-H "X-Access-Key: YOUR_API_KEY" \
-d '{
"url": "https://example.com",
"format": "jpeg",
"full_page": true,
"viewport_width": 1440,
"viewport_height": 900,
"image_quality": 90
}' \
-o fullpage.jpg
# Mobile device emulation
curl "https://api.nodium.io/api/v1/screenshot/take?access_key=YOUR_API_KEY&url=https://example.com&format=webp&viewport_device=iphone_16_pro" \
-o mobile.webpNode.js (fetch)
const fs = require("fs");
async function takeScreenshot() {
const response = await fetch(
"https://api.nodium.io/api/v1/screenshot/take",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Access-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
url: "https://example.com",
format: "png",
viewport_width: 1280,
viewport_height: 1024,
}),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(`${error.error_code}: ${error.message}`);
}
const buffer = Buffer.from(await response.arrayBuffer());
fs.writeFileSync("screenshot.png", buffer);
console.log("Screenshot saved!");
}
takeScreenshot();Python (requests)
import requests
response = requests.get(
"https://api.nodium.io/api/v1/screenshot/take",
params={
"access_key": "YOUR_API_KEY",
"url": "https://example.com",
"format": "png",
"viewport_width": 1280,
"viewport_height": 1024,
},
)
if response.status_code == 200:
with open("screenshot.png", "wb") as f:
f.write(response.content)
print("Screenshot saved!")
else:
error = response.json()
print(f"Error: {error['error_code']} - {error['message']}")PHP (curl)
<?php
$params = http_build_query([
'access_key' => 'YOUR_API_KEY',
'url' => 'https://example.com',
'format' => 'png',
'viewport_width' => 1280,
'viewport_height'=> 1024,
]);
$ch = curl_init("https://api.nodium.io/api/v1/screenshot/take?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
file_put_contents('screenshot.png', $response);
echo "Screenshot saved!\n";
} else {
$error = json_decode($response, true);
echo "Error: {$error['error_code']} - {$error['message']}\n";
}Output Formats
Image Formats
| Format | format= | Transparency | Compression | Best For |
|---|---|---|---|---|
| PNG | png | Yes | Lossless | UI screenshots, pixel-perfect captures |
| JPEG | jpeg | No | Lossy | Photos, general-purpose, smaller files |
| WebP | webp | Yes | Both | Web delivery, best size/quality ratio |
| AVIF | avif | Yes | Lossy | Maximum compression, modern browsers |
| HEIF | heif | Yes | Lossy | Apple ecosystem |
| TIFF | tiff | Yes | Lossless | Print, archival |
| JP2 | jp2 | Yes | Both | High-quality archival |
| GIF | gif | Yes | Lossless | Simple graphics (static; use /animate for animated) |
Document Formats
| Format | format= | Best For |
|---|---|---|
pdf | Reports, invoices, printable documents | |
| HTML | html | Extracting rendered HTML source |
| Markdown | markdown | Content extraction in Markdown format |
Video Formats (endpoint /animate only)
| Format | format= | Best For |
|---|---|---|
| MP4 | mp4 | Universal video playback |
| WebM | webm | Web-optimized video |
| GIF | gif | Social media, email embeds |
| MOV | mov | Apple ecosystem, transparent background support |
| AVI | avi | Legacy systems |
Response Types
Control what the API returns with the response_type parameter:
| Value | Content-Type | Description |
|---|---|---|
by_format (default) | Matches format (e.g. image/png) | Returns the raw binary file (image, PDF, or video) |
json | application/json | Returns JSON with screenshot URL, metadata, and cache info |
empty | none | Returns only HTTP status and headers (fastest) |
JSON response example
{
"screenshot_url": "https://cdn.nodium.io/screenshots/abc123.png",
"cache_url": "https://cdn.nodium.io/cache/abc123.png",
"metadata": {
"image_size": { "width": 1280, "height": 1024 },
"page_title": "Example Domain"
}
}Response headers
Every response includes informational headers:
| Header | Description |
|---|---|
x-nodium-rendering-seconds | Time spent rendering (e.g. 2.34) |
x-nodium-size-bytes | Output file size in bytes |
x-nodium-reference | Unique screenshot reference ID |
x-nodium-trace-id | Trace ID for debugging |
x-nodium-cache-url | URL to the cached screenshot (if caching enabled) |
Error Handling
Error response format
When an error occurs, the API returns a JSON body regardless of response_type:
{
"error_code": "request_not_valid",
"message": "The request parameters are not valid. Check the request body or query string.",
"http_status_code": 400
}Common error codes
| Error Code | HTTP Status | Cause |
|---|---|---|
access_key_required | 400 | Missing API key |
access_key_invalid | 400 | Invalid or revoked API key |
request_not_valid | 400 | Invalid parameters |
screenshots_limit_reached | 400 | Monthly quota exceeded |
concurrency_limit_reached | 400 | Too many simultaneous requests |
timeout_error | 500 | Page took too long to load |
network_error | 500 | Cannot reach the target URL |
internal_application_error | 500 | Server error (safe to retry) |
temporary_unavailable | 503 | Service overloaded (safe to retry) |
Retry strategy
For production applications, implement exponential backoff on retryable errors:
- Retry on:
500(internal_application_error,network_error,timeout_error) and503(temporary_unavailable) - Do not retry on:
400errors (fix the request first) - Recommended: 3 retries with delays of 1s, 2s, 4s
async function takeScreenshotWithRetry(params, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(
"https://api.nodium.io/api/v1/screenshot/take",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Access-Key": "YOUR_API_KEY",
},
body: JSON.stringify(params),
}
);
if (response.ok) return response;
const error = await response.json();
// Do not retry client errors
if (response.status < 500) throw new Error(error.message);
// Exponential backoff
if (attempt < maxRetries) {
await new Promise((r) => setTimeout(r, 1000 * Math.pow(2, attempt)));
}
}
throw new Error("Max retries exceeded");
}Next Steps
Now that you know the basics, explore the rest of the documentation:
- API Reference -- Complete reference for all 145+ parameters, endpoints, error codes, and response headers
- Guides -- Practical guides for common use cases: full-page captures, PDF generation, authenticated pages, animated screenshots, webhooks, and more