CAPTURERECALL FOR DEVELOPERS

Put screenshot capture
inside your product.

One API for website previews, release checks, project directories, and visual references. Capture a public page, get the image, and optionally keep a private copy in CaptureRecall.

A useful capture primitive

From public URL to project-ready image.

Desktop, mobile, full page

Set your viewport and choose a visible-page or full-page capture. Get PNG or JPEG over HTTPS.

Return it or recall it

Use the image directly in your application. With an active hosted plan, save a PNG and its metadata to your private CaptureRecall library.

Limits you can see

Create revocable server keys, inspect usage, and stop at your monthly quota. Your free allowance is shared across keys.

Make your first request

Start with a URL and a server key.

Sign in, create a key in the developer dashboard, and put it in your backend’s secret manager. Keys are shown once, expire after one year, and can be revoked. Your account can have three active keys.

curl --fail-with-body https://capturerecall.com/api/developer/v1/screenshots \
  -H "Authorization: Bearer $CAPTURERECALL_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://capturerecall.com/","width":1280,"height":720,"format":"png"}' \
  --output screenshot.png

JavaScript / Node.js

// Run on your server (Node.js 22+), never ship your key to a browser.
const response = await fetch('https://capturerecall.com/api/developer/v1/screenshots', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.CAPTURERECALL_API_KEY}`,
    'Content-Type': 'application/json' },
  body: JSON.stringify({ url: 'https://capturerecall.com/',
    width: 390, height: 844, fullPage: true, format: 'png' })
});
if (!response.ok) throw new Error(await response.text());
const { writeFile } = await import('node:fs/promises');
await writeFile('screenshot.png', new Uint8Array(await response.arrayBuffer()));

Python standard library

import os, json, urllib.request
request = urllib.request.Request(
    'https://capturerecall.com/api/developer/v1/screenshots',
    data=json.dumps({'url': 'https://capturerecall.com/', 'format': 'png'}).encode(),
    headers={'Authorization': 'Bearer ' + os.environ['CAPTURERECALL_API_KEY'],
             'Content-Type': 'application/json'}, method='POST')
with urllib.request.urlopen(request, timeout=60) as response:
    with open('screenshot.png', 'wb') as image:
        image.write(response.read())

Request reference

POST /api/developer/v1/screenshots with a Bearer developer key and JSON body.

FieldDefaultAccepted values
urlRequiredPublic HTTP(S), at most 2,048 characters
width / height1280 / 720320–1920 / 240–1080 pixels
fullPagefalsetrue or false
formatpngpng or jpeg
savefalsetrue saves a PNG to your paid hosted library
metadataOptionaltitle, description, note, tags, favorite, createdAt; used when saving

Binary responses are image/png or image/jpeg, up to 8 MiB. With save:true, a 201 JSON response includes the private capture ID and authenticated download endpoint. Saved images count against your existing library storage allowance.

Usage and saved files

GET /api/developer/v1/usage returns your plan, monthly limit, used attempts, and UTC month. GET /api/developer/v1/captures/{id} downloads a saved PNG using a key for that library. Keys can read that library’s saved captures, so keep them private.

Errors and retries

400 invalid request; 401 invalid or revoked key; 402 hosted plan required for saving; 409 hosted storage full; 413 request too large; 422 image too large; 429 quota, rate, or shared capacity reached; 502 capture failed; 503 capture paused or unavailable. Error JSON includes error and code. Inspect the code before retrying; a retry is a new attempt. The request body is limited to 8 KiB. Maximum six attempts per minute and three in flight per account.

Download OpenAPI specification

Start free. Expand when your project needs it.

Free: 25 attempts/month. Personal: 1,000/month plus a 1 GB hosted library for CAD $8/month. Team: 1,000/month per paid seat plus 5 GB storage per seat for CAD $15/seat/month, two seats minimum. Existing Personal and Team subscribers receive the API allowance.

Allowances reset on the first day of each UTC calendar month. There is no rollover or automatic overage billing. All requests remain subject to rate and shared capacity limits; the free pool may pause before an individual account uses its full allowance.

Compare plans →

Developer API FAQ

What is the CaptureRecall developer API?

An HTTPS API that captures public website screenshots in Cloudflare-hosted browsers and returns PNG or JPEG images. It is separate from the free local desktop app.

What is included for free?

A signed-in account gets 25 capture attempts per UTC calendar month, shared across its API keys. Free accounts also share a global capacity budget. No card is required; capture pauses when a limit is reached.

How do paid limits work?

Personal includes 1,000 capture attempts per UTC calendar month for CAD $8/month. Team includes 1,000 per paid seat for CAD $15/seat/month, with two seats minimum. Quotas are hard limits; there are no automatic overage charges.

Do failed requests count?

Authorized capture attempts count, including website blocks, timeouts, and repeated cached captures. Invalid input and unauthorized requests do not. Retrying is a new attempt.

Where do API images go?

Images are returned directly by default. Public-page captures may be cached privately in the renderer for up to 24 hours. With save:true and an active hosted plan, a PNG is also stored in your private CaptureRecall library. The desktop library is not uploaded automatically.

Can I capture private or logged-in pages?

The API supports public HTTP(S) websites only. It does not accept login cookies, custom target headers, private network URLs, CAPTCHA bypass, or arbitrary browser scripts. Some websites block automated capture.

Is there an uptime guarantee?

The API is an early release with quota, rate and shared capacity limits. There is no contractual uptime guarantee; check error codes and keep a manual fallback where your application needs one.