One URL in, one screenshot out.
A screenshot API for developers
One URL in, one screenshot out.
Turn any web page into a PNG, JPEG or PDF with a single HTTP request. No headless browser to run, no SDK to install.
See screenshot
Live capture, no signup. Shared public demo with a small daily quota.
Try it free — get an API key Read the docs
request
GET /screenshot?url=https://example.com &full_page=true&format=png x-api-key: YOUR_API_KEY
← 200 OK content-type: image/png [ the screenshot itself, ready to save ]
- PNG & JPEG screenshots
- PDF generation
- Full-page capture
- Custom viewport
- CSS selectors
- Change monitoring + webhooks
- One endpoint`GET /screenshot?url=…`
- No infrastructureNo Chromium to install or patch
- Predictable limits`429` \+ `Retry-After`, never a silent hang
- Free tier200 screenshots/month, no card
- `url`Required. Any public http/https page.
- `format` `png` (default), `jpeg` or `pdf`.
- `full_page` `true` for the whole scrollable page.
- `width` `height`Viewport, 200–2560px. Default 1280×800.
- `selector`Capture one element (PNG/JPEG).
- `quality`1–100, JPEG only.
- 200 screenshots/month
- 3 monitored pages, checked every 6h
- PNG, JPEG and PDF Get a free key
- 2,000 screenshots/month
- 20 monitored pages, checked every 1h
- Webhook alerts on change Choose Starter
- 10,000 screenshots/month
- 100 monitored pages, checked every 15–30 min
- Webhook alerts on change
Why an API
Running a headless browser yourself is a side project you didn't ask for.
Taking one screenshot is easy. Keeping it working in production is not. That's the part this API takes off your plate.
Heavy dependencies
A browser binary, system libraries and fonts on every server or CI runner that needs a capture.
Timeouts and hangs
Slow or broken pages need timeouts, size caps and clean error handling — or they block your workers.
Glue code for every format
Full page, viewport sizes, a single element, PDF output — each one is more code to write and maintain.
Who it's for
Built for developers who need a screenshot, not a screenshot platform.
If your product, script or pipeline needs to see a web page, one HTTP request is all it takes.
SaaS products
Show thumbnails of your users' sites, dashboards or pages inside your own app.
Link previews & OG images
Generate preview images of any URL at the exact viewport size you need.
QA & visual checks
Capture pages in CI, or let a monitor compare captures and call your webhook when something changes.
PDF generation
Save any page as a PDF that looks like the real page — viewport-sized or the full content.
Automations
Any script, cron job or workflow tool that can send an HTTP request can capture a page.
Agencies & archiving
Keep a record of how a client's page looked at a point in time, or track competitor pages.
Looking for something more specific? See dedicated pages for URL to PDF, website monitoring and visual regression testing.
Features
Everything a capture needs. Nothing you have to learn.
Every option is a query parameter on the same endpoint.
PNG or JPEG
`format=png` or `jpeg`, with `quality` 1–100 for JPEG.
PDF output
`format=pdf` renders the page as it looks on screen, not a print stylesheet.
Full-page capture
`full_page=true` captures the whole scrollable page, up to 30,000px tall.
Any viewport
`width` / `height` from 200 to 2560px — mobile, tablet or desktop.
Single element
`selector` captures just one element by CSS selector.
Change monitoring
`POST /monitors` captures a URL on a schedule, compares it and calls your webhook on change.
API example
Copy, paste, get a file back.
The response body is the image or PDF itself. No job IDs, no polling.
cURL Node.js Python Copy
curl -G \ "https://screenshot-api-production-ffd7.up.railway.app/screenshot" \ -H "x-api-key: YOUR_API_KEY" \ --data-urlencode "url=https://example.com" \ -d "full_page=true" \ -d "format=png" \ -o screenshot.png
import { writeFileSync } from "node:fs";
const params = new URLSearchParams({ url: "https://example.com", full_page: "true", format: "png", }); const res = await fetch( "https://screenshot-api-production-ffd7.up.railway.app/screenshot?" + params, { headers: { "x-api-key": process.env.SCREENSHOT_API_KEY } } ); if (!res.ok) throw new Error(await res.text()); const file = Buffer.from(await res.arrayBuffer()); writeFileSync("screenshot.png", file);
import os, requests
res = requests.get( "https://screenshot-api-production-ffd7.up.railway.app/screenshot", params={"url": "https://example.com", "full_page": "true", "format": "png"}, headers={"x-api-key": os.environ["SCREENSHOT_API_KEY"]}, timeout=30, ) res.raise_for_status() open("screenshot.png", "wb").write(res.content)
Full reference, limits and error codes in the docs.
How it works
From zero to your first capture in three steps.
1
Get a free key
Enter your email in the docs and your API key is issued on the spot. No card.
2
Call the endpoint
`GET /screenshot?url=…` with your key in the `x-api-key` header.
3
Get the file
The response is the PNG, JPEG or PDF. Save it, store it, show it.
Monitor: URL→Scheduled capture→Compare→Change detected→Your webhook
Comparison
Screenshot Happy vs. running it yourself
What you'd build around Puppeteer or Playwright, already done.
| | DIY headless browser | Screenshot Happy | | ------------- | ------------------------------------------------- | -------------------------------- | | Setup | Install a browser, its system libraries and fonts | One HTTP request with an API key | | Maintenance | Browser updates, crashes, memory | Handled for you | | Formats | Code for each: full page, viewport, element, PDF | Query parameters | | Change alerts | Build a scheduler, image diff and webhook sender | POST /monitors | | Cost to start | A server that runs a browser | Free tier, then from €9/month |
There are other good screenshot APIs — ScreenshotOne, Urlbox, ApiFlash and more. If you're happy with one, there's no reason to switch. This one is small, self-contained and has a real free tier: a good fit for prototypes and side projects, or if you want to try something different before committing.
Pricing
Screenshots and change monitoring, one plan.
No separate products, no usage billing to track. Each plan gives you more of both. Cancel any time.
Free
€0/month
No card required
Starter
€9/month
Billed monthly via Stripe
Growth
€29/month
Billed monthly via Stripe
Over your quota you get a clear `429`, never a surprise charge. Need more than Growth? Contact us.
FAQ
Questions, answered.
Is there really a free plan?
Yes. 200 screenshots a month and 3 monitored pages, no card required. Enter your email in the docs and you get a key immediately.
Which output formats are supported?
PNG (default), JPEG with adjustable quality, and PDF. PDF renders the page as it looks on screen; add `full_page=true` for one page sized to the whole content.
What are the rate limits?
10 requests per minute per API key, on every plan, plus your plan's monthly quota. Over a limit you get a `429` with a `Retry-After` header — never a silent hang.
What happens if I go over my monthly quota?
Requests return a clear `429` telling you so. There is no overage billing and no surprise charge. You can upgrade at any time.
How does change monitoring work?
One `POST /monitors` call with a URL, a webhook and a check interval. The page is captured on that schedule, compared with the previous capture, and your webhook is called when the difference crosses your threshold. It needs your own API key — the public demo can't create monitors.
Can I cancel or change plans?
Yes, no contracts. Manage or cancel your subscription yourself from the billing portal in the docs with your API key.
Is the demo on this page real?
Yes — it calls the same `/screenshot` endpoint with a shared public key that has a small daily quota for all visitors. For regular use, get your own free key.
Something isn't working. Who do I ask?
Use the support form in the docs and we'll reply by email.
Your first screenshot is one request away.
Try the live demo above, or get a free API key and call it from your own code.
