Real Chrome
Pages render in a current Chrome build with JavaScript on. Content assembled client-side is in the HTML you download, not missing from it.
Send up to 1,000 URLs in one request. We load each page in Chrome with JavaScript enabled, detect when a site blocks us, rotate the exit IP, retry, and hand you the HTML.
No card required to register. Accounts are reviewed before activation.
import os
import requests
API = os.environ.get("API", "https://bankworks.info")
KEY = os.environ["API_KEY"]
# One request, twenty pages.
pages = range(1, 21)
urls = [f"https://example.com/p/{n}" for n in pages]
response = requests.post(
f"{API}/v1/jobs",
headers={"Authorization": f"Bearer {KEY}"},
json={"urls": urls, "maxAttempts": 3},
timeout=30,
)
print(response.json())
const API = process.env.API ?? "https://bankworks.info";
const KEY = process.env.API_KEY;
// One request, twenty pages.
const urls = Array.from({ length: 20 }, (_, i) =>
`https://example.com/p/${i + 1}`);
const response = await fetch(`${API}/v1/jobs`, {
method: "POST",
headers: {
Authorization: `Bearer ${KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ urls, maxAttempts: 3 }),
});
console.log(await response.json());
# One request, twenty pages.
curl -sS -X POST "$API/v1/jobs" \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d "$(jq -n '{
urls: [range(1; 21) | "https://example.com/p/\(.)"],
maxAttempts: 3
}')"
This is infrastructure, not a dataset. You name the pages; we render them and return the HTML. What you extract from it is yours.
Pages render in a current Chrome build with JavaScript on. Content assembled client-side is in the HTML you download, not missing from it.
Name a string only the real page contains and anything else is rejected and retried instead of stored. Scroll lazy-loaded content and wait after load before the HTML is read.
A challenge page that returns HTTP 200 is still a failure. We detect those, quarantine the exit IP and retry elsewhere instead of storing a useless page as a success.
Each URL becomes an independent task. One slow page does not hold up the other 999, and partial results are readable while the rest run.
Work is committed to a database before it is queued. A worker that dies mid-page has its task picked up again rather than dropped.
Every HTML download carries an X-HTML-SHA256 header
computed over the stored bytes, so you can prove what you received.
POST /v1/jobs with your URLs and
options. The response returns a jobId immediately — nothing
blocks on rendering.GET /v1/jobs/{jobId}
returns counters and per-task status.GET /v1/tasks/{taskId}/html
returns the stored HTML with its SHA-256.Numbers we measured on our own cluster, not marketing figures.
Throughput is shared across the fleet. If you need a committed rate, tell us the volume and we will quote capacity rather than guess.
We do not break anti-bot protection. No CAPTCHA solving, no browser fingerprint spoofing, no residential-proxy evasion. Sites that actively refuse automated access will keep refusing it.
We also do not resell consumer bandwidth. Every exit is one we operate under contract.
You are responsible for having the right to collect the pages you ask for. We respond to complaints by blocking targets.
Prefer a predictable bill? A monthly plan renews by itself through Stripe or PayPal and includes a number of successful requests. You can also keep a balance next to it: usage beyond your plan is charged from the balance at 1.45 USD per 1,000 requests.
100,000 successful requests every month.
140.00 USD / month
150,000 successful requests every month.
200.00 USD / month
200,000 successful requests every month.
250.00 USD / month
Cancel any time: you keep what you paid for until the end of the month. Card payments are verified with your bank (3-D Secure). Failed and blocked requests are never billed.
Register, get reviewed, and receive an API key. Pay per successful request from a balance, or pick a monthly plan — a request that did not succeed is not billed.