Allscreenshots
API reference

Scheduled screenshots

Automatically capture screenshots on a recurring schedule

Scheduled screenshots

Capture a URL on a recurring schedule without running your own cron, browser, or storage. A schedule captures the page, keeps the result for as long as you specify, and can email you or POST to a webhook — optionally only when the page actually changed.

Scheduled captures are available on every plan, including Free — they're metered by your monthly screenshot quota. Webhook delivery is free on every plan too. Email delivery is a paid feature (Starter and above).

Create schedule

POST /v1/schedules

Request body

{
  "name": "Homepage Monitor",
  "url": "https://example.com",
  "schedule": "0 0 9 * * *",
  "timezone": "America/New_York",
  "options": {
    "viewport": { "width": 1920, "height": 1080 },
    "format": "png",
    "fullPage": false,
    "blockAds": true
  },
  "destinations": [
    { "type": "email", "to": ["[email protected]"], "subject": "Homepage snapshot" }
  ],
  "onlyOnChange": true,
  "diffThreshold": 0.01,
  "alertOnFailure": true,
  "autoPauseAfterFailures": 5,
  "retentionDays": 30,
  "startsAt": "2025-02-01T00:00:00Z",
  "endsAt": null
}

Parameters

ParameterTypeRequiredDescription
namestringYesSchedule name (max 255 chars)
urlstringYesURL to capture
schedulestringYesCron expression or interval alias
timezonestringNoTimezone for cron (default: UTC)
optionsobjectNoScreenshot options
destinationsarrayNoWhere to deliver each capture — email or webhook (max 10)
onlyOnChangebooleanNoSkip delivery when the capture matches the previous run (default: false)
diffThresholdnumberNoFraction of changed pixels (0–1) that counts as a change (default: 0.01)
alertOnFailurebooleanNoSend a failure notice to your destinations when a run fails (default: false)
autoPauseAfterFailuresintegerNoPause the schedule after this many consecutive failures (1–100)
retentionDaysintegerNoDays to keep captures (1–365, default: 30)
startsAtstringNoISO 8601 — don't run before this time
endsAtstringNoISO 8601 — don't run after this time
webhookUrlstringNoDeprecated. Use a webhook destination instead
webhookSecretstringNoDeprecated. Use a webhook destination's secret instead

Schedule formats

Cron expressions

Standard 6-field cron format:

┌───────────── second (0-59)
│ ┌───────────── minute (0-59)
│ │ ┌───────────── hour (0-23)
│ │ │ ┌───────────── day of month (1-31)
│ │ │ │ ┌───────────── month (1-12)
│ │ │ │ │ ┌───────────── day of week (0-7, Sunday=0 or 7)
│ │ │ │ │ │
* * * * * *

Examples:

ExpressionDescription
0 0 9 * * *Every day at 9:00 AM
0 0 */4 * * *Every 4 hours
0 0 9 * * 1-5Weekdays at 9:00 AM
0 0 0 1 * *First day of each month at midnight
0 0 9,12,18 * * *At 9 AM, 12 PM, and 6 PM daily

Interval format

Simple intervals for common schedules:

FormatDescription
hourlyEvery hour at minute 0
dailyEvery day at midnight
weeklyEvery Sunday at midnight
monthlyFirst day of month at midnight

Screenshot options

The options object takes the same fields as the screenshot API, minus url (which comes from the schedule):

{
  "options": {
    "viewport": { "width": 1920, "height": 1080 },
    "device": null,
    "format": "png",
    "fullPage": false,
    "quality": 80,
    "delay": 0,
    "waitFor": null,
    "waitUntil": "domcontentloaded",
    "timeout": 30000,
    "darkMode": false,
    "customCss": null,
    "hideSelectors": [],
    "selector": null,
    "blockAds": true,
    "blockCookieBanners": true,
    "blockLevel": "none",
    "stealthMode": false,
    "outputs": null
  }
}

Use outputs to capture more than an image per run — a PDF, HTML, Markdown, or extracted JSON alongside the screenshot. See multiple outputs. Content outputs (HTML/Markdown/JSON) require the content extraction capability, included on Pro and above.

Delivery destinations

By default a capture is stored and reachable from the schedule history. Add destinations to also push each run to email or a webhook. A schedule can have up to 10 destinations.

Each destination can set onlyOnChange to override the schedule-level setting — for example, archive every run to a webhook but email a person only when the page changes.

Email

{
  "type": "email",
  "to": ["[email protected]", "[email protected]"],
  "subject": "Pricing page snapshot",
  "onlyOnChange": true
}
FieldTypeRequiredDescription
tostring[]YesRecipient addresses
subjectstringNoCustom subject line
onlyOnChangebooleanNoOverride the schedule's change setting for this destination

Webhook

{
  "type": "webhook",
  "url": "https://your-server.com/webhooks/scheduled",
  "secret": "whsec_...",
  "onlyOnChange": false
}
FieldTypeRequiredDescription
urlstringYesEndpoint that receives the POST
secretstringNoSigns the payload with HMAC-SHA256 (write-only; never returned)
onlyOnChangebooleanNoOverride the schedule's change setting for this destination

Webhook delivery is available on every plan, including Free. Email delivery requires a paid plan (Starter and above).

Webhook destination payload

Each run posts JSON to your endpoint with the X-Webhook-Event: schedule.delivery header. When you set a secret, an X-Webhook-Signature HMAC-SHA256 header is included (same scheme as webhooks).

Single-output capture:

{
  "event": "schedule.delivery",
  "scheduleName": "Daily homepage",
  "url": "https://example.com",
  "executionId": "exec001abc",
  "resultUrl": "https://api.allscreenshots.com/v1/screenshots/jobs/abc123xyz0/result",
  "storageUrl": "https://storage.allscreenshots.com/abc123xyz0.png",
  "changed": true
}

Multi-output capture — same shape plus an outputs map keyed by output id:

{
  "event": "schedule.delivery",
  "scheduleName": "Daily homepage",
  "url": "https://example.com",
  "executionId": "exec001abc",
  "resultUrl": "https://api.allscreenshots.com/v1/screenshots/jobs/abc123xyz0/result/screenshot",
  "storageUrl": "https://storage.allscreenshots.com/abc123xyz0/screenshot.png",
  "changed": true,
  "outputs": {
    "screenshot": {
      "type": "screenshot",
      "contentType": "image/png",
      "size": 245678,
      "resultUrl": "https://api.allscreenshots.com/v1/screenshots/jobs/abc123xyz0/result/screenshot",
      "storageUrl": "https://storage.allscreenshots.com/abc123xyz0/screenshot.png"
    },
    "markdown": {
      "type": "markdown",
      "contentType": "text/markdown",
      "size": 1200,
      "resultUrl": "https://api.allscreenshots.com/v1/screenshots/jobs/abc123xyz0/result/markdown",
      "storageUrl": "https://storage.allscreenshots.com/abc123xyz0/markdown.md"
    }
  }
}

Top-level resultUrl/storageUrl point at the first output (the screenshot for typical captures). Read outputs to iterate every artifact.

If the run fails (or auto-pause kicks in) and alertOnFailure is set, the same endpoint receives a schedule.failed event instead:

{
  "event": "schedule.failed",
  "scheduleName": "Daily homepage",
  "url": "https://example.com",
  "error": "Page load timed out",
  "autoPaused": false
}

Change detection

Set onlyOnChange: true and a schedule compares each capture against the previous successful run. If the page hasn't changed, the capture is still recorded in history but delivery is skipped — so you only get emailed when something is actually different.

diffThreshold is the fraction of pixels that must differ to count as a change, from 0 to 1 (default 0.01, i.e. 1%). The first run has no baseline, so it always counts as a change and delivers.

diffThresholdBehavior
0.1Only large changes (~10% of pixels) trigger delivery
0.03Moderate changes
0.005Small changes — catches minor edits

The dashboard exposes these three values as Low / Medium / High sensitivity.

Response

{
  "id": "schedabc123",
  "name": "Homepage Monitor",
  "url": "https://example.com",
  "schedule": "0 0 9 * * *",
  "scheduleDescription": "at 9:00 AM America/New_York",
  "timezone": "America/New_York",
  "status": "active",
  "options": {
    "viewport": { "width": 1920, "height": 1080 },
    "format": "png",
    "fullPage": false,
    "blockAds": true
  },
  "destinations": [
    { "type": "email", "id": "dst_a1b2c3", "to": ["[email protected]"], "subject": "Homepage snapshot" }
  ],
  "onlyOnChange": true,
  "diffThreshold": 0.01,
  "alertOnFailure": true,
  "autoPauseAfterFailures": 5,
  "consecutiveFailures": 0,
  "retentionDays": 30,
  "startsAt": "2025-02-01T00:00:00Z",
  "endsAt": null,
  "lastExecutedAt": null,
  "nextExecutionAt": "2025-01-16T14:00:00Z",
  "executionCount": 0,
  "successCount": 0,
  "failureCount": 0,
  "createdAt": "2025-01-15T10:30:00Z",
  "updatedAt": "2025-01-15T10:30:00Z"
}

status is one of active, paused, completed, or failed. Webhook secrets are never returned; destinations come back with a generated id and masked secrets.

List schedules

GET /v1/schedules

Response

{
  "schedules": [
    {
      "id": "schedabc123",
      "name": "Homepage Monitor",
      "url": "https://example.com",
      "schedule": "0 0 9 * * *",
      "scheduleDescription": "at 9:00 AM America/New_York",
      "timezone": "America/New_York",
      "status": "active",
      "retentionDays": 30,
      "lastExecutedAt": "2025-01-15T14:00:00Z",
      "nextExecutionAt": "2025-01-16T14:00:00Z",
      "executionCount": 1,
      "successCount": 1,
      "failureCount": 0,
      "createdAt": "2025-01-15T10:30:00Z",
      "updatedAt": "2025-01-15T10:30:00Z"
    }
  ],
  "total": 1
}

Get schedule

GET /v1/schedules/{scheduleId}

Response

Full schedule details including recent captures.

Update schedule

PUT /v1/schedules/{scheduleId}

Request body

Only include fields you want to update. Accepts the same fields as create, including destinations, onlyOnChange, diffThreshold, and the failure-handling options. Passing destinations replaces the existing list.

{
  "name": "Updated Name",
  "schedule": "0 0 */2 * * *",
  "onlyOnChange": true,
  "diffThreshold": 0.02,
  "options": {
    "fullPage": true
  }
}

Pause/resume schedule

POST /v1/schedules/{scheduleId}/pause
POST /v1/schedules/{scheduleId}/resume

Pausing stops the schedule from running until you resume it. Resuming also resets the consecutive-failure counter, so a schedule that auto-paused after repeated failures starts clean.

Run now

POST /v1/schedules/{scheduleId}/trigger

Runs the capture immediately, regardless of the next scheduled time. Useful for testing a new schedule or grabbing an on-demand snapshot. The run shows up in the schedule history like any other.

Delete schedule

DELETE /v1/schedules/{scheduleId}

Deleting a schedule also deletes all associated captures. This cannot be undone.

Get schedule history

GET /v1/schedules/{scheduleId}/history

Query parameters

ParameterTypeDefaultDescription
limitinteger50Maximum executions to return

Response

limit defaults to 50 and is capped at 100. Execution status is success or failed. When change detection is on, diffScore is the measured fraction of changed pixels and changed says whether it crossed diffThreshold. deliveries records the outcome per destination.

{
  "scheduleId": "schedabc123",
  "totalExecutions": 30,
  "executions": [
    {
      "id": "exec001abc",
      "executedAt": "2025-01-15T14:00:00Z",
      "runId": "run_7f3a9c",
      "status": "success",
      "resultUrl": "https://api.allscreenshots.com/v1/screenshots/jobs/job001abc/result",
      "storageUrl": "https://storage.allscreenshots.com/job001abc.png",
      "fileSize": 245678,
      "renderTimeMs": 1234,
      "diffScore": 0.042,
      "changed": true,
      "deliveries": [
        { "type": "email", "id": "dst_a1b2c3", "status": "sent" }
      ],
      "expiresAt": "2025-04-15T14:00:00Z"
    },
    {
      "id": "exec002abc",
      "executedAt": "2025-01-14T14:00:00Z",
      "runId": "run_2b8e1d",
      "status": "failed",
      "errorCode": "TIMEOUT",
      "errorMessage": "Navigation timed out after 30000ms",
      "expiresAt": "2025-04-14T14:00:00Z"
    }
  ]
}

Examples

Daily homepage monitoring

curl -X POST 'https://api.allscreenshots.com/v1/schedules' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Daily Homepage",
    "url": "https://example.com",
    "schedule": "0 0 9 * * *",
    "timezone": "America/New_York",
    "options": {
      "fullPage": true,
      "blockAds": true,
      "blockCookieBanners": true
    },
    "destinations": [
      { "type": "webhook", "url": "https://your-server.com/webhooks/daily-capture", "secret": "whsec_..." }
    ],
    "retentionDays": 90
  }'

Hourly competitor tracking, emailed on change

curl -X POST 'https://api.allscreenshots.com/v1/schedules' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Competitor Pricing",
    "url": "https://competitor.com/pricing",
    "schedule": "hourly",
    "options": {
      "waitFor": ".pricing-table",
      "waitUntil": "networkidle"
    },
    "onlyOnChange": true,
    "diffThreshold": 0.01,
    "destinations": [
      { "type": "email", "to": ["[email protected]"], "subject": "Competitor pricing changed" }
    ],
    "retentionDays": 7
  }'

Business hours only

curl -X POST 'https://api.allscreenshots.com/v1/schedules' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Dashboard Status",
    "url": "https://internal-dashboard.example.com",
    "schedule": "0 0 9-17 * * 1-5",
    "timezone": "Europe/London",
    "options": {
      "viewport": { "width": 1920, "height": 1080 }
    }
  }'

Schedule limits

Scheduled captures are available on every plan. Each plan caps how many schedules an API key can have. The cap counts every schedule on the key, including paused ones — delete schedules you no longer need to free up room.

PlanSchedules
Free50
Starter50
Pro50
Business100
Scale500
Enterprise1000

Every run counts against your monthly screenshot quota. A daily schedule uses ~30 screenshots per month; an hourly one uses ~720. Each extra outputs entry on a run counts too.

On this page