Snapshots
Snapshots are the captured results — each one contains a screenshot image, and optionally an on-the-fly PDF export and HTML source. Snapshots belong to a monitor and are created either automatically (on schedule) or manually (via the trigger endpoint). Each snapshot tracks the HTTP status code, response time, and page weight of the captured page.
List snapshots
Returns snapshots for a specific monitor, newest first. You can filter by date range and status — useful for pulling snapshots from a specific time period or finding only failed captures. The response includes signed URLs for downloading each file type.
/v1/monitors/{monitorId}/snapshotsQuery parameters
| Parameter | Type | Description |
|---|---|---|
captured_after | string | Only snapshots after this date (ISO 8601, e.g. 2026-09-01) |
captured_before | string | Only snapshots before this date |
status | string | Filter: completed, failed, pending, processing |
sort | string | captured_at (default), created_at, http_status, response_time_ms, page_weight_bytes |
order | string | desc (default) or asc |
per_page | integer | Items per page (default: 20) |
# Last week's completed snapshots
curl "https://api.snapshotarchive.com/v1/monitors/42/snapshots?status=completed&captured_after=2026-09-24" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"$response = Http::withToken('YOUR_API_KEY')
->get('https://api.snapshotarchive.com/v1/monitors/42/snapshots', [
'status' => 'completed',
'captured_after' => '2026-09-24',
]);
$snapshots = $response->json('data');resp = requests.get(f'{BASE}/monitors/42/snapshots', headers=headers,
params={'status': 'completed', 'captured_after': '2026-09-24'})
snapshots = resp.json()['data']const { data: snapshots } = await fetch(
`${BASE}/monitors/42/snapshots?status=completed&captured_after=2026-09-24`,
{ headers }
).then(r => r.json());uri = URI("#{BASE}/monitors/42/snapshots?status=completed&captured_after=2026-09-24")
req = Net::HTTP::Get.new(uri, headers)
resp = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
snapshots = JSON.parse(resp.body)['data']req, _ := http.NewRequest("GET",
BASE+"/monitors/42/snapshots?status=completed&captured_after=2026-09-24", nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
resp, _ := http.DefaultClient.Do(req)Response
{
"data": [
{
"id": "9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b",
"monitor_id": 42,
"status": "completed",
"http_status": 200,
"response_time_ms": 1250,
"page_weight_bytes": 1845000,
"files": {
"screenshot_url": "https://storage.example.com/signed-url...",
"pdf_url": "https://api.snapshotarchive.com/v1/snapshots/9e8f.../pdf",
"html_url": "https://storage.example.com/signed-url..."
},
"captured_at": "2026-09-30T12:00:00Z",
"created_at": "2026-09-30T12:00:00Z"
}
],
"meta": { "current_page": 1, "per_page": 20, "total": 47, "last_page": 3 }
}Get the latest snapshot
A shortcut to retrieve the most recent completed snapshot for a monitor. Instead of listing snapshots and picking the first one, this gives you the latest result directly. Returns 404 if the monitor has no completed snapshots yet.
/v1/monitors/{monitorId}/latest-snapshotcurl "https://api.snapshotarchive.com/v1/monitors/42/latest-snapshot" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"$client = new \GuzzleHttp\Client();
$response = $client->get('https://api.snapshotarchive.com/v1/monitors/42/latest-snapshot', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY',
'Accept' => 'application/json',
],
]);
$data = json_decode($response->getBody(), true);import requests
response = requests.get(
"https://api.snapshotarchive.com/v1/monitors/42/latest-snapshot",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Accept": "application/json",
},
)
data = response.json()const response = await fetch("https://api.snapshotarchive.com/v1/monitors/42/latest-snapshot", {
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Accept": "application/json",
},
});
const data = await response.json();require "net/http"
require "json"
uri = URI("https://api.snapshotarchive.com/v1/monitors/42/latest-snapshot")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"
request["Accept"] = "application/json"
response = http.request(request)
data = JSON.parse(response.body)req, _ := http.NewRequest("GET", "https://api.snapshotarchive.com/v1/monitors/42/latest-snapshot", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()Get a snapshot by UUID
Retrieves a single snapshot by its UUID. The response includes download URLs for the screenshot, PDF, and HTML files (if available). Use this to poll a snapshot's status after triggering a capture — check the status field until it becomes completed or failed.
/v1/snapshots/{uuid}curl "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"$client = new \GuzzleHttp\Client();
$response = $client->get('https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY',
'Accept' => 'application/json',
],
]);
$data = json_decode($response->getBody(), true);import requests
response = requests.get(
"https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Accept": "application/json",
},
)
data = response.json()const response = await fetch("https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b", {
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Accept": "application/json",
},
});
const data = await response.json();require "net/http"
require "json"
uri = URI("https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"
request["Accept"] = "application/json"
response = http.request(request)
data = JSON.parse(response.body)req, _ := http.NewRequest("GET", "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()Snapshot statuses
| Status | Description |
|---|---|
pending | Queued, waiting for processing |
processing | Browser is capturing the page |
completed | Capture finished, files available for download |
failed | Capture failed (check last_error_message on the monitor) |
Delete a snapshot
Permanently removes a snapshot and all its associated files (screenshot, HTML). This cannot be undone. Returns 204 No Content on success.
/v1/snapshots/{uuid}curl -X DELETE "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"$response = Http::withToken('YOUR_API_KEY')
->delete('https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b');
// 204 No Contentresponse = requests.delete(
'https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b',
headers={'Authorization': 'Bearer YOUR_API_KEY'}
) # 204 No Contentconst response = await fetch('https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b', {
method: 'DELETE',
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}); // 204 No Contentuuid = '9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b'
uri = URI("https://api.snapshotarchive.com/v1/snapshots/#{uuid}")
req = Net::HTTP::Delete.new(uri)
req['Authorization'] = 'Bearer YOUR_API_KEY'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
# 204 No Contentreq, _ := http.NewRequest("DELETE", "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
// 204 No ContentDownload screenshot, PDF, and HTML
Each completed snapshot can have up to three downloadable files: a PNG screenshot, a PDF document, and the raw HTML source. Use these endpoints to download individual files. The screenshot and PDF endpoints return the file directly; the HTML endpoint redirects to a signed storage URL.
PDF and HTML downloads require a Starter plan or above. If your plan doesn't include these features, the API returns 403.
Download the PNG screenshot image. If watermarking is enabled on the monitor, the watermark is applied dynamically.
Download the PDF export. The PDF is generated on-the-fly from the screenshot with a metadata cover page including capture details and SHA-256 integrity hash. Requires Starter+.
Download the raw HTML source. Redirects to a signed URL. Requires Starter+.
# Download screenshot as PNG
curl -L "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../screenshot" \
-H "Authorization: Bearer YOUR_API_KEY" \
-o screenshot.png
# Download PDF (generated on-the-fly)
curl "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../pdf" \
-H "Authorization: Bearer YOUR_API_KEY" \
-o page.pdf
# Download HTML source
curl -L "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../html" \
-H "Authorization: Bearer YOUR_API_KEY" \
-o source.html$uuid = '9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b';
// Download screenshot
$screenshot = Http::withToken('YOUR_API_KEY')
->get("https://api.snapshotarchive.com/v1/snapshots/{$uuid}/screenshot");
Storage::put('screenshot.png', $screenshot->body());
// Download PDF (generated on-the-fly)
$pdf = Http::withToken('YOUR_API_KEY')
->get("https://api.snapshotarchive.com/v1/snapshots/{$uuid}/pdf");
Storage::put('page.pdf', $pdf->body());
// Download HTML source
$html = Http::withToken('YOUR_API_KEY')
->get("https://api.snapshotarchive.com/v1/snapshots/{$uuid}/html");
Storage::put('source.html', $html->body());uuid = '9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b'
headers = {'Authorization': 'Bearer YOUR_API_KEY'}
# Download screenshot
r = requests.get(f'https://api.snapshotarchive.com/v1/snapshots/{uuid}/screenshot',
headers=headers)
with open('screenshot.png', 'wb') as f:
f.write(r.content)
# Download PDF (generated on-the-fly)
r = requests.get(f'https://api.snapshotarchive.com/v1/snapshots/{uuid}/pdf',
headers=headers)
with open('page.pdf', 'wb') as f:
f.write(r.content)
# Download HTML source
r = requests.get(f'https://api.snapshotarchive.com/v1/snapshots/{uuid}/html',
headers=headers)
with open('source.html', 'wb') as f:
f.write(r.content)import fs from 'fs';
const uuid = '9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b';
const headers = { 'Authorization': 'Bearer YOUR_API_KEY' };
const base = `https://api.snapshotarchive.com/v1/snapshots/${uuid}`;
// Download screenshot
const screenshot = await fetch(`${base}/screenshot`, { headers });
fs.writeFileSync('screenshot.png', Buffer.from(await screenshot.arrayBuffer()));
// Download PDF (generated on-the-fly)
const pdf = await fetch(`${base}/pdf`, { headers });
fs.writeFileSync('page.pdf', Buffer.from(await pdf.arrayBuffer()));
// Download HTML source
const html = await fetch(`${base}/html`, { headers, redirect: 'follow' });
fs.writeFileSync('source.html', Buffer.from(await html.arrayBuffer()));uuid = '9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b'
# Download screenshot
uri = URI("https://api.snapshotarchive.com/v1/snapshots/#{uuid}/screenshot")
req = Net::HTTP::Get.new(uri)
req['Authorization'] = 'Bearer YOUR_API_KEY'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
File.binwrite('screenshot.png', res.body)
# Download PDF (generated on-the-fly)
uri = URI("https://api.snapshotarchive.com/v1/snapshots/#{uuid}/pdf")
req = Net::HTTP::Get.new(uri)
req['Authorization'] = 'Bearer YOUR_API_KEY'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
File.binwrite('page.pdf', res.body)uuid := "9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b"
base := "https://api.snapshotarchive.com/v1/snapshots/" + uuid
// Download screenshot
req, _ := http.NewRequest("GET", base+"/screenshot", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
os.WriteFile("screenshot.png", data, 0644)
// Download PDF (generated on-the-fly)
req, _ = http.NewRequest("GET", base+"/pdf", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
resp, _ = http.DefaultClient.Do(req)
defer resp.Body.Close()
data, _ = io.ReadAll(resp.Body)
os.WriteFile("page.pdf", data, 0644)Forward snapshot via email
Send a snapshot to one or more email addresses with all available attachments (screenshot, full-page screenshot, HTML source, PDF with metadata). Ideal for compliance archiving, SMTP journaling (e.g. Intradyn, Global Relay), or sending records to a team inbox.
Queue an email to the specified recipient(s) with the snapshot data and files as attachments.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Recipient email address(es), comma-separated. Max 5. |
curl -X POST "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../forward" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'$response = Http::withToken('YOUR_API_KEY')
->post('https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../forward', [
'email' => '[email protected]',
]);response = requests.post(
'https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../forward',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={'email': '[email protected]'}
)const response = await fetch('https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../forward', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ email: '[email protected]' })
});uri = URI('https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../forward')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req['Authorization'] = 'Bearer YOUR_API_KEY'
req.body = { email: '[email protected]' }.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }body := strings.NewReader(`{"email":"[email protected]"}`)
req, _ := http.NewRequest("POST", "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../forward", body)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)Response
{
"data": {
"message": "Snapshot forwarding queued.",
"recipients": ["[email protected]"],
"snapshot_id": "9e8f7a6b-5c4d-3e2f-1a0b-9c8d7e6f5a4b"
}
}Email contents
The forwarded email includes:
- Subject:
[Snapshot Archive] example.com — 2026-10-01 15:30 UTC - Body: URL, timestamp, HTTP status, page size, response time, SHA-256 hash of HTML source
- Attachments: viewport screenshot, full-page screenshot, HTML source, PDF with metadata cover page
Total attachment size is limited to ~25MB. Files exceeding the limit are skipped automatically.
Auto-forwarding via monitor settings
You can also configure automatic forwarding on a per-monitor basis using the Update Monitor endpoint:
{
"forward_enabled": true,
"forward_when": "every",
"forward_to": ["[email protected]", "[email protected]"],
"forward_attach": ["screenshot", "full_page", "certificate", "html"]
}| Field | Type | Description |
|---|---|---|
forward_enabled | boolean | Enable/disable auto-forwarding |
forward_when | string | every — every capture, changes — only significant visual changes, digest — daily summary, manual — no auto-forward |
forward_to | array | Recipient email addresses (max 5). Each gets a separate email. |
forward_attach | array | Files to attach: screenshot, full_page, certificate (PDF), html |
Bulk export as ZIP
Download multiple snapshots from a monitor as a single ZIP archive. You can filter by date range and choose which file types to include. The ZIP organizes files by timestamp, so each snapshot's files are in a clearly labeled folder. Requires Starter plan or above.
/v1/monitors/{monitorId}/exportQuery parameters
| Parameter | Type | Description |
|---|---|---|
captured_after | string | Start date (ISO 8601) |
captured_before | string | End date (ISO 8601) |
include | string | Comma-separated file types: screenshot, pdf, html (default: screenshot) |
limit | integer | Max snapshots to include, 1–50 (default: 50) |
# Export last month's screenshots + PDFs
curl -X POST "https://api.snapshotarchive.com/v1/monitors/42/export" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d "captured_after=2026-09-01&captured_before=2026-09-30&include=screenshot,pdf" \
-o export.zip$client = new \GuzzleHttp\Client();
$response = $client->post('https://api.snapshotarchive.com/v1/monitors/42/export', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY',
],
'form_params' => [
'captured_after' => '2026-09-01',
'captured_before' => '2026-09-30',
'include' => 'screenshot,pdf',
],
'sink' => 'export.zip',
]);
// Check X-Export-Snapshot-Count and X-Export-File-Count headersimport requests
response = requests.post(
"https://api.snapshotarchive.com/v1/monitors/42/export",
headers={"Authorization": "Bearer YOUR_API_KEY"},
data={
"captured_after": "2026-09-01",
"captured_before": "2026-09-30",
"include": "screenshot,pdf",
},
stream=True,
)
with open("export.zip", "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)const response = await fetch("https://api.snapshotarchive.com/v1/monitors/42/export", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/x-www-form-urlencoded",
},
body: "captured_after=2026-09-01&captured_before=2026-09-30&include=screenshot,pdf",
});
const blob = await response.blob();
// Save blob to filerequire "net/http"
uri = URI("https://api.snapshotarchive.com/v1/monitors/42/export")
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.set_form_data(
"captured_after" => "2026-09-01",
"captured_before" => "2026-09-30",
"include" => "screenshot,pdf"
)
response = http.request(request)
File.open("export.zip", "wb") { |f| f.write(response.body) }data := url.Values{
"captured_after": {"2026-09-01"},
"captured_before": {"2026-09-30"},
"include": {"screenshot,pdf"},
}
req, _ := http.NewRequest("POST", "https://api.snapshotarchive.com/v1/monitors/42/export",
strings.NewReader(data.Encode()))
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
out, _ := os.Create("export.zip")
defer out.Close()
io.Copy(out, resp.Body)The response headers include X-Export-Snapshot-Count and X-Export-File-Count so you know how many files are in the archive.
Download snapshot package
Download all available files for a single snapshot as a ZIP. The archive includes screenshot.png, document.pdf, and source.html (whichever files exist). Requires Starter plan or above.
/v1/snapshots/{uuid}/packagecurl -L "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../package" \
-H "Authorization: Bearer YOUR_API_KEY" \
-o snapshot-package.zip$client = new \GuzzleHttp\Client();
$response = $client->get('https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../package', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY',
],
'sink' => 'snapshot-package.zip',
]);import requests
response = requests.get(
"https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../package",
headers={"Authorization": "Bearer YOUR_API_KEY"},
stream=True,
)
with open("snapshot-package.zip", "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)const response = await fetch("https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../package", {
headers: {
"Authorization": "Bearer YOUR_API_KEY",
},
});
const blob = await response.blob();
// Save blob to filerequire "net/http"
uri = URI("https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../package")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"
response = http.request(request)
File.open("snapshot-package.zip", "wb") { |f| f.write(response.body) }req, _ := http.NewRequest("GET", "https://api.snapshotarchive.com/v1/snapshots/9e8f7a6b-.../package", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
out, _ := os.Create("snapshot-package.zip")
defer out.Close()
io.Copy(out, resp.Body)