Making a request
Every scrape is one POST to /scrape with your clientKey and a url in the JSON body. The response holds the fetched page and metadata about how it was fetched.
The endpoint
There is a single endpoint: POST https://api.capzy.ai/scrape. Send Content-Type: application/json. The clientKey and url fields are required. Everything else is optional and has a default.
Core parameters
These are the parameters that shape the fetch itself. Rendering, anti-bot, extraction, and caching each have their own page. See Rendering & anti-bot and Extraction & formats.
| Parameter | Description |
|---|---|
clientKey | string, required. Your capzy_ key. Sent in the JSON body, not a header. |
url | string, required. The absolute URL to fetch. |
method | string, default "GET". Any HTTP method the target accepts. |
headers | object, default {}. Extra request headers merged onto the coherent browser defaults. |
body | string, default null. Raw request body, for example a form or JSON payload with a POST. |
cookies | object or array, default null. Cookies to send with the request. |
format | string, default "raw". "raw" HTML, "text" visible text, or "markdown". See Extraction & formats. |
proxyPool | string, default "datacenter". "datacenter" or "residential". asp forces residential. |
proxyCountry | string. ISO-2 country code for the egress IP, for example US or DE. |
timeout | int, milliseconds. Upper bound on the whole request before it fails. |
cache | bool, default false. Serve a cached copy when one is fresh. Cache hits cost zero. |
The response
A completed scrape returns errorId: 0, a status of ready, and a result object. The result holds the fetched content, the upstream status_code, response headers and cookies, and metadata such as which engine ran (http or browser), how many bytesDownloaded, and the egress pool, countries, and IP used.
{
"errorId": 0,
"status": "ready",
"taskId": "sc_9f2a...",
"result": {
"content": "<!doctype html>...",
"format": "raw",
"status_code": 200,
"url": "https://example.com",
"headers": { "content-type": "text/html; charset=utf-8" },
"cookies": { "session": "abc..." },
"engine": "http",
"bytesDownloaded": 51234,
"extracted": null,
"screenshot": null,
"scenarioResults": null,
"captchaWait": 0,
"asp": null,
"egress": { "pool": "datacenter", "countries": ["US"], "ip": "203.0.113.7" },
"featuresUsed": [],
"elapsedMs": 412
},
"cost": 0.01,
"viewUrl": "https://capzy.ai/dashboard/scraper/sc_9f2a..."
}The top-level cost is the amount billed for this request in USD, and viewUrl links to the run in your dashboard. When you enable rendering, asp, or extraction, the corresponding fields (screenshot, asp, extracted, scenarioResults) are populated instead of null.
Synchronous by default, polling as a fallback
Most scrapes finish on the same request and return status: "ready" directly. If the work runs long, roughly past 90 seconds of synchronous wait, the endpoint returns status: "processing" with a taskId instead.
{
"errorId": 0,
"status": "processing",
"taskId": "sc_9f2a..."
}Poll POST https://api.capzy.ai/getTaskResult with that taskId and your clientKey until status is ready (or failed). A two-second interval is plenty.
status once: if it is ready use result, if it is processing poll the taskId. The same code then works whether a given page returns inline or needs a poll.Examples
curl -s https://api.capzy.ai/scrape \
-H 'Content-Type: application/json' \
-d '{
"clientKey": "capzy_YOUR_KEY",
"url": "https://example.com",
"format": "markdown",
"proxyPool": "datacenter",
"proxyCountry": "US"
}'Next, add rendering and anti-bot for JavaScript-heavy or protected sites, or turn the page straight into structured fields.