Send a list of URLs, get them all back together. Useful for medium-volume jobs where you can wait for the full set. For larger jobs use the async variant.
Supported
format=json returns lean per-URL records: url, title, eval, time_ms, worker. Best for discovery and quick metadata sweeps.
Not supported
Per-URL content body is NOT in the batch response. For full HTML/markdown/text per URL, fan out single /v1/scrape calls from your own worker pool (~50-100 concurrent) or use /v1/scrape/batch/async with format=html for the rendered shell.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| urls | array | yes | โ | List of URLs (max 100). |
| concurrency | integer | no | 5 | Maximum parallel requests (max 25). |
| format | string | no | markdown | Output format applied to each URL. |
| timeout | integer | no | 120 | Overall timeout in seconds. |
Request
curl -X POST https://api.qcrawl.com/v1/scrape/batch \
-H "Authorization: Bearer osk_..." \
-d '{"urls": ["https://a.com","https://b.com"], "concurrency": 5, "format": "json"}' Response
{
"status": "success",
"total_urls": 2,
"concurrency": 5,
"total_time_ms": 612,
"avg_time_ms": 306.0,
"results": [
{"url": "https://a.com", "title": "A Title", "eval": null, "time_ms": 285, "worker": 0},
{"url": "https://b.com", "title": "B Title", "eval": null, "time_ms": 327, "worker": 1}
],
"time_ms": 612
}