Core
Batch

POST /v1/batch

Scrape up to 100 URLs in a single request. Results are returned in the same order as the input array. Failed URLs are included in the response with ok: false and an error field, the whole batch never fails because of individual URL errors.

The options.concurrency you request is clamped to a per-plan cap for this endpoint (and to a hard ceiling of 20 regardless of plan):

Plan/v1/batch worker cap
Free2
Hobby5
Pro10
Scale20

These are batch workers, not the account-wide concurrency figure quoted on Pricing. Batch is the only endpoint that clamps concurrency today.

Request

POST /v1/batch
Content-Type: application/json
x-api-key: YOUR_KEY

Body

FieldTypeRequiredDefaultDescription
urlsstring[]YesURLs to scrape. Must be a non-empty array of valid http:// or https:// URLs, max 100.
options.extractListingbooleanNotrueRun the listing extraction pipeline on each page.
options.includeHtmlbooleanNofalseInclude raw HTML in each result. Increases response size.
options.cookiesstringNoCookie string forwarded to every request (Netscape or JSON format).
options.headersobjectNoCustom HTTP headers forwarded to every request.
options.concurrencynumberNo5Parallel fetch limit. Clamped to your tier cap (see table above).

Example request

curl -X POST https://api.superscraper.dev/v1/batch \
  -H "x-api-key: ss_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [
      "https://www.yelp.com/biz/acme-plumbing-austin",
      "https://www.yelp.com/biz/lone-star-electric-dallas",
      "https://www.angi.com/companylist/us/tx/austin/plumbers.htm"
    ],
    "options": {
      "extractListing": true,
      "concurrency": 3
    }
  }'

Response

HTTP 200 on success. The response header X-Batch-Summary summarises the run in a compact format: ok=N;failed=M;latencyMs=X.

Body

FieldTypeDescription
resultsarrayOne entry per URL in input order (see result item below)
summary.totalnumberTotal URLs processed
summary.oknumberNumber of successful scrapes
summary.failednumberNumber of failed scrapes
summary.latencyMsnumberWall-clock time for the entire batch in milliseconds

Result item

FieldTypeDescription
urlstringThe URL that was scraped
okbooleantrue if the page was fetched successfully
markdownstring | nullPage content as markdown
htmlstring | undefinedRaw HTML (only present when options.includeHtml: true)
listingobject | nullStructured listing data (same shape as /v1/scrape)
statusCodenumber | nullHTTP status code from the fetch
errorstring | undefinedError message when ok is false
metadata.fetchMethodstringHow the page was fetched: "plain", "playwright", or "stealth"
metadata.latencyMsnumberFetch time for this individual URL

Example response

{
  "results": [
    {
      "url": "https://www.yelp.com/biz/acme-plumbing-austin",
      "ok": true,
      "markdown": "# Acme Plumbing\n\n**4.8** ★ ...",
      "listing": {
        "name": "Acme Plumbing",
        "phone": "(512) 555-0187",
        "address": "1402 S 1st St",
        "city": "Austin",
        "state": "TX",
        "zip": "78704",
        "rating": 4.8,
        "review_count": 214,
        "_confidence": 0.92,
        "_extraction_method": "json-ld"
      },
      "statusCode": 200,
      "metadata": {
        "fetchMethod": "plain",
        "latencyMs": 412
      }
    },
    {
      "url": "https://www.yelp.com/biz/lone-star-electric-dallas",
      "ok": true,
      "markdown": "# Lone Star Electric\n\n**4.6** ★ ...",
      "listing": { "name": "Lone Star Electric", "rating": 4.6, "_confidence": 0.88, "_extraction_method": "json-ld" },
      "statusCode": 200,
      "metadata": { "fetchMethod": "plain", "latencyMs": 389 }
    },
    {
      "url": "https://www.angi.com/companylist/us/tx/austin/plumbers.htm",
      "ok": false,
      "markdown": null,
      "listing": null,
      "statusCode": 403,
      "error": "Fetch failed: HTTP 403",
      "metadata": { "fetchMethod": "plain", "latencyMs": 211 }
    }
  ],
  "summary": {
    "total": 3,
    "ok": 2,
    "failed": 1,
    "latencyMs": 847
  }
}

Errors

StatusErrorCause
400`urls` must be a non-empty arrayurls field missing, not an array, or empty
400`urls` may contain at most 100 entriesArray length exceeds 100
400Invalid URL(s) + invalidUrls arrayOne or more entries are not valid URLs
400Invalid JSON bodyMalformed request body
401API key requiredMissing x-api-key header
429Rate limit exceededToo many requests in the sliding window

Notes

  • Each successfully scraped URL consumes one credit, same as /v1/scrape. Failed URLs are free.
  • Concurrency is capped by your plan tier.
  • For more than 100 URLs, pass async: true (or just send more than 100) to run the batch as a job: the call returns 202 with a jobId you poll at GET /v1/jobs/:id. Async batches accept up to 10,000 URLs.