POST /screenshots/* returns 202 Accepted with a jobId immediately — the actual capture happens in the background. Steps 3 and 4 show how to wait for it and download the result.Get your API key
The fastest way is to create an account in the dashboard — your API key is shown immediately on the confirmation screen. Alternatively, register directly via the API:
1curl -X POST https://api.screenshotfreeapi.com/auth/register \
2 -H "Content-Type: application/json" \
3 -d '{
4 "name": "Jane Smith",
5 "email": "you@example.com",
6 "password": "secret123!"
7 }'1{
2 "userId": "usr_4a8b2f91",
3 "email": "you@example.com",
4 "apiKey": "sfa_xxxxxxxxxxxxxxxxxxxx",
5 "warning": "Save this key — it will not be shown again."
6}apiKey field appears once in the registration response. Store it immediately in an environment variable — it cannot be retrieved again.Submit a capture job
Send a POST to /screenshots/web with the URL you want to capture. The endpoint returns a jobId — your handle for polling and fetching the result.
1const res = await fetch(
2 "https://api.screenshotfreeapi.com/screenshots/web",
3 {
4 method: "POST",
5 headers: {
6 "Authorization": "Bearer sfa_YOUR_KEY",
7 "Content-Type": "application/json",
8 },
9 body: JSON.stringify({
10 url: "https://stripe.com",
11 format: "png",
12 fullPage: false,
13 }),
14 },
15);
16
17const { jobId } = await res.json();
18// → "job_web_8a3b7d21"1{
2 "jobId": "job_web_8a3b7d21",
3 "status": "queued",
4 "statusUrl": "https://api.screenshotfreeapi.com/jobs/job_web_8a3b7d21/status",
5 "estimatedSeconds": 5
6}"fullPage": true for a full-page scroll capture, or "description": "the pricing table" to let Claude vision AI identify and crop a specific element automatically.Poll until complete
Screenshot jobs typically complete in 3–8 seconds. Poll GET /jobs/:id/status every 2 seconds until status is "completed" or "failed".
1async function waitForJob(jobId: string, apiKey: string) {
2 const url = `https://api.screenshotfreeapi.com/jobs/${jobId}/status`;
3
4 while (true) {
5 const res = await fetch(url, {
6 headers: { "Authorization": `Bearer ${apiKey}` },
7 });
8 const { status } = await res.json();
9
10 if (status === "completed" || status === "failed") return status;
11
12 await new Promise((r) => setTimeout(r, 2_000)); // poll every 2 s
13 }
14}
15
16const status = await waitForJob("job_web_8a3b7d21", "sfa_YOUR_KEY");1{ "status": "queued", "progress": 0 }
2{ "status": "processing", "progress": 55 }
3{ "status": "completed", "progress": 100 }webhookUrl in the capture request and the API pushes a job.completed event to your endpoint when done. Webhook docs →Download the screenshot
Once the status is "completed", fetch the full result. The screenshots[0].url is a presigned S3 URL — download the image within 15 minutes before the link expires.
1const res = await fetch(
2 `https://api.screenshotfreeapi.com/jobs/${jobId}/result`,
3 { headers: { "Authorization": `Bearer ${apiKey}` } },
4);
5
6const { screenshots, metadata } = await res.json();
7
8// Presigned S3 URL — expires in 15 minutes, download immediately
9const imageUrl = screenshots[0].url;
10console.log(metadata.pageTitle); // "Stripe | Financial Infrastructure…"1{
2 "jobId": "job_web_8a3b7d21",
3 "status": "completed",
4 "screenshots": [
5 {
6 "url": "https://cdn.screenshotfreeapi.com/…/job_web_8a3b7d21.png",
7 "format": "png",
8 "width": 1280,
9 "height": 800,
10 "capturedAt": "2026-06-15T12:34:56Z"
11 }
12 ],
13 "metadata": {
14 "pageTitle": "Stripe | Financial Infrastructure to Grow Your Revenue",
15 "processingMs": 3420
16 }
17}metadata.processingMs tells you how long the Playwright render took. The pageTitle field is extracted from the captured page's <title> tag and is useful for logging and display.Next steps