View .md

Batch scrape

Scrape a list of up to 100 known URLs as one asynchronous job. Each URL is fetched on its own, without following links, through the same pipeline as a crawl. The job has a crawl id, so you follow it, cancel it and list its failures with the crawl endpoints, and it can notify a webhook.

POST/orgs/{id}/batch/scrape

Requires an API key with the scrape or the crawl scope. Submitting a batch counts against your plan's request rate limit.

bash
curl -X POST "https://xdive.dev/api/orgs/$ORG_ID/batch/scrape" \
  -H "X-API-Key: $XDIVE_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "urls": [
      "https://example.com/pricing",
      "https://example.com/about",
      "https://example.com/blog/launch"
    ],
    "formats": ["markdown", "links"],
    "ignore_invalid_urls": true
  }'
# {"id":"crl_2b8e5d1f9a4c7e3b6d0f2a8c4e6b1d9f","status":"queued","urls":3,"invalid_urls":[]}

The SDK methods submit the batch and poll it until it finishes (wait=False in Python returns the id instead). With cURL, poll GET /orgs/{id}/crawls/{crawlId} as described on Crawl.

Parameters

FieldTypeDefaultDescription
urlsarray of stringsrequired1 to 100 absolute http or https URLs. Blank entries are skipped and exact duplicates are scraped once.
ignore_invalid_urlsbooleanfalseSkip invalid entries instead of rejecting the request. Skipped entries are returned in invalid_urls.
formatsarraynoneRepresentations for each page, as on Scrape. screenshot and audio are not available. Without formats, each page has a markdown field.
extractbooleantrueMain-content extraction: drop navigation, headers and footers.
respect_robotsbooleantrueSkip URLs that robots.txt disallows.
adaptive_fetchbooleantruePlain HTTP first, escalating to a Chrome TLS fingerprint and then a headless browser for blocked pages, challenges and JavaScript shells. false uses plain HTTP only.
bypass_cachebooleanfalseNeither read nor write the page cache.
max_ageinteger0Cache freshness window in milliseconds, as on Scrape.
headersobjectnoneExtra request headers for every fetch, with the rules on Scrape.
redact_piibooleanfalseReplace emails, phone numbers, card numbers, SSNs, IBANs and IP addresses with typed tokens.
webhook_urlstringnoneReceives signed event POSTs, as for crawls.
webhook_secretstringnoneHMAC-SHA256 signing key. Required unless the platform's signed-webhook policy is off.
webhook_eventsarray of strings["completed", "failed"]Any of started, page, completed, failed.

A URL is valid when it parses as an absolute URL with an http or https scheme and a host.

Response

The batch is queued and the response is 202 Accepted:

json
{
  "id": "crl_2b8e5d1f9a4c7e3b6d0f2a8c4e6b1d9f",
  "status": "queued",
  "urls": 3,
  "invalid_urls": []
}
FieldTypeDescription
idstringThe job id. Use it with the crawl endpoints.
statusstringqueued.
urlsintegerNumber of URLs that will be scraped, after removing blanks, duplicates and skipped invalid entries.
invalid_urlsarray of stringsEntries skipped because they are not valid URLs.

Results

GET /orgs/{id}/crawls/{crawlId} returns the job in the crawl format, with url set to batch: followed by the first URL and maxDepth set to 0. Once the job is finished, results lists one page per URL in the order you submitted them; a URL that could not be fetched is a page with an error. The job's status is success when at least one URL succeeded.

To see only the failures, use GET /orgs/{id}/crawls/{crawlId}/errors. To stop the job, DELETE /orgs/{id}/crawls/{crawlId}; URLs not yet fetched are reported with the error cancelled before fetch.

Limits and usage

  • 100 URLs per batch, fetched four at a time.
  • The job runs for at most 2 minutes; URLs not fetched by then are reported as failed pages.
  • Each page is read up to 5 MB.

A batch counts as one crawl when submitted, and its pages, including failed ones, count against your monthly page quota when it finishes. If the quota is already used up, the batch is refused with 402.

Errors

StatusCodeWhen
400urls is empty or has more than 100 entries, no valid URL remains, a format is invalid or not allowed, or a header, webhook_events entry or max_age is invalid.
400Some entries are invalid and ignore_invalid_urls is not set. The body lists them in invalid_urls.
400WEBHOOK_TARGET_DENIEDwebhook_url is not a public URL.
400SIGNED_WEBHOOK_REQUIREDwebhook_url was set without webhook_secret.
402The monthly page quota is used up.
403The key has neither the scrape nor the crawl scope.
429Your plan's request rate limit was exceeded. Retry after Retry-After.
501An LLM format (json, product, menu) was requested and no LLM is configured.
503The job could not be queued.
json
{
  "error": "urls contains invalid entries; pass ignore_invalid_urls to skip them",
  "invalid_urls": ["ftp://example.com/file", "example.com/no-scheme"]
}
  • Scrape for one page, synchronously, with every option.
  • Crawl for status, cancellation, errors and webhooks.
  • Extract to pull structured data across up to 10 URLs.