SnoopScan
Working with it

Jobs and webhooks

Long crawls and batches, without polling.

Reading one page is immediate. Reading a site is not, so Crawl and Batch answer straight away with a job id and get on with it.

import requestsr = requests.post(    'https://api.snoopscan.com/v1/crawl',    headers={'Authorization': 'Bearer sk_YOUR_KEY'},    json={        'url': 'https://example.com',        'limit': 100,        'maxDepth': 3,        'webhook': 'https://hooks.example.com/snoop'    },)print(r.json())
const r = await fetch('https://api.snoopscan.com/v1/crawl', {  method: 'POST',  headers: { Authorization: 'Bearer sk_YOUR_KEY', 'Content-Type': 'application/json' },  body: JSON.stringify({      "url": "https://example.com",      "limit": 100,      "maxDepth": 3,      "webhook": "https://hooks.example.com/snoop"  }),});console.log(await r.json());
curl -X POST https://api.snoopscan.com/v1/crawl \  -H 'Authorization: Bearer sk_YOUR_KEY' \  -H 'Content-Type: application/json' \  -d '{    "url": "https://example.com",    "limit": 100,    "maxDepth": 3,    "webhook": "https://hooks.example.com/snoop"}'
Returns a job id immediately. Pages arrive as they are read.

Polling

GET /v1/crawl/{id} gives the job's status and how far it has got. GET /v1/crawl/{id}/pages pages through what has been read so far with a cursor, so you can start using results before the job finishes. Errors, if there were any, are on /errors.

Webhooks

Better: give a webhook URL when you start the job and nothing has to poll at all. We call you when the job finishes, and monitors call you when a watched page actually changed.

Every webhook is signed with your key's signing secret. Verify the signature before you trust the body — the URL is public, and a signature is the only thing separating our call from anyone else's.

Failed deliveries

Delivery is retried with a widening gap between attempts. A job's results do not depend on the webhook: if every delivery fails, the job is still finished and still readable by polling. A webhook is a convenience, never the only copy.

Answer fast and do the work later. Return 200 as soon as you have the body; if you do the processing before replying, a slow queue on your side looks like a failed delivery on ours.