Documentation Python quickstart Blog Free tools hello@quanticdata.ioLog in

QuanticData API in Node.js

Every endpoint of the web data API with a working Node.js example: scrape, search, map, crawl, batch, SEO audit, collectors and proxy generation. One host, one Bearer key, one JSON envelope. Also in: Python · cURL · PHP.

The QuanticData scrape call written in Node.js: install line, the POST with a Bearer key, and the JSON envelope back with payload.usage.cost_usd 0.0002, plus the 401/402/422/429 error strip.
The whole Node.js path in one picture: install, one authenticated POST to /v1/scrape, and the envelope that comes back — payload with the Markdown, and usage.cost_usd saying the call cost $0.0002. The strip along the bottom is every failure you can get, and none of them is billed.

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?

No. Every endpoint is plain JSON over HTTPS with a Bearer key, so the standard HTTP client of Node.js is enough. The examples on this page use nothing else.

How do I know what a call cost?

Every response carries 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?

Pay-as-you-go accounts have 60 requests per minute, Starter 300, Growth 600, Scale 1,200. Above that the API answers 429 with a Retry-After header; back off and retry, exactly as you would with any target.

Can I get the response as JSON instead of Markdown?

Yes. 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 key

Free key, $2 of usage credit every month, no credit card.