Quickstart
- Get a key — register, no card. Keys start with
qd_live_. - Call scrape — POST JSON to
/v1/scrape. Copy, replace the key, run it. - Read
payload— Markdown is inpayload.content.payload.usageis what the call cost.
curl -X POST "https://api.quanticdata.io/v1/scrape" \
-H "Authorization: Bearer qd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "format": "markdown"}'
Authentication
Host https://api.quanticdata.io/v1. Every request sends Authorization: Bearer qd_live_… and Content-Type: application/json. One key covers every Data API and proxy generation. x-api-key is accepted as a fallback; do not put the key in the query string in production.
To import this API (Postman, Insomnia, Stoplight and similar): OpenAPI 3.0 at https://quanticdata.io/docs/openapi.yaml (JSON twin openapi.json) or the Postman Collection v2.1 at https://quanticdata.io/docs/postman.json. GraphQL and Kafka are not offered — REST only.
PAYG includes $2 of free usage every month and 60 requests per minute. Subscription tiers raise the cap and discount unit prices — see pricing and plans.
Envelope
Success is {"type":"response","message":"…","payload":{…}}. Failure is {"type":"error","message":"…"} and costs nothing. List endpoints also fill pagination. Billed calls add payload.usage (cost_usd, free_usd, paid_usd).
{
"type": "response",
"message": "Extraction successful",
"payload": { "content": "…", "engine": "tls", "usage": { "cost_usd": 0.0002 } }
}
Scrape
POST /v1/scrape alias /v1/scraper/extract $0.0002 · render $0.001
One URL through the residential pool, returned as Markdown, HTML or text. Starts on a TLS-fingerprint tier and escalates to a stealth browser only on a block, or when you set render: true.
| Param | Type | Default | Description |
|---|---|---|---|
| url req | string | required | The page to fetch (http/https, max 2048 chars). Optional when you pass html instead. |
| format | string | markdown | markdown | html | text. format: "raw" is accepted as an alias for html. |
| formats | string[] | — | Extra formats to return together under formats in the response. |
| render | boolean | false | Force the stealth headless browser (JS execution). Bills the rendered rate. |
| engine | string | auto | auto | tls | fetch | render. auto starts on the cheap TLS tier and escalates to a browser only on a block; tls never escalates. |
| mobile | boolean | false | Mobile viewport and user agent (render mode). |
| screenshot | bool | "fullPage" | off | Base64 PNG of the page, render mode: true = viewport, "fullPage" = whole page. |
| country / state / city | string | — | Proxy exit geo (ISO country code; state/city require country). |
| rotation | string | rotating | rotating (new IP per request) | sticky. |
| sessionId | string | auto | Sticky session id (max 64 chars, generated if omitted). |
| sessionDuration | number | 10 | Sticky session lifetime in minutes (3–1440). |
| contentMode | string | smart | smart (page minus nav/footer/cookie chrome) | article (Readability main article) | full (whole body). Alias: content_mode. |
| include_links | boolean | false | Also return the page's de-duplicated absolute links. Alias: includeLinks. |
| waitMs | number | — | Extra wait after load before capture (render mode, max 15000). |
| waitForSelector | string | — | Wait until this CSS selector appears (render mode). |
| scrollToBottom | boolean | false | Auto-scroll to trigger lazy-loaded content (render mode). |
| actions | object[] | — | Ordered interactions before capture (max 20), e.g. {"click": "#accept"}, {"scroll": "bottom"}. |
| xhr | boolean | false | Record the page's XHR/fetch traffic under xhr (forces render). |
| extract | object | — | CSS selector schema, e.g. {"price": ".price"} — returns a structured data object. |
| headers | object | — | Extra request headers replayed to the target (max 32; hop-by-hop headers rejected). |
| cookies | object | — | name → value cookies sent to the target (max 50). |
| mode | string | full | "summary" returns metadata only (title, description, canonical…) — the cheap mode for audits. |
| ai_prompt / ai_schema | string / object | — | LLM extraction: natural-language prompt and/or JSON Schema. Result under payload.ai.data. |
| html | string | — | Convert markup you already have (max 5MB) — no fetch, no proxy bandwidth. |
Request
curl -X POST "https://api.quanticdata.io/v1/scrape" \
-H "Authorization: Bearer qd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "format": "markdown"}'
{
"type": "response",
"message": "Extraction successful",
"payload": {
"url": "https://example.com",
"finalUrl": "https://example.com/",
"status": 200,
"title": "Example Domain",
"format": "markdown",
"content": "# Example Domain\n\nThis domain is for use in…",
"engine": "tls",
"usage": { "cost_usd": 0.0002, "free_usd": 0.0002, "paid_usd": 0 }
}
}
Optional fields appear only when requested: data (extract), links (include_links), screenshot, xhr, formats, ai. Guide: Web Scraping API.
SERP
POST /v1/serp alias /v1/scraper/serp from $0.0005 · render $0.002
Structured search results: organic, ads, People Also Ask, related searches, knowledge panels and Google AI Overviews, across 17 verticals on Google, Bing and DuckDuckGo.
| Param | Type | Default | Description |
|---|---|---|---|
| query req | string | required* | The search. *Optional for ID-addressed verticals: place_details (with place_id/data_id), product (product_id), flights, lens, reviews (data_id). |
| engine | string | google | bing | duckduckgo. | |
| search_type | string | search | search, shopping, images, news, places, maps, videos, scholar, jobs, autocomplete, place_details, hotels, flights, events, product, lens, reviews, trends. Alias: type. |
| country | string | — | ISO country — proxy exit and engine locale. Alias: gl. |
| lang | string | — | UI language, e.g. "en", "it". Alias: hl. |
| num | number | 10 | Results to request, clamped to 1–100. |
| page | number | 1 | Result page, 1-based. start (offset) is also accepted. |
| device | string | desktop | desktop | mobile. |
| render | boolean | per engine | Google renders by default; pass false for the cheaper HTTP tier. Bing/DuckDuckGo do not render by default. |
| location | string | — | Human-readable search location ("Milan, Italy") — encoded to uule server-side. |
| uule | string | — | Encoded uule token OR raw "lat,lon[,radius]" coordinates. |
| safe | string | — | active | off — SafeSearch. |
| nfpr | boolean | — | 1/true disables auto-corrected results. |
| google_params | object | — | Escape hatch: extra Google URL params (max 24 keys). |
Vertical-specific params: place_id / data_id, product_id, flight dates and airport ids, hotel dates, image_url (lens), gps_coordinates (maps), next_page_token (reviews).
Request
curl -X POST "https://api.quanticdata.io/v1/serp" \
-H "Authorization: Bearer qd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "best coffee grinder", "engine": "google", "country": "us"}'
{
"type": "response",
"message": "SERP successful",
"payload": {
"search_parameters": { "engine": "google", "q": "best coffee grinder", "country": "us" },
"organic": [
{ "rank": 1, "title": "…", "link": "https://…", "description": "…" }
],
"people_also_ask": [ … ],
"usage": { "cost_usd": 0.0005, "free_usd": 0.0005, "paid_usd": 0 }
}
}
Guide: SERP API.
Map
POST /v1/map alias /v1/scraper/map $0.0005
URL discovery for a whole site: robots.txt sitemaps, /sitemap.xml (including nested indexes) and same-domain homepage links, de-duplicated. Synchronous — no per-page crawl.
| Param | Type | Default | Description |
|---|---|---|---|
| url req | string | required | Seed URL — the site to map. |
| limit | number | 100 | Max URLs to return (cap 5000). The response always carries the site-wide total and a per-section summary. |
| search | string | — | Only return URLs containing this substring. |
| includeSubdomains | boolean | false | Include URLs on subdomains of the seed host. |
| sitemapOnly | boolean | false | Skip the homepage link scrape. |
| group_by | string | — | "path" returns the path tree with counts instead of the URL list. |
| country | string | — | ISO country code for the proxy exit geo. |
curl -X POST "https://api.quanticdata.io/v1/map" \
-H "Authorization: Bearer qd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "limit": 100}'
{
"type": "response",
"message": "Map successful",
"payload": {
"url": "https://example.com",
"links": ["https://example.com/", "https://example.com/about"],
"count": 100,
"total": 2417,
"summary": { "/blog": 1988, "/docs": 240 },
"usage": { "cost_usd": 0.0005, "free_usd": 0.0005, "paid_usd": 0 }
}
}
Guide: Crawl & Map.
Crawl
POST /v1/crawl alias /v1/scraper/crawl
GET /v1/crawl/{jobId} alias /v1/scraper/crawl/{jobId}
DELETE /v1/crawl/{jobId} alias /v1/scraper/crawl/{jobId} $0.0003 / page
Asynchronous BFS from a seed. POST returns a job id; poll GET. Use ?since={nextCursor}&include_content=false for cheap status checks, then fetch bodies when the job completes.
| Param | Type | Default | Description |
|---|---|---|---|
| url req | string | required | Seed URL the crawl starts from. |
| limit | number | 50 | Max pages (cap 500). Charged up front on this limit; unfetched or failed pages are refunded when the job settles. |
| depth | number | 3 | Max link depth from the seed (cap 10). |
| format | string | markdown | markdown | html | text, applied to every page. |
| contentMode | string | smart | smart | article | full. Alias: content_mode. |
| render | boolean | false | Render each page with the stealth browser (rendered rate per page). |
| sameDomain | boolean | true | Only follow same-host links. |
| allowSubdomains | boolean | false | Also follow subdomains of the seed host. |
| include / exclude | string[] | — | URL substrings/globs to include or exclude (max 50 patterns). |
| country | string | — | ISO country code for the proxy exit geo. |
curl -X POST "https://api.quanticdata.io/v1/crawl" \
-H "Authorization: Bearer qd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "limit": 20, "depth": 2}'
# poll, then cancel
curl "https://api.quanticdata.io/v1/crawl/JOB_ID?include_content=false" \
-H "Authorization: Bearer qd_live_YOUR_KEY"
curl -X DELETE "https://api.quanticdata.io/v1/crawl/JOB_ID" \
-H "Authorization: Bearer qd_live_YOUR_KEY"
{
"type": "response",
"message": "Crawl started",
"payload": {
"id": "d5b8…", "status": "running", "seed": "https://example.com/",
"limit": 20, "pagesCrawled": 0, "pagesQueued": 1,
"statusUrl": "/api/v1/scraper/crawl/d5b8…"
}
}
Guide: Crawl & Map.
Batch
POST /v1/batch alias /v1/scraper/batch
GET /v1/batch/{jobId} alias /v1/scraper/batch/{jobId} $0.0002 / URL
Scrape up to 5,000 URLs you already know, with shared options. POST returns a job id. Poll GET with include_content=true and since, or pass webhook.
| Param | Type | Default | Description |
|---|---|---|---|
| urls req | string[] | required | URLs to scrape (max 5000, 2048 chars each). Charged up front per URL; the failed share is refunded at settlement. |
| format | string | markdown | markdown | html | text. |
| engine | string | auto | auto | tls | fetch | render. |
| render | boolean | false | Force the headless browser for every URL (rendered rate per URL). |
| extract | object | — | CSS selector schema applied to every URL. |
| contentMode | string | smart | smart | article | full. Alias: content_mode. |
| mode | string | full | "summary" stores per-URL metadata only. |
| concurrency | number | 5 | Simultaneous fetches (cap 20). |
| webhook | string | — | Public http(s) URL to POST the finished job to. |
| country | string | — | ISO country code for the proxy exit geo. |
curl -X POST "https://api.quanticdata.io/v1/batch" \
-H "Authorization: Bearer qd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"urls": ["https://example.com", "https://example.org"], "format": "markdown"}'
curl "https://api.quanticdata.io/v1/batch/JOB_ID?include_content=true" \
-H "Authorization: Bearer qd_live_YOUR_KEY"
SEO audit
POST /v1/seo-audit alias /v1/scraper/seo-audit $0.0012
Fetches a URL twice — pure HTTP (no JS) and fully rendered — and returns both views, the diff (JS-only content, changed title/description, missing canonical) and bot-facing meta (robots, OG, JSON-LD types).
| Param | Type | Default | Description |
|---|---|---|---|
| url req | string | required | The page to audit. |
| no_render | boolean | false | Skip the rendered pass — no-JS view only, bills at the plain scrape rate. Alias: noRender. |
| country | string | — | ISO country code for the proxy exit geo. |
curl -X POST "https://api.quanticdata.io/v1/seo-audit" \
-H "Authorization: Bearer qd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
{
"type": "response",
"message": "SEO audit successful",
"payload": {
"url": "https://example.com",
"noJs": { "status": 200, "title": "…", "wordCount": 412 },
"render": { "status": 200, "title": "…", "wordCount": 1180 },
"diff": { "contentOnlyInJs": true },
"usage": { "cost_usd": 0.0012, "free_usd": 0.0012, "paid_usd": 0 }
}
}
Guide: SEO Audit API.
Collectors
GET /v1/scraper/collectors catalog, no charge
GET /v1/scraper/collectors/{slug}
POST /v1/scraper/collectors/{slug}/run from $0.0005 / row
GET /v1/scraper/collectors/runs
GET /v1/scraper/collectors/runs/{runId}
Ready-made scrapers on a semantic input (keyword + location, place id, product id, domain) instead of URLs. Each publishes a versioned schema. Billed per delivered row. Long runs return 202 + statusUrl. Export with ?format=csv.
| Param | Type | Default | Description |
|---|---|---|---|
| <input fields> | per collector | — | The collector's semantic input — keyword + location, data_id, product_id, domains… — exactly as published in input_schema by GET /v1/scraper/collectors/{slug}. |
| max_results | integer | per collector | How many rows to deliver at most (clamped to the collector's cap). You pay only for delivered rows. |
| country / lang | string | — | Proxy exit geo (ISO code) and Google interface language, where the collector supports them. |
| async | boolean | false | Force background processing: 202 + statusUrl to poll. Long inputs go async automatically. |
curl "https://api.quanticdata.io/v1/scraper/collectors" \
-H "Authorization: Bearer qd_live_YOUR_KEY"
curl -X POST "https://api.quanticdata.io/v1/scraper/collectors/google_maps_places/run" \
-H "Authorization: Bearer qd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "pizza restaurants", "location": "Brooklyn, NY", "country": "us", "max_results": 20}'
curl "https://api.quanticdata.io/v1/scraper/collectors/runs/RUN_ID?format=csv" \
-H "Authorization: Bearer qd_live_YOUR_KEY"
{
"type": "response",
"message": "Collector run complete",
"payload": {
"run_id": "cmsx…", "slug": "google_maps_places", "status": "done",
"count": 20, "partial": false,
"results": [{ "rank": 1, "name": "…", "address": "…", "place_id": "ChIJ…" }],
"usage": { "cost_usd": 0.02, "free_usd": 0.02, "paid_usd": 0 }
}
}
Catalog: Collectors.
Proxies
GET /v1/public/proxies
POST /v1/public/proxies/generate
GET /v1/public/proxies/whitelist-ip
POST /v1/public/proxies/whitelist-ip
DELETE /v1/public/proxies/whitelist-ip
Same host and Bearer key. List your plans, then generate ready-to-use endpoint strings (HTTP or SOCKS5). Geo targeting depends on the plan: country / state / city, ISP or ASN. Whitelist is for IP-auth on Residential Basic, Datacenter, ISP, IPv6 and Mobile — Residential Premium and Private use user:pass and skip it. Valid location codes: GET /v1/public/geo/countries?planType=… (also states, cities, asns).
| Param | Type | Default | Description |
|---|---|---|---|
| orderId req | string | required | From GET /v1/public/proxies. |
| protocol | string | http | http | socks5. |
| format | string | user:pass@host:port | Also host:port:user:pass, http://user:pass@host:port, socks5://user:pass@host:port. |
| quantity | integer | 10 | How many strings to return (max 10,000). |
| country / state / city | string | — | Geo targeting. state alias: region. Slugs from the geo endpoints. |
| rotation | string | rotating | rotating | sticky | static (IPv6 only). |
| sessionTime | integer | 10 | Sticky duration in minutes (1–1440; Basic/Datacenter min 3). |
| isp / asn | string | — | isp: Premium and Mobile V2. asn: Basic/Datacenter Basic (e.g. AS12345). |
curl "https://api.quanticdata.io/v1/public/proxies?active=true" \
-H "Authorization: Bearer qd_live_YOUR_KEY"
curl -X POST "https://api.quanticdata.io/v1/public/proxies/generate" \
-H "Authorization: Bearer qd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"orderId":"YOUR_ORDER_ID","protocol":"http","quantity":10,"country":"us","rotation":"rotating"}'
Errors and rate limits
HTTP status plus {"type":"error","message":"…"}.
| Param | Type | Default | Description |
|---|---|---|---|
| 400 | status | — | Malformed input — the message says which param and why. |
| 401 | status | — | Missing, invalid or expired API key. |
| 403 | status | — | The endpoint is not enabled for your account, or no proxy plan is available. |
| 429 | status | — | Your key's rate limit, or an upstream throttle from the target — back off on Retry-After. |
| 5xx | status | — | Our side (including scraper-service timeouts). Never billed. |
PAYG allows 60 requests per minute. Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. A 429 also sends Retry-After.
MCP server
npx -y quanticdata-mcp exposes scrape, search, map, crawl, batch, seo_audit, collectors and proxy tools to Claude, Cursor and any MCP client. Tools: MCP server page.
claude mcp add quanticdata \ -e QUANTICDATA_API_KEY=qd_live_your_key_here \ -- npx -y quanticdata-mcp
Pricing
List prices on pay-as-you-go. Volume tiers take up to 30% off. You pay the tier that actually ran. Failed calls are never billed. Crawl and batch charge up front and refund the unfetched share.
| Call | List price |
|---|---|
| Scrape (per page) | $0.0002 |
| Scrape, JS render (per page) | $0.001 |
| SERP (per search) | $0.0005 |
| SERP, rendered (per search) | $0.002 |
| Map (per site) | $0.0005 |
| Crawl (per page) | $0.0003 |
| Batch (per URL) | $0.0002 |
| SEO audit (per URL) | $0.0012 |
| Collectors (per delivered result) | from $0.0005 |
FAQ
How do I authenticate?
Every request carries Authorization: Bearer qd_live_… (or your key prefix). One key covers scrape, SERP, map, crawl, batch, SEO audit, collectors and proxy generation. Get a key at app.quanticdata.io/register — $2 free every month, no card.
What is the base URL?
https://api.quanticdata.io/v1. Short aliases (POST /v1/scrape, /v1/serp, /v1/map, /v1/crawl, /v1/batch, /v1/seo-audit) and the long form (POST /v1/scraper/extract, /v1/scraper/serp, …) hit the same API. Collectors live under /v1/scraper/collectors. Proxy plans live under /v1/public/proxies.
Is there a free web scraping API?
Yes. Every account with a permanent email address includes $2 of free usage each month with no card. Failed calls are never billed. PAYG is 60 requests per minute; subscription tiers raise limits and discount unit prices.
How do I scrape a page in Python?
POST https://api.quanticdata.io/v1/scrape with requests: Authorization Bearer header and a JSON body containing url. Read payload.content for Markdown. The same envelope is used from Node, curl, or any HTTP client.
Do failed requests cost money?
No. Pay per success: a blocked page, a 4xx/5xx from the target, a timeout or a failed job is never charged. Crawl and batch are charged up front on requested volume and the unfetched share is refunded when the job settles. Collectors bill per delivered row — zero rows, zero charge.
How much does a scrape cost?
A successful scrape is $0.0002 per page on the TLS/request tier and $0.001 when the stealth browser renders JavaScript. SERP starts at $0.0005 ($0.002 rendered), map $0.0005 per site, crawl $0.0003 per page, batch $0.0002 per URL, SEO audit $0.0012 per URL, collectors from $0.0005 per delivered result.
What is the difference between scrape, batch and crawl?
Scrape fetches one URL and returns immediately. Batch takes a list of URLs you already know (up to 5,000) and runs them asynchronously. Crawl starts from a seed URL and follows links (up to 500 pages, depth 10). Map lists every URL of a site without fetching page bodies.
How do I use this from Claude or Cursor?
Install the MCP server: npx -y quanticdata-mcp with env QUANTICDATA_API_KEY. Claude Code: claude mcp add quanticdata -e QUANTICDATA_API_KEY=qd_live_… -- npx -y quanticdata-mcp. Cursor reads .cursor/mcp.json. Tools include scrape, search, map, crawl, batch, seo_audit, collectors and proxy tools (list_proxies, generate_proxies).
What does a successful response look like?
Every endpoint returns { "type": "response", "message": "…", "payload": {…} }. On failure, type is "error" and the reason is in message — nothing is billed. Successful calls also carry payload.usage with cost_usd, free_usd and paid_usd.
Are there rate limits?
PAYG keys are limited to 60 requests per minute. Responses include X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 also sends Retry-After in seconds. Subscription tiers raise the cap.
Where do I get an API key?
Sign up at https://app.quanticdata.io/register. No card. Keys start with qd_live_. Reveal and rotate them on the API Keys page in the dashboard.
Can I get Markdown instead of HTML?
Yes. format defaults to markdown on scrape, crawl and batch. Pass html or text, or formats as an array to receive several at once. contentMode smart strips nav/footer/cookie chrome; article uses Readability; full keeps the whole body.