Setup
# Node 18+ has fetch built in; no install needed
Get a key at app.quanticdata.io/register: no card, keys start with qd_live_, and every account has $2 of credit a month. Base URL https://api.quanticdata.io/v1, header Authorization: Bearer qd_live_…. The full parameter reference is the API reference and the OpenAPI file; this page is the Node.js path through it.
The envelope
Every data call answers with the same shape: ok, payload with the result, and payload.usage with the cost. Errors come back as ok: false with error.code and error.message, and are not billed.
Scrape a page
POST /v1/scrape · $0.0002 per page
const res = await fetch("https://api.quanticdata.io/v1/scrape", {
method: "POST",
headers: {
Authorization: "Bearer qd_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"url": "https://example.com",
"format": "markdown"
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { payload } = await res.json();
console.log(payload);
payload.content is the Markdown; payload.usage is what the call cost. Add render: true for JavaScript pages ($0.001) or engine: "tls" to refuse escalation.
Search results
POST /v1/serp · $0.0005 per search
const res = await fetch("https://api.quanticdata.io/v1/serp", {
method: "POST",
headers: {
Authorization: "Bearer qd_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"query": "best coffee grinder",
"engine": "google",
"country": "us"
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { payload } = await res.json();
console.log(payload);
payload.organic is the list of results; ai_overview, people_also_ask and related_searches ride along when Google returns them.
Map a site
POST /v1/map · $0.0005 per site
const res = await fetch("https://api.quanticdata.io/v1/map", {
method: "POST",
headers: {
Authorization: "Bearer qd_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"url": "https://example.com",
"limit": 100
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { payload } = await res.json();
console.log(payload);
Every URL the site exposes through sitemaps and homepage links, with a per-section summary. Use search to filter or group_by: "path" for the tree.
Crawl a site
POST /v1/crawl · $0.0003 per page
const res = await fetch("https://api.quanticdata.io/v1/crawl", {
method: "POST",
headers: {
Authorization: "Bearer qd_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"url": "https://example.com",
"limit": 50,
"depth": 3,
"format": "markdown"
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { payload } = await res.json();
console.log(payload);
Async. The response carries a jobId; poll GET /v1/crawl/{jobId} until status is done. Pages not fetched are refunded.
Batch of URLs
POST /v1/batch · $0.0002 per URL
const res = await fetch("https://api.quanticdata.io/v1/batch", {
method: "POST",
headers: {
Authorization: "Bearer qd_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"urls": [
"https://example.com/a",
"https://example.com/b"
],
"format": "markdown",
"concurrency": 5
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { payload } = await res.json();
console.log(payload);
Up to 1,000 URLs per job, async; poll GET /v1/batch/{jobId} or pass a webhook URL.
SEO audit
POST /v1/seo-audit · $0.0012 per URL
const res = await fetch("https://api.quanticdata.io/v1/seo-audit", {
method: "POST",
headers: {
Authorization: "Bearer qd_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"url": "https://example.com"
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { payload } = await res.json();
console.log(payload);
Fetches the URL as a plain HTTP client and as a rendered browser, and returns both views plus the diff: title, description, canonical, h1, word count, JS-only content.
Run a collector
POST /v1/scraper/collectors/google_maps_places/run · from $0.0005 per result
const res = await fetch("https://api.quanticdata.io/v1/scraper/collectors/google_maps_places/run", {
method: "POST",
headers: {
Authorization: "Bearer qd_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"query": "pizza restaurants",
"location": "Brooklyn, NY",
"country": "us",
"max_results": 20
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { payload } = await res.json();
console.log(payload);
Collectors take a semantic input, never a URL. A 200 is a finished run; a 202 is async, poll GET /v1/scraper/collectors/runs/{runId}. Billed per delivered row.
Generate proxy strings
POST /v1/public/proxies/generate · no charge; bandwidth is billed by the plan
const res = await fetch("https://api.quanticdata.io/v1/public/proxies/generate", {
method: "POST",
headers: {
Authorization: "Bearer qd_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"orderId": "your_order_id",
"protocol": "http",
"format": "user:pass@host:port",
"quantity": 10,
"country": "us",
"rotation": "rotating"
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { payload } = await res.json();
console.log(payload);
GET /v1/public/proxies lists your plans and their orderId. The generator returns ready-to-use endpoint strings for a country, state or city.
Errors you will see
- 401 — missing or wrong key. Keys are case-sensitive and start with
qd_live_. - 402 — credit exhausted on pay-as-you-go; add a payment method or wait for the monthly $2.
- 422 — the body did not validate: the message names the field.
- 429 — account rate limit; honour
Retry-After. - ok: false with a 200 — the target could not be fetched (blocked, timed out, gone). Not billed; the error code says which.
Prices for every unit are on the pricing page. Agents can skip the HTTP layer entirely with the MCP server, which exposes the same calls as tools.
Guides for Node.js developers
Longer walkthroughs from the blog that use the same key and gateway:
Questions about the API in Node.js
Do I need an SDK to use the API from Node.js?
How do I know what a call cost?
payload.usage with cost_usd, the part covered by free credit and the part charged. Failed calls return an error envelope and cost nothing.What happens on rate limits?
Can I get the response as JSON instead of Markdown?
format accepts markdown, html, text or raw, and extract takes CSS selectors or a JSON schema with an AI prompt to return structured fields under payload.data.Run the Node.js examples now
A free key takes a minute, and the $2 of monthly credit covers about 10,000 scraped pages.
Get my free API keyFree key, $2 of usage credit every month, no credit card.