curl --request POST \
--url https://api.prefetch.io/batch/scrape \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"urls": [
"https://stripe.com/pricing",
"https://stripe.com/docs"
],
"concurrency": 2,
"ignore_invalid_urls": false,
"webhook": "https://example.com/hooks/prefetch",
"scrape_options": {
"formats": [
"markdown"
],
"only_main_content": true,
"include_links": true,
"include_images": true,
"include_base64_images": false,
"include_selectors": [
"<string>"
],
"exclude_selectors": [
"<string>"
],
"json_prompt": "<string>",
"json_schema": {},
"summary_max_words": 120,
"screenshot_full_page": false,
"screenshot_format": "jpeg",
"wait_for": 15000,
"wait_for_selector": "<string>",
"headers": {},
"mobile": false,
"max_age": 0,
"store_in_cache": true,
"check_prompt_injection": false
}
}
'import requests
url = "https://api.prefetch.io/batch/scrape"
payload = {
"urls": ["https://stripe.com/pricing", "https://stripe.com/docs"],
"concurrency": 2,
"ignore_invalid_urls": False,
"webhook": "https://example.com/hooks/prefetch",
"scrape_options": {
"formats": ["markdown"],
"only_main_content": True,
"include_links": True,
"include_images": True,
"include_base64_images": False,
"include_selectors": ["<string>"],
"exclude_selectors": ["<string>"],
"json_prompt": "<string>",
"json_schema": {},
"summary_max_words": 120,
"screenshot_full_page": False,
"screenshot_format": "jpeg",
"wait_for": 15000,
"wait_for_selector": "<string>",
"headers": {},
"mobile": False,
"max_age": 0,
"store_in_cache": True,
"check_prompt_injection": False
}
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
urls: ['https://stripe.com/pricing', 'https://stripe.com/docs'],
concurrency: 2,
ignore_invalid_urls: false,
webhook: 'https://example.com/hooks/prefetch',
scrape_options: {
formats: ['markdown'],
only_main_content: true,
include_links: true,
include_images: true,
include_base64_images: false,
include_selectors: ['<string>'],
exclude_selectors: ['<string>'],
json_prompt: '<string>',
json_schema: {},
summary_max_words: 120,
screenshot_full_page: false,
screenshot_format: 'jpeg',
wait_for: 15000,
wait_for_selector: '<string>',
headers: {},
mobile: false,
max_age: 0,
store_in_cache: true,
check_prompt_injection: false
}
})
};
fetch('https://api.prefetch.io/batch/scrape', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.prefetch.io/batch/scrape",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'urls' => [
'https://stripe.com/pricing',
'https://stripe.com/docs'
],
'concurrency' => 2,
'ignore_invalid_urls' => false,
'webhook' => 'https://example.com/hooks/prefetch',
'scrape_options' => [
'formats' => [
'markdown'
],
'only_main_content' => true,
'include_links' => true,
'include_images' => true,
'include_base64_images' => false,
'include_selectors' => [
'<string>'
],
'exclude_selectors' => [
'<string>'
],
'json_prompt' => '<string>',
'json_schema' => [
],
'summary_max_words' => 120,
'screenshot_full_page' => false,
'screenshot_format' => 'jpeg',
'wait_for' => 15000,
'wait_for_selector' => '<string>',
'headers' => [
],
'mobile' => false,
'max_age' => 0,
'store_in_cache' => true,
'check_prompt_injection' => false
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.prefetch.io/batch/scrape"
payload := strings.NewReader("{\n \"urls\": [\n \"https://stripe.com/pricing\",\n \"https://stripe.com/docs\"\n ],\n \"concurrency\": 2,\n \"ignore_invalid_urls\": false,\n \"webhook\": \"https://example.com/hooks/prefetch\",\n \"scrape_options\": {\n \"formats\": [\n \"markdown\"\n ],\n \"only_main_content\": true,\n \"include_links\": true,\n \"include_images\": true,\n \"include_base64_images\": false,\n \"include_selectors\": [\n \"<string>\"\n ],\n \"exclude_selectors\": [\n \"<string>\"\n ],\n \"json_prompt\": \"<string>\",\n \"json_schema\": {},\n \"summary_max_words\": 120,\n \"screenshot_full_page\": false,\n \"screenshot_format\": \"jpeg\",\n \"wait_for\": 15000,\n \"wait_for_selector\": \"<string>\",\n \"headers\": {},\n \"mobile\": false,\n \"max_age\": 0,\n \"store_in_cache\": true,\n \"check_prompt_injection\": false\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.prefetch.io/batch/scrape")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"urls\": [\n \"https://stripe.com/pricing\",\n \"https://stripe.com/docs\"\n ],\n \"concurrency\": 2,\n \"ignore_invalid_urls\": false,\n \"webhook\": \"https://example.com/hooks/prefetch\",\n \"scrape_options\": {\n \"formats\": [\n \"markdown\"\n ],\n \"only_main_content\": true,\n \"include_links\": true,\n \"include_images\": true,\n \"include_base64_images\": false,\n \"include_selectors\": [\n \"<string>\"\n ],\n \"exclude_selectors\": [\n \"<string>\"\n ],\n \"json_prompt\": \"<string>\",\n \"json_schema\": {},\n \"summary_max_words\": 120,\n \"screenshot_full_page\": false,\n \"screenshot_format\": \"jpeg\",\n \"wait_for\": 15000,\n \"wait_for_selector\": \"<string>\",\n \"headers\": {},\n \"mobile\": false,\n \"max_age\": 0,\n \"store_in_cache\": true,\n \"check_prompt_injection\": false\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.prefetch.io/batch/scrape")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"urls\": [\n \"https://stripe.com/pricing\",\n \"https://stripe.com/docs\"\n ],\n \"concurrency\": 2,\n \"ignore_invalid_urls\": false,\n \"webhook\": \"https://example.com/hooks/prefetch\",\n \"scrape_options\": {\n \"formats\": [\n \"markdown\"\n ],\n \"only_main_content\": true,\n \"include_links\": true,\n \"include_images\": true,\n \"include_base64_images\": false,\n \"include_selectors\": [\n \"<string>\"\n ],\n \"exclude_selectors\": [\n \"<string>\"\n ],\n \"json_prompt\": \"<string>\",\n \"json_schema\": {},\n \"summary_max_words\": 120,\n \"screenshot_full_page\": false,\n \"screenshot_format\": \"jpeg\",\n \"wait_for\": 15000,\n \"wait_for_selector\": \"<string>\",\n \"headers\": {},\n \"mobile\": false,\n \"max_age\": 0,\n \"store_in_cache\": true,\n \"check_prompt_injection\": false\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "crw_5a8d2e7f1c4b4a9e8d3c6b1a0f9e8d7c",
"status": "pending",
"url_count": 2,
"invalid_urls": [],
"created_at": "2026-10-11T09:14:03.221Z",
"expires_at": "2026-10-12T09:14:03.221Z"
},
"meta": {
"requestId": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"durationMs": 58
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}POST /batch/scrape
Scrape a list of URLs in one job. Free to submit, then 1 credit per page returned.
curl --request POST \
--url https://api.prefetch.io/batch/scrape \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"urls": [
"https://stripe.com/pricing",
"https://stripe.com/docs"
],
"concurrency": 2,
"ignore_invalid_urls": false,
"webhook": "https://example.com/hooks/prefetch",
"scrape_options": {
"formats": [
"markdown"
],
"only_main_content": true,
"include_links": true,
"include_images": true,
"include_base64_images": false,
"include_selectors": [
"<string>"
],
"exclude_selectors": [
"<string>"
],
"json_prompt": "<string>",
"json_schema": {},
"summary_max_words": 120,
"screenshot_full_page": false,
"screenshot_format": "jpeg",
"wait_for": 15000,
"wait_for_selector": "<string>",
"headers": {},
"mobile": false,
"max_age": 0,
"store_in_cache": true,
"check_prompt_injection": false
}
}
'import requests
url = "https://api.prefetch.io/batch/scrape"
payload = {
"urls": ["https://stripe.com/pricing", "https://stripe.com/docs"],
"concurrency": 2,
"ignore_invalid_urls": False,
"webhook": "https://example.com/hooks/prefetch",
"scrape_options": {
"formats": ["markdown"],
"only_main_content": True,
"include_links": True,
"include_images": True,
"include_base64_images": False,
"include_selectors": ["<string>"],
"exclude_selectors": ["<string>"],
"json_prompt": "<string>",
"json_schema": {},
"summary_max_words": 120,
"screenshot_full_page": False,
"screenshot_format": "jpeg",
"wait_for": 15000,
"wait_for_selector": "<string>",
"headers": {},
"mobile": False,
"max_age": 0,
"store_in_cache": True,
"check_prompt_injection": False
}
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
urls: ['https://stripe.com/pricing', 'https://stripe.com/docs'],
concurrency: 2,
ignore_invalid_urls: false,
webhook: 'https://example.com/hooks/prefetch',
scrape_options: {
formats: ['markdown'],
only_main_content: true,
include_links: true,
include_images: true,
include_base64_images: false,
include_selectors: ['<string>'],
exclude_selectors: ['<string>'],
json_prompt: '<string>',
json_schema: {},
summary_max_words: 120,
screenshot_full_page: false,
screenshot_format: 'jpeg',
wait_for: 15000,
wait_for_selector: '<string>',
headers: {},
mobile: false,
max_age: 0,
store_in_cache: true,
check_prompt_injection: false
}
})
};
fetch('https://api.prefetch.io/batch/scrape', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.prefetch.io/batch/scrape",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'urls' => [
'https://stripe.com/pricing',
'https://stripe.com/docs'
],
'concurrency' => 2,
'ignore_invalid_urls' => false,
'webhook' => 'https://example.com/hooks/prefetch',
'scrape_options' => [
'formats' => [
'markdown'
],
'only_main_content' => true,
'include_links' => true,
'include_images' => true,
'include_base64_images' => false,
'include_selectors' => [
'<string>'
],
'exclude_selectors' => [
'<string>'
],
'json_prompt' => '<string>',
'json_schema' => [
],
'summary_max_words' => 120,
'screenshot_full_page' => false,
'screenshot_format' => 'jpeg',
'wait_for' => 15000,
'wait_for_selector' => '<string>',
'headers' => [
],
'mobile' => false,
'max_age' => 0,
'store_in_cache' => true,
'check_prompt_injection' => false
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.prefetch.io/batch/scrape"
payload := strings.NewReader("{\n \"urls\": [\n \"https://stripe.com/pricing\",\n \"https://stripe.com/docs\"\n ],\n \"concurrency\": 2,\n \"ignore_invalid_urls\": false,\n \"webhook\": \"https://example.com/hooks/prefetch\",\n \"scrape_options\": {\n \"formats\": [\n \"markdown\"\n ],\n \"only_main_content\": true,\n \"include_links\": true,\n \"include_images\": true,\n \"include_base64_images\": false,\n \"include_selectors\": [\n \"<string>\"\n ],\n \"exclude_selectors\": [\n \"<string>\"\n ],\n \"json_prompt\": \"<string>\",\n \"json_schema\": {},\n \"summary_max_words\": 120,\n \"screenshot_full_page\": false,\n \"screenshot_format\": \"jpeg\",\n \"wait_for\": 15000,\n \"wait_for_selector\": \"<string>\",\n \"headers\": {},\n \"mobile\": false,\n \"max_age\": 0,\n \"store_in_cache\": true,\n \"check_prompt_injection\": false\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.prefetch.io/batch/scrape")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"urls\": [\n \"https://stripe.com/pricing\",\n \"https://stripe.com/docs\"\n ],\n \"concurrency\": 2,\n \"ignore_invalid_urls\": false,\n \"webhook\": \"https://example.com/hooks/prefetch\",\n \"scrape_options\": {\n \"formats\": [\n \"markdown\"\n ],\n \"only_main_content\": true,\n \"include_links\": true,\n \"include_images\": true,\n \"include_base64_images\": false,\n \"include_selectors\": [\n \"<string>\"\n ],\n \"exclude_selectors\": [\n \"<string>\"\n ],\n \"json_prompt\": \"<string>\",\n \"json_schema\": {},\n \"summary_max_words\": 120,\n \"screenshot_full_page\": false,\n \"screenshot_format\": \"jpeg\",\n \"wait_for\": 15000,\n \"wait_for_selector\": \"<string>\",\n \"headers\": {},\n \"mobile\": false,\n \"max_age\": 0,\n \"store_in_cache\": true,\n \"check_prompt_injection\": false\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.prefetch.io/batch/scrape")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"urls\": [\n \"https://stripe.com/pricing\",\n \"https://stripe.com/docs\"\n ],\n \"concurrency\": 2,\n \"ignore_invalid_urls\": false,\n \"webhook\": \"https://example.com/hooks/prefetch\",\n \"scrape_options\": {\n \"formats\": [\n \"markdown\"\n ],\n \"only_main_content\": true,\n \"include_links\": true,\n \"include_images\": true,\n \"include_base64_images\": false,\n \"include_selectors\": [\n \"<string>\"\n ],\n \"exclude_selectors\": [\n \"<string>\"\n ],\n \"json_prompt\": \"<string>\",\n \"json_schema\": {},\n \"summary_max_words\": 120,\n \"screenshot_full_page\": false,\n \"screenshot_format\": \"jpeg\",\n \"wait_for\": 15000,\n \"wait_for_selector\": \"<string>\",\n \"headers\": {},\n \"mobile\": false,\n \"max_age\": 0,\n \"store_in_cache\": true,\n \"check_prompt_injection\": false\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "crw_5a8d2e7f1c4b4a9e8d3c6b1a0f9e8d7c",
"status": "pending",
"url_count": 2,
"invalid_urls": [],
"created_at": "2026-10-11T09:14:03.221Z",
"expires_at": "2026-10-12T09:14:03.221Z"
},
"meta": {
"requestId": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"durationMs": 58
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}Overview
/batch/scrape scrapes up to 500 URLs you already have, as one job. Each page is fetched and rendered exactly as GET /scrape would render it, configured through scrape_options. Nothing is followed and no sitemap is read: you get the pages you listed.
It works like a crawl: you get an id straight away, then read progress and pages from GET /batch/scrape/{id}, or receive them by webhook.
Use it instead of many /scrape calls when you have a list of URLs: one request instead of hundreds, and no concurrency limit to manage on your side.
Example request
curl -X POST "https://api.prefetch.io/batch/scrape" \
-H "X-API-Key: $PREFETCH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"urls": ["https://stripe.com/pricing", "https://stripe.com/docs"],
"scrape_options": { "formats": ["markdown"], "only_main_content": true }
}'
const res = await fetch("https://api.prefetch.io/batch/scrape", {
method: "POST",
headers: { "X-API-Key": process.env.PREFETCH_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
urls: ["https://stripe.com/pricing", "https://stripe.com/docs"],
scrape_options: { formats: ["markdown"] },
}),
});
const { data } = await res.json();
console.log(data.id); // poll GET /batch/scrape/{id}
Invalid URLs
Every URL gets the checks a single/scrape would. By default one invalid or blocklisted URL rejects the whole batch with a 400 that names it. Set ignore_invalid_urls: true to drop those URLs instead; they are listed in the response’s invalid_urls. Duplicate URLs, including the same page under another spelling (www., a trailing slash), are scraped once.
Webhooks
webhook works as it does for crawls, with events named batch_scrape.started, batch_scrape.page, batch_scrape.completed and batch_scrape.failed. See crawl webhooks for the payload and how to verify the signature. Not available through RapidAPI.
Credits
Submitting is free. You are charged 1 credit per page returned, or 4 whenscrape_options asks for summary, json or check_prompt_injection. Pages are billed as they complete — when you poll the status endpoint, or when the batch ends — and failed pages are never charged.
To run brand, enrich, company, classify, screenshot or styleguide over a list instead, see POST /batch/{endpoint}.
prefetch_batch_scrape submits the batch and waits for it, returning the pages when it finishes in time.Related
GET /batch/scrape/{id}
GET /batch/scrape/{id}/errors
Authorizations
Your Prefetch API key. Obtain one from the dashboard.
Body
The pages to scrape (1–500). Duplicates are scraped once.
1 - 500 elements[ "https://stripe.com/pricing", "https://stripe.com/docs" ]
Pages fetched in parallel.
1 <= x <= 5Drop URLs that fail validation (listed in invalid_urls) instead of rejecting the whole batch.
Where to send progress: an https URL, or an object. Events: batch_scrape.started, batch_scrape.page (one per page), batch_scrape.completed, batch_scrape.failed. Each delivery is signed — X-Prefetch-Signature: t=<unix>,v1=<hex>, HMAC-SHA256 of <t>.<raw body> with the secret returned when the batch is created — the same scheme as monitor webhooks.
"https://example.com/hooks/prefetch"
How each crawled page is fetched and rendered. The same options GET /scrape takes.
Show child attributes
Show child attributes