Features Full Page Screenshot Wait for Selector & Delay Block Cookie Banners Custom Viewport & Device Website to PDF HTML to Image Dark Mode Image Format & Quality MCP Server Webhook Pricing Docs Blog Log In Sign Up

Screenshots

The Screenshots API is the core of ScreenshotRun. It lets you capture any website, raw HTML, or Markdown as an image or PDF, then retrieve, list, or delete screenshots you have created. All endpoints require authentication.

This page covers every endpoint. For the full list of capture parameters (viewport, format, device emulation, and more), see Screenshot Options.

How It Works

There are two ways to capture a screenshot:

  1. Synchronous (Quick Capture) — send a request and get the image back directly. No polling, no waiting. Best for simple integrations where you need the image right away.
  2. Asynchronous (Create) — send a request and get a screenshot ID back immediately. The screenshot is processed in the background. You can poll for its status or use a webhook to get notified when it is ready. Best for high-volume workloads or when you don't need the image instantly.

Quick Capture

http
GET /v1/screenshots/capture
POST /v1/screenshots/capture

The simplest way to take a screenshot. The API waits for the capture to finish and returns the image file directly — no polling needed.

Use GET with query parameters for simple requests. Use POST with a JSON body when sending large payloads like html or markdown (GET query strings have length limits).

Both methods accept the same parameters.

Example: GET with query parameters

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&width=1440&format=webp" \
  -o screenshot.webp

Example: POST with JSON body

bash
curl -X POST https://api.screenshotrun.com/v1/screenshots/capture \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1>Hello World</h1><p>Rendered from HTML</p>",
    "width": 1200,
    "height": 630
  }' \
  -o screenshot.png

Using in the browser

Because the GET endpoint returns a binary image, you can use it directly in HTML as a link or an image source. Just make sure to use a domain-restricted API key if embedding in client-side code.

html
<a href="https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&width=1280&format=png">
  Take Screenshot
</a>
Tip

To get the async JSON response instead (same behavior as POST /v1/screenshots), pass response_type=json.

Create a Screenshot

http
POST /v1/screenshots

Queues a new screenshot for capture in the background. Returns a 202 Accepted response with the screenshot object in pending status. This is the async method — the screenshot is not ready yet when you get the response.

After creating a screenshot, you can either poll for its status with Get a Screenshot, or set up a webhook to be notified automatically when it completes.

When to use async vs. sync

  • Use async (POST /screenshots) when you are capturing many screenshots, processing them in a queue, or want non-blocking behavior in your application.
  • Use sync (GET /capture) when you need the image right away and your use case is simple — a single capture at a time.

Example Request

cURL

bash
curl -X POST https://api.screenshotrun.com/v1/screenshots \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "width": 1440,
    "height": 900,
    "format": "webp",
    "full_page": true,
    "dark_mode": true
  }'

PHP

php
$response = Http::withToken(env('SCREENSHOT_API_KEY'))
    ->post('https://api.screenshotrun.com/v1/screenshots', [
        'url' => 'https://example.com',
        'width' => 1440,
        'height' => 900,
        'format' => 'webp',
        'full_page' => true,
        'dark_mode' => true,
    ]);

$screenshot = $response->json('data');
echo "Screenshot ID: " . $screenshot['id'];

Python

python
import requests

response = requests.post(
    "https://api.screenshotrun.com/v1/screenshots",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "url": "https://example.com",
        "width": 1440,
        "height": 900,
        "format": "webp",
        "full_page": True,
        "dark_mode": True,
    }
)

screenshot = response.json()["data"]
print(f"Screenshot ID: {screenshot['id']}")

JavaScript (Node.js)

javascript
const response = await fetch("https://api.screenshotrun.com/v1/screenshots", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://example.com",
    width: 1440,
    height: 900,
    format: "webp",
    full_page: true,
    dark_mode: true,
  }),
});

const { data } = await response.json();
console.log(`Screenshot ID: ${data.id}`);

Ruby

ruby
require "net/http"
require "json"
require "uri"

uri = URI("https://api.screenshotrun.com/v1/screenshots")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"
request["Content-Type"] = "application/json"
request.body = {
  url: "https://example.com",
  width: 1440,
  height: 900,
  format: "webp",
  full_page: true,
  dark_mode: true
}.to_json

response = http.request(request)
screenshot = JSON.parse(response.body)["data"]
puts "Screenshot ID: #{screenshot['id']}"

Go

go
payload := strings.NewReader(`{
  "url": "https://example.com",
  "width": 1440,
  "height": 900,
  "format": "webp",
  "full_page": true,
  "dark_mode": true
}`)

req, _ := http.NewRequest("POST", "https://api.screenshotrun.com/v1/screenshots", payload)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")

resp, err := http.DefaultClient.Do(req)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

var result struct {
    Data struct {
        ID string `json:"id"`
    } `json:"data"`
}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Screenshot ID: %s\n", result.Data.ID)

Response (202 Accepted)

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "pending",
    "url": "https://example.com",
    "options": {
      "width": 1440,
      "height": 900,
      "format": "webp",
      "quality": 80,
      "full_page": true,
      "device": "desktop",
      "block_ads": false,
      "block_cookies": true,
      "dark_mode": true,
      "delay": 0,
      "timeout": 30,
      "retina": false
    },
    "estimated_time": 5,
    "created_at": "2026-03-09T10:30:00.000000Z",
    "links": {
      "self": "https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000"
    }
  }
}

Screenshot Statuses

After you create a screenshot, it moves through these statuses:

StatusMeaning
pendingThe screenshot is queued and waiting to be processed.
processingA browser is loading the page and taking the screenshot right now.
completedThe screenshot is ready. You can download the image.
failedSomething went wrong. Check the error field for details.

Polling for Completion

If you are not using webhooks, you can poll for the screenshot status. Here is a simple polling example in Python:

python
import time
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.screenshotrun.com/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Create screenshot
response = requests.post(
    f"{BASE_URL}/screenshots",
    headers=headers,
    json={"url": "https://example.com"}
)
screenshot_id = response.json()["data"]["id"]

# Poll until ready
while True:
    status_response = requests.get(
        f"{BASE_URL}/screenshots/{screenshot_id}",
        headers=headers,
    )
    data = status_response.json()["data"]

    if data["status"] == "completed":
        # Download the image
        image_response = requests.get(
            f"{BASE_URL}/screenshots/{screenshot_id}/image",
            headers=headers,
        )
        with open("screenshot.png", "wb") as f:
            f.write(image_response.content)
        print("Screenshot saved!")
        break
    elif data["status"] == "failed":
        print(f"Failed: {data['error']['message']}")
        break

    time.sleep(2)  # Wait 2 seconds before next poll
Tip

For production workloads, use webhooks instead of polling. They are more efficient and give you instant notifications.

Get a Screenshot

http
GET /v1/screenshots/{id}

Returns the screenshot object with its current status and details. Use this to check whether an async screenshot has finished processing.

Example Request

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000

Response — Completed

When the screenshot is ready, the response includes full metadata: image dimensions, file size, processing time, and download links.

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "completed",
    "url": "https://example.com",
    "options": {
      "width": 1440,
      "height": 900,
      "format": "webp",
      "quality": 80,
      "full_page": true,
      "device": "desktop",
      "block_ads": false,
      "block_cookies": true,
      "dark_mode": true,
      "delay": 0,
      "timeout": 30,
      "retina": false
    },
    "file_size": 245760,
    "mime_type": "image/webp",
    "width": 1440,
    "height": 3200,
    "processing_time_ms": 3450,
    "completed_at": "2026-03-09T10:30:05.000000Z",
    "expires_at": "2026-04-09T10:30:05.000000Z",
    "created_at": "2026-03-09T10:30:00.000000Z",
    "links": {
      "self": "https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000",
      "image": "https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000/image"
    }
  }
}

Response — Failed

If something went wrong during capture, the error field tells you what happened. Common causes include page timeouts, invalid URLs, and blocked content.

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "failed",
    "url": "https://example.com",
    "options": { ... },
    "error": {
      "message": "Page load timed out after 30 seconds.",
      "code": "TIMEOUT"
    },
    "created_at": "2026-03-09T10:30:00.000000Z",
    "links": {
      "self": "https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000"
    }
  }
}

Get Screenshot Image

http
GET /v1/screenshots/{id}/image

Downloads the actual image file. This only works for screenshots with completed status. The response includes the correct Content-Type header for the format you chose (e.g. image/png, image/webp, application/pdf).

Example Request

bash
# Download to file
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://api.screenshotrun.com/v1/screenshots/550e8400-.../image \
  -o screenshot.webp

Responses

StatusDescription
200 OKImage file with appropriate Content-Type header (image/png, image/jpeg, image/webp, image/avif, image/tiff, or application/pdf)
404 Not FoundScreenshot is not ready yet (status is pending or processing)
410 GoneScreenshot image has expired and been deleted (see Image Retention below)

Image Retention

Screenshots are stored temporarily. After the retention period expires, the image file is automatically deleted. The metadata (status, options, timestamps) stays available through the API, but the image itself returns 410 Gone.

How long your screenshots are kept depends on your plan:

PlanRetention
Free24 hours
Starter48 hours
Pro7 days
Growth30 days
Business30 days
Note

Download images as soon as they are ready, or use webhooks to trigger automatic downloads when screenshots complete. You can also create signed URLs to share images without exposing your API key.

List Screenshots

http
GET /v1/screenshots

Returns a paginated list of your screenshots, newest first. You can filter by status and date range, which is useful for building dashboards or audit logs.

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger20Results per page (max 100)
statusstringFilter by status: pending, processing, completed, failed
sort_bystringcreated_atSort field
sort_dirstringdescSort direction: asc or desc
date_fromstringFilter screenshots created after this date (ISO 8601)
date_tostringFilter screenshots created before this date (ISO 8601)

Example Request

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.screenshotrun.com/v1/screenshots?status=completed&per_page=10&sort_dir=desc"

Response

json
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "status": "completed",
      "url": "https://example.com",
      "options": { ... },
      "file_size": 245760,
      "mime_type": "image/webp",
      "width": 1440,
      "height": 3200,
      "processing_time_ms": 3450,
      "completed_at": "2026-03-09T10:30:05.000000Z",
      "expires_at": "2026-04-09T10:30:05.000000Z",
      "created_at": "2026-03-09T10:30:00.000000Z",
      "links": {
        "self": "...",
        "image": "..."
      }
    }
  ],
  "links": {
    "first": "https://api.screenshotrun.com/v1/screenshots?page=1",
    "last": "https://api.screenshotrun.com/v1/screenshots?page=5",
    "prev": null,
    "next": "https://api.screenshotrun.com/v1/screenshots?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 5,
    "links": [
      {"url": null, "label": "« Previous", "page": null, "active": false},
      {"url": "...?page=1", "label": "1", "page": 1, "active": true},
      {"url": "...?page=2", "label": "2", "page": 2, "active": false},
      {"url": "...?page=2", "label": "Next »", "page": 2, "active": false}
    ],
    "path": "https://api.screenshotrun.com/v1/screenshots",
    "per_page": 10,
    "to": 10,
    "total": 48
  }
}

Delete a Screenshot

http
DELETE /v1/screenshots/{id}

Permanently deletes a screenshot and its image file. This action cannot be undone.

Example Request

bash
curl -X DELETE -H "Authorization: Bearer YOUR_API_KEY" \
  https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000

Response

Returns 204 No Content on success with an empty body.

Feature Availability

Some parameters are only available on certain plans. If you use a feature not included in your plan, the API returns a 422 error telling you which feature requires an upgrade. Check your current plan details anytime via GET /v1/account.

Feature / ParameterFreeStarterProBusiness
url, width, heightYesYesYesYes
full_pageYesYesYesYes
delayYesYesYesYes
block_cookiesYesYesYesYes
selectorYesYesYesYes
wait_for_selectorYesYesYesYes
omit_backgroundYesYesYesYes
reduced_motionYesYesYesYes
device (mobile/tablet)YesYesYes
retinaYesYesYes
block_adsYesYesYes
block_chatsYesYesYes
format: pdfYesYesYes
webhook_urlYesYesYes
html (HTML rendering)YesYesYes
user_agentYesYesYes
headers, cookiesYesYesYes
dark_modeYesYes
css, jsYesYes
stealthYesYes
timezoneYesYes
extract_metadataYesYes
markdown (Markdown rendering)YesYes
Batch APIYesYes
Signed URLsYesYesYes
PDF options (landscape, page size, margins)YesYesYes
geolocationYes
proxyYes

Next Steps

  • Screenshot Options — full parameter reference, grouped by category, with examples for every option
  • Caching — avoid redundant captures by caching screenshots
  • Signed URLs — share screenshots without exposing your API key
  • Batch Screenshots — capture up to 100 URLs in a single request
  • Webhooks — get notified when screenshots are ready