Create a job
/v1/jobsAPI keyNested types: screenshot | extract | visibility | inspect | performance | journey | crawl. Credits = sum of nested estimates.
| Name | Type | Required | Description |
|---|---|---|---|
requests | array | required | List of { type, body } operations to run sequentially. |
requests[].type | string | required | screenshot | extract | visibility | inspect | performance | journey | crawl. |
requests[].body | object | required | Same body shape as the matching POST /v1/… endpoint. |
webhook_url | string | optional | HTTPS URL to notify when the job finishes. |
webhook_secret | string | optional | HMAC secret for this job (overrides key/env secret). |
curl -X POST https://scout.macrocontent.dev/v1/jobs \
-H "Authorization: Bearer sk_scout_…" \
-H "Content-Type: application/json" \
-d @job.json{
"webhook_url": "https://hooks.example.com/scout",
"webhook_secret": "whsec_…",
"requests": [
{ "type": "screenshot", "body": { "url": "https://example.com", "format": "jpeg" } },
{ "type": "inspect", "body": { "url": "https://example.com", "include": ["meta"] } },
{
"type": "journey",
"body": {
"debug": { "on_error_only": true },
"steps": [
{ "type": "navigate", "url": "https://example.com" },
{ "type": "extract", "fields": [{ "name": "h1", "selector": "h1", "type": "text" }] }
]
}
}
]
}Poll
/v1/jobs/:idAPI keyPoll status/results until expires_at (default TTL 1800s). 0 credits.
curl https://scout.macrocontent.dev/v1/jobs/job_… \
-H "Authorization: Bearer sk_scout_…"Statuses: queued → running → completed | failed. Results live until expires_at (default ~1800s) — Scout is not a long-term archive. Large jobs (many screenshots / debug journeys) can produce multi‑MB JSON; keep batches modest or omit journey debug in production.
Journey inside a job
Nested journey bodies support the same fields as POST /v1/journey, including debug. Prefer debug only while developing — batch responses get large.
Webhook HMAC
When a secret is available, Scout POSTs the job result and signs it with:
X-Scout-Timestamp— unix secondsX-Scout-Signature—sha256=<hex>of HMAC-SHA256(secret,"${timestamp}.${rawBody}")
Secret resolution order: job webhook_secret → key webhook secret → env SCOUT_WEBHOOK_SECRET.
const crypto = require('crypto');
function verify(secret, timestamp, signatureHeader, rawBody, maxAge = 300) {
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > maxAge) return false;
const expected = 'sha256=' + crypto.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`).digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
}