Get started
Introduction
What the API does and the shape of every call.
SnoopScan turns a public web page into something a program can use. You send a URL; you get markdown, HTML, links, a summary, a screenshot, or JSON in a schema you wrote. Pages that only exist once JavaScript has run come back the same way as static ones, and so do pages that block ordinary HTTP requests.
Request and response
There is one shape and every tool uses it. A URL or a list of them, a few options, and a response that always looks the same:
import requestsr = requests.post( 'https://api.snoopscan.com/v1/scrape', headers={'Authorization': 'Bearer sk_YOUR_KEY'}, json={ 'url': 'https://example.com/pricing', 'formats': [ 'markdown', 'links' ], 'onlyMainContent': True },)print(r.json())
const r = await fetch('https://api.snoopscan.com/v1/scrape', { method: 'POST', headers: { Authorization: 'Bearer sk_YOUR_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ "url": "https://example.com/pricing", "formats": [ "markdown", "links" ], "onlyMainContent": true }),});console.log(await r.json());
curl -X POST https://api.snoopscan.com/v1/scrape \ -H 'Authorization: Bearer sk_YOUR_KEY' \ -H 'Content-Type: application/json' \ -d '{ "url": "https://example.com/pricing", "formats": [ "markdown", "links" ], "onlyMainContent": true}'
Every tool answers with success, data, and what the call cost.
A success is {"success": true, "data": {…}}. A failure is {"success": false, "error": {…}} with a code you can branch on. There is no third case, and no endpoint that answers differently.
Try it before you sign up.
The Playground runs these same calls in the browser with no account and no key, so you can see the shape of a response before you write anything.
Start here
- Your first request — a key and one call, about a minute.
- Authentication — one bearer key opens every tool.
- Output formats — pick what comes back.
- Errors — every code and what to do about it.
Endpoints
Every one of them runs on the same key and the same allowance.
| Tool | Endpoint | What it is for |
|---|---|---|
| Scrape | POST /v1/scrape |
One URL into clean markdown for a RAG pipeline, an LLM prompt or an archive. Navigation, cookie walls and boilerplate stay out of it. |
| Crawl | POST /v1/crawl |
A documentation site, a help centre or a whole blog, page by page, with depth and path filters. Poll the job or take a webhook. |
| Map | POST /v1/map |
Every URL on a site in seconds, for a content audit, a migration inventory, or to find the pages worth scraping before you spend on them. |
| Search | POST /v1/search |
Web search with every result already scraped, so a research agent reads whole pages instead of guessing from snippets. |
| Extract | POST /v1/extract |
A JSON schema and up to 100 URLs in, rows out — pricing tables, spec sheets, job listings. Reads the page's own structured markup first. |
| Batch | POST /v1/batch/scrape |
Thousands of URLs as one job, for a backfill or a nightly refresh, running at whatever concurrency your plan allows. Poll it or take a webhook. |
| Products | POST /v1/products |
A whole store catalogue with prices, variants and stock, hundreds of products in one call. Competitor pricing without a crawl. |
| Posts | POST /v1/posts |
Every article from a blog or forum, hundreds at a time, for a content aggregator, a newsroom feed or a training set. |
| Monitor | POST /v1/monitor |
Watch a page on a schedule and get a webhook only when it really changed. Price drops, job boards, terms and docs. |
| Places | POST /v1/places/search |
Business listings by trade and town, with the website, the phone number and the people behind it. Lead lists, ready to work. |
| Domain | POST /v1/domain |
Domain age, registrar, hosting and backlinks for any site. Judge a source, size up a competitor, or check a domain was not registered last week. |
| Company | POST /v1/company |
One company domain in, the details a lead list sells out: name, phone, LinkedIn, headcount, industry, plus the emails and socials the site publishes. |
You are not charged for a request that failed.
A page you already fetched, re-read from cache, costs nothing either; one someone else had already fetched costs a single credit. Every response carries a
cost object saying which it was — see Credits.