Screenshot -- Node.js / TypeScript SDK
Official Node.js SDK for the Nodium Screenshot API. Supports Node.js 18+ and all modern runtimes (Deno, Bun).
Installation
npm install @nodium/screenshot# or with yarn
yarn add @nodium/screenshot
# or with pnpm
pnpm add @nodium/screenshotQuick Start
import { NodiumScreenshot } from "@nodium/screenshot";
const client = new NodiumScreenshot("YOUR_API_KEY");
const screenshot = await client.take({
url: "https://example.com",
format: "png",
});
// screenshot.data is a Buffer containing the PNG image
fs.writeFileSync("screenshot.png", screenshot.data);Client Initialization
import { NodiumScreenshot } from "@nodium/screenshot";
// Basic initialization
const client = new NodiumScreenshot("YOUR_API_KEY");
// With options
const client = new NodiumScreenshot("YOUR_API_KEY", {
baseUrl: "https://api.nodium.io/api/v1/screenshot",
timeout: 60_000, // Request timeout in milliseconds (default: 60000)
retries: 3, // Automatic retries on 5xx errors (default: 3)
retryDelay: 1000, // Base delay between retries in ms (default: 1000)
});Environment Variable
You can also set your API key via the NODIUM_API_KEY environment variable:
// Reads from process.env.NODIUM_API_KEY automatically
const client = new NodiumScreenshot();Methods
take(params) -- Capture a Screenshot
Takes a screenshot of a URL, HTML, or Markdown content.
const result = await client.take({
url: "https://example.com",
format: "png",
viewport_width: 1280,
viewport_height: 1024,
full_page: true,
image_quality: 90,
});
// result.data -- Buffer with image/PDF bytes
// result.headers -- Response headers (rendering time, size, reference ID)animate(params) -- Record an Animated Screenshot
Records a scroll animation or interaction video.
const result = await client.animate({
url: "https://example.com",
format: "mp4",
scroll_animation: "smooth",
animation_duration: 5,
viewport_width: 1280,
viewport_height: 720,
});
fs.writeFileSync("animation.mp4", result.data);bulk(params) -- Batch Capture
Capture multiple URLs in a single request.
const results = await client.bulk({
urls: [
"https://example.com",
"https://example.org",
"https://example.net",
],
format: "png",
viewport_width: 1280,
viewport_height: 1024,
});
results.forEach((result, index) => {
fs.writeFileSync(`screenshot-${index}.png`, result.data);
});getUsage() -- Check API Usage
Returns your current billing period usage.
const usage = await client.getUsage();
console.log(`Screenshots taken: ${usage.screenshots_taken}`);
console.log(`Monthly limit: ${usage.monthly_limit}`);
console.log(`Remaining: ${usage.remaining}`);
console.log(`Billing period ends: ${usage.period_end}`);Fluent Builder API
Every method supports a fluent builder pattern for a more readable configuration style.
const result = await client
.take()
.url("https://example.com")
.format("png")
.viewport(1280, 1024)
.fullPage(true)
.imageQuality(90)
.execute();
fs.writeFileSync("screenshot.png", result.data);Builder Methods
| Method | Description |
|---|---|
.url(url) | Target URL to capture |
.html(html) | Raw HTML to render |
.markdown(md) | Markdown content to render |
.format(fmt) | Output format: png, jpeg, webp, avif, pdf, etc. |
.viewport(width, height) | Viewport dimensions |
.viewportDevice(device) | Device emulation (e.g. iphone_16_pro) |
.fullPage(bool) | Capture the entire scrollable page |
.imageQuality(n) | JPEG/WebP quality (1-100) |
.selector(css) | Capture a specific CSS selector |
.delay(ms) | Wait before capture (milliseconds) |
.blockAds(bool) | Block ads and trackers |
.darkMode(bool) | Force dark color scheme |
.responseType(type) | by_format, json, or empty |
.webhook(url) | Webhook URL for async delivery |
.execute() | Execute the request and return the result |
Chaining Example
const pdf = await client
.take()
.url("https://example.com/report")
.format("pdf")
.fullPage(true)
.viewport(1440, 900)
.delay(2000)
.blockAds(true)
.execute();
fs.writeFileSync("report.pdf", pdf.data);TypeScript Types
The SDK ships with full TypeScript definitions out of the box.
import {
NodiumScreenshot,
ScreenshotParams,
AnimateParams,
BulkParams,
ScreenshotResult,
UsageResult,
NodiumError,
ImageFormat,
VideoFormat,
ResponseType,
} from "@nodium/screenshot";
// Typed parameters
const params: ScreenshotParams = {
url: "https://example.com",
format: "png",
viewport_width: 1280,
viewport_height: 1024,
full_page: true,
};
// Typed result
const result: ScreenshotResult = await client.take(params);Key Types
type ImageFormat = "png" | "jpeg" | "webp" | "avif" | "heif" | "tiff" | "jp2" | "gif";
type VideoFormat = "mp4" | "webm" | "gif" | "mov" | "avi";
type DocumentFormat = "pdf" | "html" | "markdown";
type ResponseType = "by_format" | "json" | "empty";
interface ScreenshotParams {
url?: string;
html?: string;
markdown?: string;
format: ImageFormat | DocumentFormat;
viewport_width?: number;
viewport_height?: number;
full_page?: boolean;
image_quality?: number;
selector?: string;
delay?: number;
response_type?: ResponseType;
webhook_url?: string;
// ... 145+ additional parameters
}
interface ScreenshotResult {
data: Buffer;
headers: {
renderingSeconds: number;
sizeBytes: number;
reference: string;
traceId: string;
cacheUrl?: string;
};
}Error Handling
The SDK throws typed NodiumError instances for all API errors.
import { NodiumError } from "@nodium/screenshot";
try {
const result = await client.take({
url: "https://example.com",
format: "png",
});
fs.writeFileSync("screenshot.png", result.data);
} catch (error) {
if (error instanceof NodiumError) {
console.error(`Error code: ${error.code}`); // e.g. "request_not_valid"
console.error(`Message: ${error.message}`); // Human-readable description
console.error(`HTTP status: ${error.httpStatus}`); // e.g. 400
console.error(`Retryable: ${error.isRetryable}`); // true for 5xx errors
if (error.code === "screenshots_limit_reached") {
console.error("Monthly quota exceeded. Upgrade your plan.");
}
} else {
// Network error, timeout, etc.
console.error("Unexpected error:", error);
}
}Error Codes
| Code | HTTP Status | Retryable |
|---|---|---|
access_key_required | 400 | No |
access_key_invalid | 400 | No |
request_not_valid | 400 | No |
screenshots_limit_reached | 400 | No |
concurrency_limit_reached | 400 | No |
timeout_error | 500 | Yes |
network_error | 500 | Yes |
internal_application_error | 500 | Yes |
temporary_unavailable | 503 | Yes |
Webhook Integration
For long-running captures, use webhooks to receive results asynchronously.
// The API will POST the result to your webhook URL instead of returning it
const result = await client.take({
url: "https://example.com",
format: "png",
webhook_url: "https://your-app.com/api/webhooks/screenshot",
response_type: "json",
});
// result contains the reference ID immediately
console.log(`Queued: ${result.headers.reference}`);Express Webhook Handler
import express from "express";
const app = express();
app.use(express.json());
app.post("/api/webhooks/screenshot", (req, res) => {
const { screenshot_url, metadata, reference } = req.body;
console.log(`Screenshot ready: ${screenshot_url}`);
console.log(`Page title: ${metadata.page_title}`);
console.log(`Size: ${metadata.image_size.width}x${metadata.image_size.height}`);
// Download and process the screenshot
// ...
res.sendStatus(200);
});
app.listen(3000);Signed URL Generation
Generate pre-signed URLs that allow third parties to take screenshots without exposing your API key.
const signedUrl = client.generateSignedUrl({
url: "https://example.com",
format: "png",
viewport_width: 1280,
viewport_height: 1024,
expires_in: 3600, // URL valid for 1 hour
});
console.log(signedUrl);
// https://api.nodium.io/api/v1/screenshot/take?url=...&signature=...&expires=...Use Case: Client-Side Screenshots
// Server-side: generate a signed URL
app.get("/api/screenshot-url", (req, res) => {
const signedUrl = client.generateSignedUrl({
url: req.query.url as string,
format: "png",
expires_in: 300,
});
res.json({ url: signedUrl });
});
// Client-side: use the signed URL directly in an <img> tag
// <img src="{signedUrl}" alt="Screenshot" />Advanced Configuration
Custom HTTP Client
Provide a custom fetch implementation for special environments.
import { NodiumScreenshot } from "@nodium/screenshot";
import { fetch as undiciFetch } from "undici";
const client = new NodiumScreenshot("YOUR_API_KEY", {
fetch: undiciFetch,
});Proxy Configuration
Route requests through an HTTP or SOCKS proxy.
import { ProxyAgent } from "undici";
const proxyAgent = new ProxyAgent("http://proxy.example.com:8080");
const client = new NodiumScreenshot("YOUR_API_KEY", {
dispatcher: proxyAgent,
});Timeout Configuration
const client = new NodiumScreenshot("YOUR_API_KEY", {
timeout: 120_000, // 2 minutes for complex pages
retries: 5, // More retries for unreliable networks
retryDelay: 2000, // 2 second base delay between retries
});Full Example
A complete example that captures a screenshot, saves it to disk, and handles all error scenarios.
import { NodiumScreenshot, NodiumError } from "@nodium/screenshot";
import fs from "node:fs";
import path from "node:path";
async function captureAndSave(targetUrl: string, outputPath: string) {
const client = new NodiumScreenshot(process.env.NODIUM_API_KEY);
try {
// Check usage before capturing
const usage = await client.getUsage();
if (usage.remaining <= 0) {
console.error("No screenshots remaining this billing period.");
process.exit(1);
}
console.log(`Remaining quota: ${usage.remaining}/${usage.monthly_limit}`);
// Take the screenshot using the fluent builder
const result = await client
.take()
.url(targetUrl)
.format("png")
.viewport(1440, 900)
.fullPage(true)
.blockAds(true)
.delay(1000)
.imageQuality(95)
.execute();
// Ensure the output directory exists
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
// Write the screenshot to disk
fs.writeFileSync(outputPath, result.data);
console.log(`Screenshot saved to ${outputPath}`);
console.log(`Rendering time: ${result.headers.renderingSeconds}s`);
console.log(`File size: ${(result.headers.sizeBytes / 1024).toFixed(1)} KB`);
console.log(`Reference: ${result.headers.reference}`);
} catch (error) {
if (error instanceof NodiumError) {
console.error(`API error [${error.code}]: ${error.message}`);
if (error.isRetryable) {
console.error("This error is retryable. The SDK already retried automatically.");
}
} else {
console.error("Unexpected error:", error);
}
process.exit(1);
}
}
// Run
captureAndSave("https://example.com", "./output/screenshot.png");Next Steps
- API Reference -- Complete reference for all 145+ parameters
- Guides -- Practical guides for common use cases
- Getting Started -- Quick intro and cURL examples