quickstart
get up and running with crawlbrulee in under 5 minutes. you’ll scrape a page, map a site, and run an async job.
prerequisites
you need an api key from the crawlbrulee dashboard . see authentication for the full setup.
set it as an environment variable:
export CRAWLBRULEE_API_KEY="your-api-key"every request uses this key via the Authorization: Bearer header. the examples below read it from the environment automatically.
scrape a page
hit POST /api/scrape with a url and tell the api what you want back. here we ask for the cleaned markdown and all links on the page.
curl
curl -X POST https://api.crawlbrulee.com/api/scrape \
-H "Authorization: Bearer $CRAWLBRULEE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"extract": {
"markdown": true,
"links": true
}
}'response:
{
"url": "https://example.com",
"requested_url": "https://example.com",
"content_type": "text/html",
"markdown": "# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.\n\n[More information...](https://www.iana.org/domains/example)",
"cleaned_html": "<h1>Example Domain</h1><p>This domain is for use in illustrative examples...</p>",
"links": [
{
"text": "More information...",
"href": "https://www.iana.org/domains/example",
"internal": false
}
],
"metadata": {
"title": "Example Domain",
"og_title": "Example Domain",
"favicon_url": "https://example.com/favicon.ico"
},
"response_meta": {
"usage": {
"credits": 1,
"engine": "http",
"proxy": "basic",
"screenshot_slices": 0
}
}
}a fully cached result is free. if crawlbrulee already has a fresh result for
a url, you get it back instantly at zero base cost; a newly produced screenshot-slice variant adds
one flat credit. control freshness with the cache.max_age parameter. check for
response_meta.usage.engine: "cache" to see whether the base result came from cache.
map a site
POST /api/map discovers every url on a site by combining sitemap parsing with in-page link discovery. pass a root url and get back a full link inventory.
curl
curl -X POST https://api.crawlbrulee.com/api/map \
-H "Authorization: Bearer $CRAWLBRULEE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com"
}'response:
{
"links": [
{ "url": "https://example.com/about" },
{ "url": "https://example.com/blog" },
{ "url": "https://example.com/docs" },
{ "url": "https://example.com/pricing" },
{ "url": "https://example.com/blog/getting-started" }
],
"response_meta": {
"usage": {
"credits": 1,
"engine": "http",
"proxy": "basic"
},
"pagination": {
"page": 1,
"limit": 5000,
"total": 5,
"total_pages": 1,
"has_more": false
},
"truncation": {
"storage_capped": false,
"response_capped": false,
"total_before_max_urls": 5,
"total_detected_before_storage_cap": 5,
"discovery_capped": false,
"sitemaps_skipped": 0,
"discovery_cap_reason": null
}
}
}a map returns up to 5,000 urls by default — raise max_urls (up to 100,000) for a bigger site. you can also filter by link type (internal, internal_subdomains, external) and paginate through large sites. see the full map guide for all options.
async scraping
for batch pipelines or pages that take a while to render, use the async flow. you submit a job, poll for status, and fetch the result when it’s done.
don’t want to poll? pass a webhook: { url } object on submit and we POST a signed payload to that url once the job reaches a terminal state — see webhooks.
submit the job
POST /api/scrape/async takes the same body as the sync endpoint but returns immediately with a job_id.
curl
curl -X POST https://api.crawlbrulee.com/api/scrape/async \
-H "Authorization: Bearer $CRAWLBRULEE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"extract": {
"markdown": true,
"links": true
}
}'response (http 202):
{
"job_id": "683a1f2b4c5d6e7f8a9b0c1d"
}poll for status
GET /api/scrape/status/{job_id} returns the current state: pending, running, done, or failed. keep polling until status is done or failed.
curl
curl https://api.crawlbrulee.com/api/scrape/status/683a1f2b4c5d6e7f8a9b0c1d \
-H "Authorization: Bearer $CRAWLBRULEE_API_KEY"response:
{
"job_id": "683a1f2b4c5d6e7f8a9b0c1d",
"status": "running",
"created_at": "2025-01-15T10:30:00.000Z"
}get the result
once status is done, fetch the full scrape result from GET /api/scrape/result/{job_id}. the response shape is the same as the sync endpoint.
curl
curl https://api.crawlbrulee.com/api/scrape/result/683a1f2b4c5d6e7f8a9b0c1d \
-H "Authorization: Bearer $CRAWLBRULEE_API_KEY"response:
{
"url": "https://example.com",
"requested_url": "https://example.com",
"content_type": "text/html",
"markdown": "# Example Domain\n\nThis domain is for use in illustrative examples ...",
"cleaned_html": "<h1>Example Domain</h1><p>This domain is for use in illustrative examples...</p>",
"links": [
{
"href": "https://www.iana.org/domains/example",
"text": "More information...",
"internal": false
}
],
"metadata": {
"title": "Example Domain"
},
"response_meta": {
"usage": {
"credits": 1,
"engine": "http",
"proxy": "basic",
"screenshot_slices": 0
}
}
}async is ideal for batch pipelines. submit hundreds of jobs, poll in parallel, and collect results as they finish. credits are reserved on submit, released if a job fails, and charged at the delivered engine on success. a cache hit has a 0-credit base.
what’s next
you’ve got the basics down. here’s where to go deeper:
- core concepts — how scraping, caching, and credits work together.
- extraction options — control exactly what data you pull from each page.
- screenshots — capture full-page or viewport screenshots.
- credits & pricing — understand what operations cost and how to optimize.
- site mapping — discover every url on a domain before you scrape.
- sdks & tools — official js/ts + Python sdks, a cli, and an mcp server.