Skip to Content

scrape (sync)

POST /api/scrape

scrape a single url and get the full result in the response. requires a bearer token — see authentication.

request

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, "images": true } }'

response

a 200 response includes the fields you requested via the extract object. fields you didn’t request are omitted from the response.

fieldtypedescription
urlstringthe url actually scraped — after any redirects, in normalized form. /api/map writes its links the same way, so the two agree on the same page. links, images, and internal labels are computed against it
requested_urlstringthe url you requested, echoed verbatim — before any redirects
content_typestringmime type of the page (e.g., text/html)
unsupported_fieldsstring[]fields requested but not supported for this content type (e.g. markdown extraction on a pdf)
markdownstringcleaned markdown (when extract.markdown: true)
cleaned_htmlstringcleaned html — returned by default (unless extract.cleaned_html: false)
raw_htmlstringraw source html (when extract.raw_html: true)
linksarraypage links (when extract.links: true) — each: { text, href, internal }
imagesarraypage images (when extract.images: true) — each: { url, alt }
screenshotobjectscreenshot data (when extract.screenshot is set) — see screenshots
metadataobjectpage metadata — returned by default (unless extract.metadata: false)
response_metaobjectoperation metadata for this response (usage/billing) — see core concepts
response_meta.usage.creditsintegercredits actually charged for this request (0 on a fully cached result)
response_meta.usage.enginestringdelivered billing engine: "http", "browser", "screenshot", or "cache"
response_meta.usage.proxystringthe proxy tier that actually resolved the request — the resolved tier, never "auto"
response_meta.usage.screenshot_slicesintegerbilled slice-variant increment: 1 when newly produced, otherwise 0
warningsstring[]non-error notices — an output was capped rather than delivered whole (e.g. screenshot_truncated, links_truncated) or couldn’t be extracted (e.g. links_unavailable); filtered to the outputs you requested. see limits and truncation

response example

{ "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 } } }

metadata fields

the metadata object is included by default. set extract.metadata: false to skip it. every field is optional — only fields present on the page appear in the response; absent fields are omitted entirely (never null), with one exception: metadata.favicon_url may be null when no favicon could be resolved.

fieldtypedescription
titlestringpage <title>
descriptionstringmeta description
keywordsstring[]meta keywords
canonicalstringcanonical url from <link rel="canonical">
og_urlstringOpen Graph url
og_titlestringOpen Graph title
og_descriptionstringOpen Graph description
og_typestringOpen Graph type (e.g., website, article)
og_site_namestringOpen Graph site name
og_localestringOpen Graph locale (e.g., en_US)
og_locale_alternatestring[]alternate Open Graph locales
og_imagestringOpen Graph image url
authorstringpage author
date_modifiedstringlast modified date
date_publishedstringpublished date
twitter_sitestringTwitter site handle
twitter_cardstringTwitter card type
twitter_descriptionstringTwitter card description
twitter_titlestringTwitter card title
twitter_imagestringTwitter card image url
robotsstringrobots meta directive
favicon_urlstringbest-effort favicon url for the page

error responses

statusnamewhen
400invalid_url, url_too_long, scrape_errorbad url, url exceeds 8,192 bytes, or scrape failed
400unsupported_url_schemaonly http and https are supported
400url_credentials_not_supportedurls with embedded credentials are rejected
400blocked_urlurl is not allowed to be scraped
400validation_errorrequest body failed validation
401invalid_credentialsinvalid or missing api token
403antibot_blockedthe target site’s anti-bot protection blocked the scrape
408request_timeoutscrape took too long
415unsupported_contenttarget content type not supported for extraction
422unsupported_screenshot_outputthe request asked only for a screenshot and the content type can’t be screenshotted (json, plain text, markdown, xml) — not billed
422too_many_redirectsthe target site redirected the request in a loop, or through more hops than we follow. not a bad request; retrying rarely helps
422page_too_largethe page’s html was too large to process. terminal — the same url fails the same way, so don’t retry it
429too_many_requests, usage_allocation_errorrate limit or credit/concurrency limit hit
499client_closed_requestclient disconnected before completion
500internal_server_errorserver-side failure — including a screenshot-only request whose capture failed (not billed)
503service_unavailabletransient failure on our end — retry the same request; not an auth problem

all errors follow the standard { name, message, details? } format. see errors for the full reference, and when no screenshot can be delivered for the screenshot-only failure semantics.

combining extraction options

you can request multiple extraction types in a single call — see extraction options for the full field reference. pass everything you need in the extract object, including a screenshot:

{ "url": "https://news.ycombinator.com", "extract": { "markdown": true, "cleaned_html": true, "links": true, "images": true, "screenshot": { "type": "full_page" } } }

request only what you need. each field you skip means less processing and a faster response.

if you don’t pass an extract object, you’ll get metadata + cleaned_html back. add markdown, raw_html, links, images, or screenshot to request more.