API Reference
Complete reference for all getSnap.dev endpoints.
Complete endpoint index
30 operations across 27 unique paths. All endpoints live under
https://api.getsnap.dev and require an X-API-Key header
unless noted. The tables below link to detailed reference sections on this page,
the dedicated teams doc and referrals doc,
or the fully interactive Swagger UI.
Your API key is shown once. It appears in the response to
POST /v1/signup and in your welcome email, and nowhere else. We store
only a SHA-256 hash of it, which is enough to recognise the key you send but cannot
be turned back into the key — so nobody, including us, can retrieve it later.
Save it when you receive it. If you lose it, email
support@getsnap.dev and we will revoke the
old key and issue a new one.
Capture (7)
| Endpoint | Method | Description |
|---|---|---|
/v1/screenshot | POST | Capture a screenshot or PDF (sync / async / binary). |
/v1/screenshot/:id | GET | Poll async screenshot status. |
/v1/batch | POST | Batch capture up to 100 URLs in one request. |
/v1/video | POST | Scrolling video (MP4 or GIF), 2–30 seconds. |
/v1/og-image | POST | 1200×630 Open Graph / Twitter Card image with title + subtitle overlay. |
/v1/diff | POST | Visual regression diff between two URLs (pixelmatch). |
/v1/audit | POST | WCAG 2.0/2.1/2.2 accessibility audit (axe-core). |
Signed render links (2)
| Endpoint | Method | Description |
|---|---|---|
/v1/render-link | POST | Generate a signed URL for use in <img> tags. |
/v1/render | GET | Serve screenshot from a signed URL (no auth header needed). |
Scheduled captures (7)
| Endpoint | Method | Description |
|---|---|---|
/v1/schedules | POST | Create a cron-driven scheduled capture. |
/v1/schedules | GET | List your scheduled captures. |
/v1/schedules/:id | GET | Fetch a scheduled capture. |
/v1/schedules/:id | PATCH | Update cron / options / webhook / active flag. |
/v1/schedules/:id | DELETE | Delete a schedule. |
/v1/schedules/:id/run | POST | Trigger a schedule immediately. |
/v1/schedules/:id/runs | GET | Recent execution history (last 100). |
Teams (11) — full reference at /docs/teams.html
| Endpoint | Method | Description |
|---|---|---|
/v1/teams | POST | Create a new team (hoists creator's plan). |
/v1/teams | GET | List teams the caller belongs to. |
/v1/teams/:id/members | GET | List members with roles + join dates. |
/v1/teams/:id/invites | POST | Invite by email (owner / admin). 7-day TTL. |
/v1/teams/accept | POST | Accept an invite token. |
/v1/teams/:id/leave | POST | Leave a team (non-owner). |
/v1/teams/:id/transfer-ownership | POST | Transfer ownership to another member. v1.12 |
/v1/teams/:id | DELETE | Dissolve the team + cancel its Stripe sub. v1.12 |
/v1/teams/:id/checkout | POST | Start Stripe Checkout for team-owned subscription. v1.13 |
/v1/teams/:id/portal | POST | Stripe billing portal for the team. v1.13 |
/v1/teams/:id/billing | GET | Team subscription status + next invoice date. v1.13 |
Personal billing (2)
| Endpoint | Method | Description |
|---|---|---|
/v1/upgrade | POST | Stripe Checkout URL for a paid plan (or portal URL if already subscribed). |
/v1/billing | POST | Stripe billing portal URL for the caller's personal subscription. |
Growth (1) — full reference at /docs/referrals.html
| Endpoint | Method | Description |
|---|---|---|
/v1/referrals | GET | Referral code + share URL + aggregate stats + individual referrals. |
Ops (5)
| Endpoint | Method | Description |
|---|---|---|
/v1/usage | GET | Current-period usage + monthly limit + plan. |
/v1/health | GET | Health check (unauthenticated). |
/v1/signup | POST | Create free account + API key. Optional plan upgrades via Checkout in the same call. |
/v1/contact | POST | Send a support message (rate-limited per IP). |
/v1/webhook/stripe | POST | Stripe webhook receiver (idempotent). Public but signature-verified. |
The authoritative source for every endpoint's request / response schema is the Swagger UI. It's generated from the same Zod schemas that validate every request, so if the docs and the server ever disagree, Swagger UI is right. This page walks through the highest-value capture endpoints in narrative form with runnable examples; jump to Swagger for exhaustive per-field docs.
Capture Screenshot
Captures a screenshot or PDF of a URL or HTML content. Returns either a CDN URL or raw binary data.
Request Headers
| Header | Type | Description |
|---|---|---|
| x-api-key | string required | Your API key |
| Content-Type | string required | Must be application/json |
Request Body
url or html must be provided. You cannot use both in the same request.| Parameter | Type | Default | Description |
|---|---|---|---|
| url | string | - | The URL to capture. Must be a valid HTTP/HTTPS URL. |
| html | string | - | Raw HTML content to render and capture. Max 500KB. Useful for OG images, invoices, email previews. |
| format | string | png | Output format: png, jpg, jpeg, webp, avif, or pdf |
| viewport_width | number | 1280 | Viewport width in pixels (320-3840) |
| viewport_height | number | 720 | Viewport height in pixels (200-2160) |
| full_page | boolean | false | Capture the entire scrollable page |
| device | string | desktop | Device emulation: desktop, mobile, or tablet |
| device_scale_factor | number | 1 | Device pixel ratio (0.5-3). Use 2 for Retina/HiDPI screenshots. |
| delay | number | 0 | Wait time in ms before capture (0-10000). Useful for JS-rendered pages. |
| css | string | "" | Custom CSS to inject before capture (max 10KB) |
| js | string | "" | Custom JavaScript to execute before capture (max 10KB). Runs via page.evaluate(). |
| dark_mode | boolean | false | Emulate prefers-color-scheme: dark |
| quality | number | 80 | Image quality 1-100 (applies to JPG/WebP only) |
| remove_popups | boolean | true | Remove cookie banners, popups, chat widgets, and overlays (90+ selectors) |
| block_ads | boolean | true | Block ad network requests (100+ domains including DoubleClick, Taboola, Outbrain, Criteo, etc.) |
| selector | string | "" | CSS selector to capture a specific element instead of the full page |
| headers | object | {} | Custom HTTP headers to send with the request. Object of key: value string pairs. |
| cookies | array | [] | Cookies to set before navigation. Array of objects with name, value, optional domain, path, httpOnly, secure. Max 50 cookies. |
| locale | string | "" | Browser locale (e.g. de-DE, fr-FR, ja-JP). Affects language headers and JS APIs. |
| timezone | string | "" | IANA timezone ID (e.g. Europe/Berlin, America/New_York). Affects Date objects in page JS. |
| user_agent | string | "" | Custom User-Agent string for the browser request. |
| lazy_load | boolean | false | Auto-scroll the page to trigger lazy-loaded images before capture. Scrolls in 300px increments then returns to top. |
| wait_for_selector | string | "" | CSS selector to wait for before capture (up to 15s). Useful for SPAs and dynamically loaded content. |
| wait_for_network_idle | boolean | true | Wait for network to be idle before capture. Disable for pages with persistent connections. |
| hide_selectors | string[] | [] | Array of CSS selectors to hide (display:none) before capture. E.g. [".banner", "#cookie-popup"] |
| remove_selectors | string[] | [] | Array of CSS selectors to remove from the DOM before capture. Elements are completely deleted. |
| omit_background | boolean | false | Transparent background for PNG screenshots. The page background becomes transparent. |
| click_selector | string | "" | CSS selector to click before capture (e.g. expand a menu). Waits up to 5s for the element. |
| scroll_to_selector | string | "" | CSS selector to scroll into view before capture. |
| extract_text | boolean | false | Extract the page's visible text content (innerText). Returned in extracted_text field. |
| extract_html | boolean | false | Extract the page's full HTML. Returned in extracted_html field. |
| response_type | string | url | url returns CDN link, binary returns raw image/PDF bytes |
| webhook_url | string | - | If provided, the screenshot is captured asynchronously. Returns 202 immediately with a request_id. The result is POSTed to this URL when ready (3 retries, exponential backoff). Use GET /v1/screenshot/:request_id to poll status. |
| s3_upload | object | - | Upload the screenshot to your own S3-compatible bucket. Object with: access_key_id, secret_access_key, bucket, region (required), endpoint (for DO Spaces, R2), path (key prefix), acl (e.g. public-read). |
| Rendering & emulation | |||
| reduced_motion | boolean | false | Emulate prefers-reduced-motion: reduce. Freezes CSS animations and transitions. |
| media_type | string | "" | Emulate CSS media type. "" (default) uses screen; pass print to render as if printing. |
| click_accept | boolean | false | Best-effort auto-click cookie-consent Accept buttons (OneTrust, Cookiebot, FundingChoices, generic "Accept all" heuristics). |
| press_escape | boolean | false | Send an Escape keypress after page load to dismiss modals. |
| bypass_csp | boolean | false | Disable the page's Content-Security-Policy. Required by some pages that block inline CSS/JS injection. |
| fail_if_selector_missing | boolean | false | Return 500 capture_failed when wait_for_selector, click_selector, scroll_to_selector, or selector can't be found. By default missing selectors are silently ignored. |
| Request blocking | |||
| block_images | boolean | false | Abort all image requests. Great for text-heavy captures and speed. |
| block_fonts | boolean | false | Abort all web-font requests. |
| block_scripts | boolean | false | Abort all <script> requests (renders a JS-free version of the page). |
| block_frames | boolean | false | Abort all <iframe> requests. |
| block_urls | string[] | [] | Array of URL substrings or wildcard patterns to block (e.g. ["*.chat.com/*", "tracker"]). Max 30 entries. |
| Region & full-page controls | |||
| clip | object | null | Capture a specific rectangle. Object with x, y, width, height in CSS pixels. Overrides full_page and selector. |
| full_page_max_height | number | 0 | Hard cap on full_page image height in pixels. 0 means no cap. Use to guard against infinite-scroll pages. |
| full_page_slices | boolean | false | Split the full-page capture into vertical strips (great for AI vision workflows that have a max image height). Returns a slices array in the response. |
| full_page_slice_height | number | 4000 | Max height per slice in pixels (200-16000). |
| full_page_slice_overlap_height | number | 0 | Pixel overlap between adjacent slices (0-2000). Useful when downstream OCR/vision models need context around the seam. |
| Data extraction | |||
| extract_metadata | boolean | false | Return an extracted_metadata object with title, favicon, open_graph (map of all og:* tags), fonts (list of actually-loaded font families), http_status, http_status_text, and http_headers. |
| Response shape | |||
| attachment_name | string | "" | Filename hint. Sets Content-Disposition: attachment; filename="<name>" when response_type: "binary". Also drives the user-S3 filename. |
PDF options (only when format: "pdf") | |||
| pdf_page_size | string | A4 | Paper size: A0-A6, Letter, Legal, Tabloid, Ledger. |
| pdf_orientation | string | portrait | portrait or landscape. |
| pdf_margin_top | string | 20px | Top margin as a CSS unit string (e.g. 20px, 1cm, 0.5in). |
| pdf_margin_right | string | 20px | Right margin. |
| pdf_margin_bottom | string | 20px | Bottom margin. |
| pdf_margin_left | string | 20px | Left margin. |
| pdf_background | boolean | true | Include CSS backgrounds when printing. |
| pdf_scale | number | 1 | Rendering scale (0.1-2.0). |
| pdf_show_header | boolean | false | Render a header on each page. |
| pdf_header | string | "" | HTML template for the header. Uses Chromium's template syntax: <span class="pageNumber"></span>, <span class="totalPages"></span>, <span class="title"></span>, <span class="url"></span>, <span class="date"></span>. |
| pdf_show_footer | boolean | false | Render a footer on each page. |
| pdf_footer | string | "" | HTML template for the footer (same syntax as header). |
| pdf_page_range | string | "" | Page range filter (e.g. 1-5,8,11-13). |
| pdf_title | string | "" | PDF document title metadata (visible in most PDF viewers). |
| pdf_subject | string | "" | PDF document subject metadata. |
| pdf_author | string | "" | PDF document author metadata. |
| pdf_keywords | string | "" | PDF document keywords metadata (comma or space separated). |
| pdf_creator | string | "" | PDF document creator metadata. |
| Proxy / geo routing | |||
| proxy_url | string | "" | Bring-your-own proxy URL. Supports http, https, socks5, socks5h. Credentials may live in the URL userinfo (http://user:pass@host:port) or be split into proxy_username/proxy_password. Wins over proxy_country. |
| proxy_username | string | "" | Proxy auth username. Overrides any userinfo in proxy_url. |
| proxy_password | string | "" | Proxy auth password. Overrides any userinfo in proxy_url. |
| proxy_country | string | "" | Managed geo pool: ISO 3166-1 alpha-2 country code (US, DE, JP, etc.). Requires the deployment to have PROXY_URL_TEMPLATE configured. Returns 500 proxy_pool_not_configured when the pool is not enabled. |
HTML Rendering Example
curl -X POST https://api.getsnap.dev/v1/screenshot \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<html><body style=\"padding:40px;font-family:sans-serif\"><h1>Hello World</h1><p>Generated by getSnap.dev</p></body></html>",
"viewport_width": 1200,
"viewport_height": 630,
"format": "png"
}'
Retina Screenshot Example
curl -X POST https://api.getsnap.dev/v1/screenshot \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://stripe.com",
"device_scale_factor": 2,
"format": "png"
}'
Custom JS Injection Example
curl -X POST https://api.getsnap.dev/v1/screenshot \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"js": "document.querySelector(\".sidebar\").style.display = \"none\";"
}'
Authenticated Page with Cookies
curl -X POST https://api.getsnap.dev/v1/screenshot \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://app.example.com/dashboard",
"cookies": [
{"name": "session_id", "value": "abc123", "domain": "app.example.com"},
{"name": "auth_token", "value": "xyz789"}
],
"headers": {"Authorization": "Bearer your-token"}
}'
Localized Screenshot
curl -X POST https://api.getsnap.dev/v1/screenshot \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://google.com",
"locale": "de-DE",
"timezone": "Europe/Berlin"
}'
Response (URL mode)
{
"url": "https://getsnap-screenshots.fra1.cdn.digitaloceanspaces.com/screenshots/a1b2c3d4/req_abc123.png",
"cached": false,
"request_id": "req_abc123",
"response_time_ms": 2340
}
Additional fields appear conditionally:
extracted_text— present whenextract_text: trueextracted_html— present whenextract_html: trueextracted_metadata— present whenextract_metadata: true. Containstitle,favicon,open_graph(map),fonts(array),http_status,http_status_text,http_headers.slices— present whenfull_page_slices: true. Array of{ index, offset_y, width, height, url }objects; each slice is uploaded as its own object on the CDN.s3_keyands3_bucket— present whens3_uploadwas provided and the upload succeeded.
Response (Binary mode)
Returns raw bytes with the appropriate Content-Type header (image/png, image/jpeg, image/webp, image/avif, or application/pdf). When attachment_name is set, a Content-Disposition: attachment; filename="…" header is also sent so browsers offer a download prompt instead of rendering the image.
Response (Webhook mode)
{
"request_id": "req_abc123",
"status": "pending",
"message": "Screenshot is being captured. Result will be POSTed to your webhook_url.",
"status_url": "https://api.getsnap.dev/v1/screenshot/req_abc123"
}
When the screenshot is ready, getSnap.dev will POST to your webhook_url:
{
"event": "screenshot.completed",
"request_id": "req_abc123",
"url": "https://getsnap-screenshots.fra1.cdn.digitaloceanspaces.com/screenshots/a1b2c3d4/req_abc123.png",
"cached": false,
"response_time_ms": 6500
}
Batch Capture
Capture screenshots of multiple URLs in a single request. Processes URLs sequentially and returns all results. Supports up to 100 URLs per batch.
Request Body
| Parameter | Type | Default | Description |
|---|---|---|---|
| urls | string[] required | - | Array of URLs to capture (1-100 URLs) |
| All other parameters from POST /v1/screenshot are supported (format, viewport_width, device_scale_factor, block_ads, etc.) and apply to every URL in the batch. | |||
| webhook_url | string | - | If provided, returns 202 immediately and POSTs all results when complete. |
Example
curl -X POST https://api.getsnap.dev/v1/batch \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"urls": [
"https://stripe.com",
"https://github.com",
"https://example.com"
],
"format": "png",
"device_scale_factor": 2,
"block_ads": true
}'
Response (Synchronous)
{
"batch_id": "batch_abc123",
"count": 3,
"succeeded": 3,
"failed": 0,
"response_time_ms": 12500,
"results": [
{
"url": "https://cdn.../screenshots/abc/req_1.png",
"source_url": "https://stripe.com",
"cached": false,
"request_id": "req_1"
},
{
"url": "https://cdn.../screenshots/def/req_2.png",
"source_url": "https://github.com",
"cached": false,
"request_id": "req_2"
},
{
"url": "https://cdn.../screenshots/ghi/req_3.png",
"source_url": "https://example.com",
"cached": false,
"request_id": "req_3"
}
]
}
Response (Async with webhook_url)
{
"batch_id": "batch_abc123",
"status": "pending",
"count": 3,
"message": "Batch capture started. Results will be POSTed to your webhook_url.",
"status_url": "https://api.getsnap.dev/v1/screenshot/batch_abc123"
}
Screenshot Status
Check the status of an async webhook screenshot or batch request. Only accessible with the same API key that created the request.
Response
{
"request_id": "req_abc123",
"status": "completed",
"created_at": "2026-08-25T12:00:00",
"completed_at": "2026-08-25T12:00:07",
"result": {
"event": "screenshot.completed",
"url": "https://getsnap-screenshots.fra1.cdn.digitaloceanspaces.com/screenshots/a1b2c3d4/req_abc123.png"
}
}
Possible status values: pending, processing, completed, failed.
Error Responses
{
"error": "validation_error",
"message": "Invalid request body",
"details": { "url": ["Either 'url' or 'html' must be provided"] }
}
{
"error": "quota_exceeded",
"message": "Monthly limit of 100 screenshots reached. Upgrade your plan.",
"used": 100,
"limit": 100
}
{
"error": "capture_failed",
"message": "Navigation timeout exceeded",
"request_id": "req_abc123"
}
Capture Scrolling Video
Records a smoothly-scrolling capture of a URL as an MP4 or GIF. Uses Chrome DevTools' Page.screencast protocol for high-fps frame sampling and encodes the result with ffmpeg.
Request Headers
| Header | Type | Description |
|---|---|---|
| x-api-key | string required | Your API key |
| Content-Type | string required | Must be application/json |
Request Body
| Parameter | Type | Default | Description |
|---|---|---|---|
| url | string required | - | The URL to record. Must be a valid HTTP/HTTPS URL. |
| format | string | mp4 | mp4 or gif. |
| viewport_width | number | 1280 | Viewport width in pixels (320-1920). |
| viewport_height | number | 720 | Viewport height in pixels (200-1080). |
| device | string | desktop | desktop, mobile, or tablet. |
| device_scale_factor | number | 1 | Retina scale (0.5-2). Capped smaller than screenshots for encoding tractability. |
| fps | number | 15 | Frames per second (10-30). |
| duration_ms | number | 5000 | Total duration in milliseconds (2000-30000). |
| quality | number | 70 | 1-100. Drives MP4 CRF (higher = better quality) or GIF palette generation. |
| remove_popups | boolean | true | Remove cookie banners / popups before recording. |
| block_ads | boolean | true | Block ad requests. |
| dark_mode | boolean | false | Emulate prefers-color-scheme: dark. |
| delay | number | 0 | Extra ms to wait after page load before recording begins (0-10000). |
| css | string | "" | Custom CSS to inject before recording. |
| js | string | "" | Custom JavaScript to execute before recording. |
| wait_for_selector | string | "" | Wait for a CSS selector before recording starts. |
| wait_for_network_idle | boolean | true | Wait for network idle before recording. |
| headers, cookies, locale, timezone, user_agent | - | Same semantics as the screenshot endpoint. | |
| proxy_url, proxy_username, proxy_password, proxy_country | - | Same semantics as the screenshot endpoint. | |
| response_type | string | url | url returns CDN link, binary returns raw MP4/GIF bytes. |
| attachment_name | string | "" | Sets Content-Disposition: attachment; filename="…" on binary responses. |
| webhook_url | string | - | If provided, returns 202 immediately and POSTs a video.completed event to this URL when done. |
| s3_upload | object | - | Same shape as the screenshot endpoint. |
Example
curl -X POST https://api.getsnap.dev/v1/video \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://stripe.com",
"format": "mp4",
"duration_ms": 8000,
"fps": 20,
"viewport_width": 1280,
"viewport_height": 720,
"quality": 75
}'
Response (URL mode)
{
"url": "https://getsnap-screenshots.fra1.cdn.digitaloceanspaces.com/videos/ONE9iLdU/vid_ONE9iLdUbWKeijB6.mp4",
"request_id": "vid_ONE9iLdUbWKeijB6",
"format": "mp4",
"duration_ms": 8000,
"frame_count": 160,
"fps": 20,
"bytes": 2109440,
"credits_charged": 8,
"response_time_ms": 10432
}
Response (Webhook mode)
{
"request_id": "vid_ONE9iLdUbWKeijB6",
"status": "pending",
"message": "Video is being captured. Result will be POSTed to your webhook_url.",
"credits_reserved": 8
}
When the video is ready, getSnap.dev will POST a video.completed event to your webhook (or video.failed on error) using the same delivery, retry, and HMAC-signature semantics as the schedules webhook.
Create Scheduled Capture
Creates a cron-driven scheduled capture. On each tick the worker runs takeScreenshot(), uploads to the CDN, optionally POSTs to your webhook, and logs a row in schedule_runs.
Request Body
| Parameter | Type | Default | Description |
|---|---|---|---|
| name | string required | - | Human-friendly name for the schedule (1-100 chars). |
| cron | string required | - | Standard 5- or 6-field UNIX cron expression. Validated with cron-parser. Examples: 0 9 * * MON-FRI, */15 * * * *, 0 0 1 * *. |
| timezone | string | UTC | IANA timezone the cron runs in (e.g. Europe/Berlin, America/New_York). |
| options | object required | - | The full /v1/screenshot options blob to use for every run. Must include url or html. |
| webhook_url | string | - | Optional URL to POST each result to. Get a schedule.completed or schedule.failed event. |
| webhook_secret | string | - | Optional HMAC-SHA256 secret. When set, deliveries include X-Webhook-Signature: sha256=hex(hmac(secret, ts + "." + body)) and X-Webhook-Timestamp headers so you can verify authenticity. |
| is_active | boolean | true | Start immediately. Pass false to create paused. |
Example
curl -X POST https://api.getsnap.dev/v1/schedules \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "morning traffic dashboard",
"cron": "0 9 * * MON-FRI",
"timezone": "Europe/Berlin",
"options": {
"url": "https://dash.example.com",
"format": "png",
"full_page": true,
"viewport_width": 1600
},
"webhook_url": "https://my-app.com/webhooks/getsnap",
"webhook_secret": "a-strong-shared-secret-abcd1234"
}'
Response
{
"id": "sched_SVVnySRhW-xbqYrE",
"name": "morning traffic dashboard",
"cron": "0 9 * * MON-FRI",
"timezone": "Europe/Berlin",
"options": { "url": "https://dash.example.com", "format": "png", "full_page": true, "viewport_width": 1600 },
"webhook_url": "https://my-app.com/webhooks/getsnap",
"has_webhook_secret": true,
"is_active": true,
"next_run_at": "2026-09-21T07:00:00.000Z",
"created_at": "2026-09-20 07:05:26",
"updated_at": "2026-09-20 07:05:26"
}
List Scheduled Captures
Returns every schedule owned by the API key that made the request. Sorted newest-first.
Response
{
"count": 2,
"schedules": [ /* Schedule objects, same shape as Create response */ ]
}
Fetch Scheduled Capture
Returns one schedule by ID. 404 if it doesn't exist or isn't owned by the requesting key.
Update Scheduled Capture
Every top-level field is optional. Provide only what changes. Editing cron, timezone, or is_active is fully synchronized with the underlying queue: the old repeatable job is removed and a new one registered atomically.
To clear webhook_url or webhook_secret, pass an empty string.
Example (pause a schedule)
curl -X PATCH https://api.getsnap.dev/v1/schedules/sched_SVVnySRhW-xbqYrE \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"is_active": false}'
Delete Scheduled Capture
Deletes the schedule, unregisters it from the queue, and drops its schedule_runs history.
{ "deleted": true, "id": "sched_SVVnySRhW-xbqYrE" }
Trigger Scheduled Capture Now
Fires a one-off ad-hoc run of the schedule without touching the cron. Useful for testing a new schedule end-to-end before waiting for the next tick.
{
"schedule_id": "sched_SVVnySRhW-xbqYrE",
"status": "queued",
"message": "Capture queued; result will be delivered via webhook (if configured) and appear in /runs."
}
List Schedule Runs
Returns the last 100 execution records for a schedule (older rows are pruned automatically to keep history bounded).
{
"schedule_id": "sched_SVVnySRhW-xbqYrE",
"count": 3,
"runs": [
{
"id": "run_mX4RpcnmpBLYhdXd",
"status": "completed",
"result_url": "https://getsnap-screenshots.fra1.cdn.digitaloceanspaces.com/screenshots/scheduled/…/run_mX4RpcnmpBLYhdXd.png",
"error": null,
"response_ms": 1373,
"webhook_status": 200,
"started_at": "2026-09-20 07:09:04",
"completed_at": "2026-09-20 07:09:05"
}
]
}
Create Render Link
Generate a signed render link URL. Use the returned URL in <img> tags, OG meta tags, or anywhere that accepts an image URL. The link serves screenshots via GET requests without exposing your API key.
Request Body
Accepts the same parameters as POST /v1/screenshot (url, html, format, viewport_width, etc.).
Response
{
"render_url": "https://api.getsnap.dev/v1/render?url=https%3A%2F%2Fexample.com&format=png&signature=abc123&key=pk_...",
"message": "Use this URL in <img> tags or anywhere that accepts an image URL."
}
Render (Signed URL)
Serves a screenshot from a signed render link. Redirects to the CDN URL. No authentication header needed — the signature in the URL verifies the request. Generated by POST /v1/render-link.
Get Usage
Returns your current billing period usage statistics.
Request Headers
| Header | Type | Description |
|---|---|---|
| x-api-key | string required | Your API key |
Response
{
"period": "2026-08",
"used": 847,
"limit": 5000,
"plan": "starter",
"remaining": 4153
}
Health Check
Returns the API service status. No authentication required.
Response
{
"status": "ok",
"timestamp": "2026-08-22T12:00:00.000Z",
"version": "1.0.0"
}