curl --request GET \
--url https://api.zenrows.com/v1/crawls/{crawl_id} \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.zenrows.com/v1/crawls/{crawl_id}"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.zenrows.com/v1/crawls/{crawl_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://api.zenrows.com/v1/crawls/{crawl_id}';
const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.zenrows.com/v1/crawls/{crawl_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.zenrows.com/v1/crawls/{crawl_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}require 'uri'
require 'net/http'
url = URI("https://api.zenrows.com/v1/crawls/{crawl_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_bodyHttpResponse<String> response = Unirest.get("https://api.zenrows.com/v1/crawls/{crawl_id}")
.header("X-API-Key", "<api-key>")
.asString();{
"crawl_id": "c_01M3XP7RZD4JT88F7PNPGBFRAF",
"status": "completed",
"stop_reason": "max_pages",
"url": "https://www.scrapingcourse.com/ecommerce/",
"max_items": 100,
"max_pages": 10,
"include_patterns": [
"/product/"
],
"exclude_patterns": [],
"discovery": [
"links"
],
"coverage": {
"pages_fetched": 10,
"pages_failed": 0,
"items_found": 88
},
"duplicates_removed": 412,
"created_at": "2026-10-09T09:00:12Z",
"finished_at": "2026-10-09T09:00:41Z",
"results": [
{
"url": "https://www.scrapingcourse.com/ecommerce/product/abominable-hoodie/"
},
{
"url": "https://www.scrapingcourse.com/ecommerce/product/adrienne-trek-jacket/"
}
],
"next_cursor": null
}{
"code": "invalid_cursor",
"title": "Invalid cursor",
"detail": "The cursor does not belong to this crawl.",
"status": 400,
"instance": "urn:zenrows:request:9ac5b40be6127c8809b91babda784059"
}{
"code": "AUTH002",
"detail": "Invalid API key.",
"instance": "/v1",
"status": 401,
"title": "Invalid apikey provided (AUTH002)",
"type": "https://docs.zenrows.com/api-error-codes#AUTH002"
}{
"code": "AUTH004",
"detail": "This account has used all its credits for the period. Upgrade or add credits to continue.",
"instance": "/v1",
"status": 402,
"title": "Usage exceeded (AUTH004)",
"type": "https://docs.zenrows.com/api-error-codes#AUTH004"
}{
"code": "crawl_not_found",
"title": "Crawl not found",
"detail": "No crawl with this identifier exists for this account.",
"status": 404,
"instance": "urn:zenrows:request:9ac5b40be6127c8809b91babda784059"
}{
"code": "too_many_crawls",
"title": "Too many active crawls",
"detail": "Your account already runs 3 active jobs. Wait for one to end, then start the crawl again.",
"status": 429,
"instance": "urn:zenrows:request:9ac5b40be6127c8809b91babda784059"
}{
"code": "internal_error",
"title": "Internal error",
"detail": "Something failed on our side. Retry later.",
"status": 500,
"instance": "urn:zenrows:request:9ac5b40be6127c8809b91babda784059"
}Read a crawl and its results
The crawl, its coverage so far and one page of results. While it runs, next_cursor is never null: read again with the same cursor to get only the new URLs. Each URL is returned once. Documented at https://docs.zenrows.com/crawl/endpoints#read-a-crawl.
curl --request GET \
--url https://api.zenrows.com/v1/crawls/{crawl_id} \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.zenrows.com/v1/crawls/{crawl_id}"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.zenrows.com/v1/crawls/{crawl_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://api.zenrows.com/v1/crawls/{crawl_id}';
const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.zenrows.com/v1/crawls/{crawl_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.zenrows.com/v1/crawls/{crawl_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}require 'uri'
require 'net/http'
url = URI("https://api.zenrows.com/v1/crawls/{crawl_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_bodyHttpResponse<String> response = Unirest.get("https://api.zenrows.com/v1/crawls/{crawl_id}")
.header("X-API-Key", "<api-key>")
.asString();{
"crawl_id": "c_01M3XP7RZD4JT88F7PNPGBFRAF",
"status": "completed",
"stop_reason": "max_pages",
"url": "https://www.scrapingcourse.com/ecommerce/",
"max_items": 100,
"max_pages": 10,
"include_patterns": [
"/product/"
],
"exclude_patterns": [],
"discovery": [
"links"
],
"coverage": {
"pages_fetched": 10,
"pages_failed": 0,
"items_found": 88
},
"duplicates_removed": 412,
"created_at": "2026-10-09T09:00:12Z",
"finished_at": "2026-10-09T09:00:41Z",
"results": [
{
"url": "https://www.scrapingcourse.com/ecommerce/product/abominable-hoodie/"
},
{
"url": "https://www.scrapingcourse.com/ecommerce/product/adrienne-trek-jacket/"
}
],
"next_cursor": null
}{
"code": "invalid_cursor",
"title": "Invalid cursor",
"detail": "The cursor does not belong to this crawl.",
"status": 400,
"instance": "urn:zenrows:request:9ac5b40be6127c8809b91babda784059"
}{
"code": "AUTH002",
"detail": "Invalid API key.",
"instance": "/v1",
"status": 401,
"title": "Invalid apikey provided (AUTH002)",
"type": "https://docs.zenrows.com/api-error-codes#AUTH002"
}{
"code": "AUTH004",
"detail": "This account has used all its credits for the period. Upgrade or add credits to continue.",
"instance": "/v1",
"status": 402,
"title": "Usage exceeded (AUTH004)",
"type": "https://docs.zenrows.com/api-error-codes#AUTH004"
}{
"code": "crawl_not_found",
"title": "Crawl not found",
"detail": "No crawl with this identifier exists for this account.",
"status": 404,
"instance": "urn:zenrows:request:9ac5b40be6127c8809b91babda784059"
}{
"code": "too_many_crawls",
"title": "Too many active crawls",
"detail": "Your account already runs 3 active jobs. Wait for one to end, then start the crawl again.",
"status": 429,
"instance": "urn:zenrows:request:9ac5b40be6127c8809b91babda784059"
}{
"code": "internal_error",
"title": "Internal error",
"detail": "Something failed on our side. Retry later.",
"status": 500,
"instance": "urn:zenrows:request:9ac5b40be6127c8809b91babda784059"
}Authorizations
Batch, Crawl, the Extract endpoints and the account endpoint read the same key from the X-API-Key header.
Path Parameters
The crawl's ID, as returned when it started.
Query Parameters
The next_cursor from the previous read. Omit it to start from the first result.
How many results to return.
1 <= x <= 10000Response
The crawl and a page of its results.
A crawl, its coverage so far and one page of results.
completed: nothing was left to open, or a limit was reached (see stop_reason). stopped: you stopped it. failed: see error.
running, completed, stopped, failed Why the crawl ended early. Absent when nothing was left to open, and when the crawl failed.
max_items, max_pages, user Present only when status is failed. Older crawls can carry domain_not_allowed (the domain was not prepared for Extract).
Show child attributes
Show child attributes
The start URL: a public http or https URL. The crawl starts on this exact URL and stays on its domain, subdomains included.
2048How many link steps to follow from the start URL. At 1, the links on the start page. Omit it to follow links until max_items or max_pages stops the crawl.
1 <= x <= 100000Stop after keeping this many URLs.
1 <= x <= 100000Stop after fetching this many pages. Caps what the crawl costs. If both limits are reached together, stop_reason is max_pages.
1 <= x <= 100000Keep, and open, only URLs that contain at least one of these texts, such as /product/. The start URL is never returned.
Drop URLs that contain any of these texts, even when they match an include pattern.
html also returns the HTML of each kept page. Omit it to get URLs only.
html ["links"]: the crawl follows the links in each page's HTML. Older crawls can also list pagination.
links, pagination Show child attributes
Show child attributes
Links met again and dropped. Results never hold a duplicate.
Absent while the crawl runs.
Show child attributes
Show child attributes
Send it as cursor on the next read. Never null while the crawl runs; null once it has ended and its last results were read.
Was this page helpful?