Web scraping API
Web scraper API
with versioned extractors
Build a web scraper for any page type in Studio or reuse a public one, release it as an immutable semver version (an extractor), and call it pinned from a realtime scraping endpoint, async jobs, the Batch API or your AI agent over MCP. Pay per scraped URL.
Or read the API reference, or connect Claude or Cursor to the web scraping MCP server.
- Ready-made scrapers by site
- Semver-pinned extractor ids
- Realtime, async jobs and batch
- Signed webhooks
- MCP server for AI agents
- Free sandbox test keys
What is ExtractHub?
ExtractHub is a web scraping API and web data extraction platform. An extractor is a saved, versioned web scraper for one kind of page (request settings plus field selectors) built in ExtractHub Studio. Owners release extractors as immutable, semantically versioned releases with an output schema, and anyone with an API key calls a pinned version (for example @user/slug@1) through a realtime REST endpoint, async jobs, the Batch API or the remote MCP server for AI agents, paying per successful extraction from prepaid USD credit.
How it works
-
Build an extractor in Studio
Point Studio at a page, choose the request settings (method, headers, proxy, JavaScript rendering, XHR capture) and select the fields to extract. Test it on the live page before you release.
-
Release an immutable version
Releasing snapshots the request options, extractor config and output schema as a semver release. The minimum bump comes from the schema diff, so a removed field or a changed type always means a new major.
-
Call it with a pinned id
Pass extractor_id=@user/slug@1 to follow fixes and added fields of major 1, or @user/slug@1.2.3 to freeze one version. Unpinned ids are rejected with the list of available majors.
curl -X POST "https://api.extracthub.io/api/extractor/extract" \
-H "X-API-Key: $EXTRACTHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"extractor_id": "@username/amazon-product@1",
"target": { "url": "https://www.example.com/product/123" }
}' {
"success": true,
"result": {
"extracted": { "title": "...", "price": "..." },
"metadata": {
"url": "https://www.example.com/product/123",
"renderJs": false,
"useProxy": true,
"scrapedAt": "2026-11-01T12:00:00.000Z",
"costUsd": 0.0025
}
}
} Every extractor page shows these examples with its real id and latest pin, for realtime, batch, pipelines and AI agents (MCP).
Five ways to run a scraper
| Mode | Use it for | How |
|---|---|---|
| Realtime | One URL, result in the response | GET/POST /api/extractor/extract |
| Async job | Automatic when the queue is busy | 202 → GET /api/extractor/jobs/{id} |
| Batch | Many URLs, results as NDJSON | POST /api/extractor/batch |
| Pipeline | Multi-step crawls, schedules | Dashboard pipeline builder |
| AI agents (MCP) | Claude, Cursor and other MCP clients | https://api.extracthub.io/mcp |
Using an AI agent? Set up the ExtractHub MCP server for Claude Code, Claude Desktop or Cursor, and let it build new extractors with the AI web scraper builder skill.
Everything around the extract call
Versions, deprecation and yank
Every released version is immutable and carries its output schema and changelog. Owners deprecate a major with a sunset date (at least 30 days ahead) and a migration note, or yank a broken version; users get an in-app notice and an email, and responses carry Deprecation and Sunset headers.
Realtime extract with async fallback
GET or POST /api/extractor/extract returns the extracted JSON in the response. Requests queue fairly per scraping provider; if no capacity frees up within the wait limit, you get 202 with a job_id, status_url and result_url instead of an error (or 503 queue_timeout with async_fallback=false).
Batch API
Submit many URLs for one pinned version in a single POST /api/extractor/batch, follow progress, and page through NDJSON results with a stable cursor. Succeeded URLs are charged, failed URLs only when their scrape reached the provider; a batch pauses when credit runs out and can be cancelled at any time.
Signed webhooks
Batches and async jobs notify your HTTPS endpoint (per request or an account default webhook) about completed, failed and paused events. Deliveries are signed with X-Webhook-Signature and retried for about 24 hours.
Pipelines
Chain extractor nodes in the dashboard so the URLs found by one step feed the next, pin each node to a version, run pipelines manually or on a cron schedule, follow progress live and export JSON, CSV or NDJSON.
Sandbox test keys
Test keys (exth_test_...) behave like live keys on every extractor endpoint but never fetch a page or use credit. sandbox_scenario simulates failures, slow responses, async jobs and insufficient credit so you can test your error handling.
Health checks
Released versions of public extractors are checked on a schedule against their expected fields, so each version shows whether it is healthy, degraded or broken before you depend on it.
MCP server for AI agents
Connect Claude Code, Claude Desktop or Cursor to the remote MCP server with your API key: agents search extractors, extract URLs and run batches through the same endpoints, prices and limits as the API.
Errors you can branch on
Every error shares one body with stable codes: validation_error, unauthorized, insufficient_balance, rate_limited, upstream_error, target_error, queue_timeout, upstream_timeout. A failure before any provider work is not charged; a failure after the provider fetched the page (target_error, upstream_timeout, extraction errors) is charged and says charged: true.
Pricing per 1,000 requests
One price per scraped URL, set by how the page is fetched. The same price applies to realtime calls, async jobs, batches, pipelines and MCP.
Direct
$0.50 / 1,000 requests
$0.0005 per URL
The page is fetched directly over HTTP from our servers, without a scraping proxy or JavaScript, for open pages and JSON APIs.
- HTML and JSON extractors
- Your own request headers (cookies, API keys)
- Realtime, jobs, batches and pipelines
10,000 pages = $5.00
HTTP extraction (proxy)
$2.50 / 1,000 requests
$0.0025 per URL
The page is fetched over HTTP through a premium scraping proxy, and the extractor parses the HTML or JSON response.
- Premium proxy with provider failover
- Proxy exit country
- Optional retry with JavaScript when blocked
10,000 pages = $25.00
JavaScript rendering
$3.50 / 1,000 requests
$0.0035 per URL
The page is rendered in a headless browser first, for sites that build their content with JavaScript. Always through the proxy.
- Everything in HTTP extraction (proxy)
- Browser actions, waits for selectors
- XHR / API response capture
10,000 pages = $35.00
Free
$0
No credit used
- Sandbox test keys (exth_test_...): every endpoint, no credit
- 50 Studio page fetches per day
- Building, validating and releasing extractors
- Catalog, account, status and cancel calls (REST and MCP)
What is charged
- Every successful extraction, at its tier. The cost is in
result.metadata.costUsd. - A request that fails after the scraping provider fetched the page (error or block page, extraction error, provider timeout), because the provider bills that fetch. The error body says
charged: true. - An extractor that allows JavaScript escalation is charged the JavaScript rate when a blocked HTTP fetch is retried with rendering.
- Not charged: failures before any provider work (invalid request, insufficient balance, rate limits, queue timeouts, provider-side errors), and failed direct requests (no provider is called).
Credit packages
- Pay $10.00 $10.00 credit
- Pay $50.00 $52.50 credit(+5%)
- Pay $100.00 $110.00 credit(+10%)
Prepaid USD credit through Polar or PayPal, no subscription. Credit does not expire while your account is active.
Pay as you go
Prepaid USD credit • No subscription
Top up your balance and each scraped URL is charged by tier: JavaScript
rendering costs more than a plain HTTP fetch. The cost of every call is returned in
result.metadata.costUsd. Turn on auto top-up to refill
below a threshold, and get an email when your balance runs low.
- Failures before the provider call are not charged
- Sandbox test keys cost nothing
- Optional auto top-up
Frequently asked questions
Is ExtractHub a web scraper API?
Yes. ExtractHub is a web scraping API: you send the URL of a page and the id of an extractor (a saved web scraper for that kind of page) and get the extracted data back as structured JSON. Scrapers run through one REST endpoint for realtime calls, async jobs, the Batch API for many URLs, and a remote MCP server for AI agents, with prepaid USD credit charged per scraped URL.
What is an extractor?
An extractor is a saved scraper for one kind of page: the request settings (method, headers, proxy, JavaScript rendering) plus the fields to extract and their selectors, for HTML or JSON responses. It is built and tested in ExtractHub Studio and returns the page as structured JSON.
How is an extractor different from a scraper?
An extractor is a web scraper with a contract. Like any scraper it fetches a page and pulls fields out of it, but it is released as immutable semver versions with an output schema, so the fields you depend on cannot silently change: a removed or retyped field always needs a new major version, and your calls pin the version they expect. Public extractors are also checked on a schedule, so each version shows whether it still works.
How does extractor versioning and pinning work?
Releasing an extractor creates an immutable version with a semver number and an output schema. The minimum bump is computed from the output-schema diff: removing a field or changing its type needs a new major, adding a field is a minor. API calls must pin a version: @user/slug@1 follows the latest 1.x release (fixes and added fields), @user/slug@1.2.3 freezes one exact version. Unpinned ids are rejected with a 400 that lists the available majors.
What happens when a version is deprecated or yanked?
An owner can deprecate a major with a sunset date at least 30 days ahead and a migration note. Calls keep working and responses carry Deprecation and Sunset headers. A yanked version is skipped by @N pins, and an exact pin to it answers 410 version_yanked. Users of the extractor get an in-app notification and an email.
When should I use realtime, async jobs or the Batch API?
Use realtime extract (GET or POST /api/extractor/extract) for one URL when you need the result in the response. Requests wait in a fair queue per scraping provider; if no capacity frees up within the wait limit, the request becomes an async job (202 with job_id, status_url and result_url) unless you pass async_fallback=false. Use the Batch API to submit many URLs in one request and read the results as NDJSON pages.
How does pricing work?
ExtractHub is pay as you go with prepaid USD credit: no subscription. Each successful extraction is charged per URL by tier: direct (fetched without a proxy or JavaScript, the lowest price), HTTP through the scraping proxy, or JavaScript rendering (always through the proxy, the highest price); the cost is returned in result.metadata.costUsd. A request, batch item or job that fails after the page was fetched through a scraping provider (the target answered an error or a block page, the extraction failed, or the provider timed out) is charged in full, because the provider bills that fetch. Failures before any provider work (invalid request, insufficient balance, rate limits, queue timeouts, a provider-side error) and failed direct requests are not charged; the error body says `charged: true` when a failed request was charged. You top up from the dashboard and can enable auto top-up when the balance falls below a threshold.
Can I test without spending credit?
Yes. Test API keys (prefix exth_test_) work on every extractor endpoint but never fetch a page, never touch the provider queue and never use credit. Results come from the version's last passing health check, its released sample or a placeholder built from its output schema, and sandbox_scenario lets you simulate failures, slow responses, async jobs and insufficient credit.
How do webhooks work?
Batches and async jobs can notify an HTTPS webhook_url (or your account default webhook) about batch.completed, batch.failed, batch.paused, job.completed and job.failed. Each delivery is signed with X-Webhook-Signature (HMAC-SHA256 with your whsec_ secret) and retried for about 24 hours. Payloads never contain result data: fetch results from the status or results URL.
Can AI agents like Claude or Cursor use ExtractHub?
Yes. ExtractHub runs a remote MCP (Model Context Protocol) server at /mcp on the API host. Add it to Claude Code, Claude Desktop, Cursor or any MCP client with your API key, and the agent can search extractors, read their output schema, extract a URL, run and page through batches and check your balance. Tool calls go through the same endpoints as the REST API, so prices, rate limits, sandbox keys and usage logs are the same.