API Reference

The Captureze API allows you to manage schedules, trigger screenshots, and access your data programmatically. Interactive documentation with request builder is available at /api/docs.

Note: API access is available on Starter and Pro plans.

Authentication

All API requests require an API key passed as a Bearer token. You can create API keys in Settings → API Keys.

curl -X GET https://captureze.com/api/schedules \
  -H "Authorization: Bearer cap_your_api_key_here"

API keys always start with cap_.

Base URL

https://captureze.com/api

Endpoints

Schedules

GET /schedules

List all schedules for your account (includes latest screenshot per schedule).

GET /schedules/:id

Get a specific schedule by ID.

POST /schedules

Create a new schedule. Takes a first screenshot immediately after creation.

Request body
{
  "name": "My Website",
  "url": "https://example.com",
  "cron_expression": "0 9 * * *",
  "full_page": false,
  "viewport_preset": "desktop",
  "diff_threshold": 5,
  "notify_on_diff": true,
  "notify_on_error": true
}

Required fields:

  • name — display name for the monitor
  • url — full URL including protocol (https://...)
  • cron_expression — standard 5-field cron (e.g. 0 9 * * * = daily at 9am)

Optional fields:

  • full_page — capture full scrollable page (default: false)
  • viewport_preset — desktop / laptop / tablet / mobile / custom
  • width, height — viewport dimensions in pixels (default: 1920×1080)
  • output_format — png / jpeg / pdf (default: png)
  • diff_threshold — % change to trigger diff notification (default: 5)
  • diff_sensitivity — low / medium / high (default: medium)
  • notify_on_success, notify_on_error, notify_on_diff — notification flags
  • custom_headers — object of extra HTTP headers to send
  • wait_for_selector — CSS selector to wait for before capture
  • hide_selectors — array of CSS selectors to hide before capture

Response: the created schedule object.

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "My Website",
  "url": "https://example.com",
  "cron_expression": "0 9 * * *",
  "width": 1920,
  "height": 1080,
  "full_page": false,
  "is_active": true,
  "viewport_preset": "desktop",
  "output_format": "png",
  "diff_threshold": 5,
  "diff_sensitivity": "medium",
  "notify_on_success": false,
  "notify_on_error": true,
  "notify_on_diff": true,
  "created_at": "2025-01-15T09:00:00Z",
  "updated_at": "2025-01-15T09:00:00Z"
}
PUT /schedules/:id

Update an existing schedule. Accepts the same fields as POST. Only provided fields are updated.

DELETE /schedules/:id

Delete a schedule and all its associated screenshots.

POST /schedules/:id/credentials

Save encrypted login credentials for sites that require authentication. Body: { "username": "...", "password": "..." }

DELETE /schedules/:id/credentials

Remove saved credentials from a schedule.

Screenshots & Captures

POST /schedules/:id/capture

Trigger an immediate screenshot for a schedule. Returns the screenshot object on completion.

Response example
{
  "id": "7f3e9a12-...",
  "schedule_id": "550e8400-...",
  "file_path": "my-website/2025-01-15T09-00-00.png",
  "file_size": 284512,
  "diff_percent": 1.3,
  "diff_image_path": "my-website/diff-2025-01-15T09-00-00.png",
  "url": "https://captureze.com/screenshots/my-website/2025-01-15T09-00-00.png",
  "thumb_url": "https://captureze.com/screenshots/my-website/thumb-2025-01-15T09-00-00.png",
  "storage_type": "platform",
  "created_at": "2025-01-15T09:00:05Z"
}
GET /schedules/:id/screenshots

List all screenshots for a schedule. Query params: ?limit=10

GET /schedules/:id/executions

Get execution history (scheduled + manual runs) with status and error details. Query params: ?limit=20

GET /schedules/:id/diff-trend

Get time-series data of visual diff percentages for charting change over time.

API Keys

GET /keys

List all API keys. The full key value is never returned after creation.

POST /keys

Create a new API key. Body: { "name": "Production App" }. The full key is returned only once.

DELETE /keys/:id

Revoke an API key. Takes effect immediately.

Webhooks

GET /webhooks

List all configured webhooks.

POST /webhooks

Create a webhook. Body: { "url": "https://...", "events": ["screenshot.completed", "diff.detected"] }. The webhook secret is returned only once.

PUT /webhooks/:id

Update a webhook URL, events, or active status.

DELETE /webhooks/:id

Delete a webhook.

POST /webhooks/:id/test

Send a test delivery to verify your endpoint is reachable.

GET /webhooks/:id/logs

Get delivery logs for a webhook. Query params: ?limit=50

Error Handling

All errors return JSON with an error field. Business logic errors also include a code field:

{
  "error": "Schedule not found"
}
{
  "error": "Site limit reached",
  "code": "SCHEDULE_LIMIT",
  "current": 5,
  "limit": 5,
  "upgrade_url": "/settings?tab=billing"
}

HTTP Status Codes

Code Meaning
200Success
201Created
400Bad request — invalid parameters or cron expression
401Unauthorized — missing or invalid API key
402Plan limit reached — code indicates which limit: SCHEDULE_LIMIT, SCREENSHOT_LIMIT, INTERVAL_LIMIT
404Resource not found
429Rate limit exceeded (see Rate Limits below)
500Server error

Rate Limits

Two independent rate limiters apply:

Global IP limit

1,000 requests per 15 minutes per IP address. Applies to all traffic regardless of authentication.

Per-user plan limit

Applies to authenticated requests.

  • Starter: 1,000 requests/hour
  • Pro: 5,000 requests/hour

When this limit is hit, the response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.

Sensitive endpoint limit

20 requests per 15 minutes per IP on /billing/checkout, /billing/portal, and /keys.

Utility Endpoints

/health is public. /validate-cron and /viewport-presets require authentication.

GET /health

Service health status (database, browserless, storage).

POST /validate-cron

Validate a cron expression. Body: { "expression": "0 9 * * *" }. Returns { "valid": true }.

GET /viewport-presets

Get predefined width/height combinations for desktop, laptop, tablet, and mobile.