- Turn a webpage into clean markdown/HTML
- Crawl an entire website and save every page as markdown
- Get all webpages under a domain
- Extract every image on a webpage
Integrate Context.dev's scraping endpoints in your app
Prerequisites
-
A Context.dev API key. Sign up at context.dev/signup, copy the key from the dashboard (prefix
ctxt_secret_), and export it: -
An SDK (optional). Install for your language, or skip the install and call directly with
curl:
Scrape a single page to Markdown
GET /web/scrape/markdown scrapes any URL into LLM-ready GitHub Flavored Markdown. Bot protection and geo-blocks are handled by automatic proxy escalation; pass useMainContentOnly: true to drop nav, footer, sidebars, and other chrome.
The endpoint transparently handles HTML, XML, JSON, text, Markdown, SVG, PDF, DOCX, DOC, XLSX, XLS, PPTX, PPT, and CSV. Excel workbooks come back as one GFM table per sheet (with each sheet name as an ## heading); PowerPoint decks come back as slide-structured markdown (one ## Slide N: Title per slide, followed by body text, tables, and speaker notes); CSV files come back as a single GFM table, with any comma-less leading line surfaced as text above it. Unsupported formats (images, media, archives) return a 415.
maxAgeMs return the cached scrape.
Request Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
url | string (URI) | none | Required. Full URL to scrape. Must include http:// or https://. |
includeLinks | boolean | true | Preserve hyperlinks in the Markdown output. |
includeImages | boolean | false | Include image references in the Markdown output. |
shortenBase64Images | boolean | true | Truncate base64-encoded image data so it doesn’t dominate the response. |
useMainContentOnly | boolean | false | Strip headers, footers, sidebars, and navigation, keeping only the main content. |
includeFrames | boolean | false | When true, the contents of iframes are rendered to Markdown. |
includeSelectors | string[] | none | CSS selectors. When provided, only matching HTML subtrees (and their descendants) are kept before conversion to Markdown. Examples: article.main, #content, [role=main]. |
excludeSelectors | string[] | none | CSS selectors to remove before conversion to Markdown. Applied after includeSelectors; exclusion takes precedence. Examples: nav, footer, .ad-banner. |
pdf | object | { shouldParse: true } | PDF-page controls: shouldParse, start, end (1-based inclusive range), ocr. Set shouldParse: false to skip PDFs. Set ocr: true to OCR images embedded in the PDF and inline the recognized text alongside the text layer. |
maxAgeMs | integer | 86400000 (24h) | Return a cached scrape if one exists younger than this. 0 forces a fresh scrape. Max is 30 days. |
waitForMs | integer | none | Browser wait time after initial load (max 30000). Use when the page needs JS time to populate. |
headers | object | none | Outbound HTTP headers forwarded to the target URL, sent as deep-object query params (e.g. headers[X-Custom]=value). When provided, caching is bypassed entirely. |
timeoutMS | integer | none | Abort with a 408 if the request exceeds this many milliseconds. Min 1000, max 300000 (5 min). |
Response
| Field | Type | Description |
|---|---|---|
success | boolean | true when the scrape completed. |
url | string | The URL that was scraped. |
markdown | string | The page rendered as GitHub Flavored Markdown. By default the full page is converted; pass useMainContentOnly: true to strip nav, footer, sidebars, and other chrome. |
contentLength | integer | UTF-8 byte length of markdown. Use this to budget tokens or detect empty results without re-measuring the string. |
Get raw HTML instead
Get raw HTML instead
To get the page as raw HTML:1 credit per callRequest Parameters
Response
| Parameter | Type | Default | Description |
|---|---|---|---|
url | string (URI) | none | Required. Full URL to scrape. |
includeFrames | boolean | false | When true, iframes are rendered inline into the returned HTML. |
useMainContentOnly | boolean | false | Return only the page’s main content, excluding headers, footers, sidebars, and navigation when detectable. |
includeSelectors | string[] | none | CSS selectors. When provided, only matching subtrees (and their descendants) are kept; everything else is dropped. |
excludeSelectors | string[] | none | CSS selectors to remove from the result. Applied after includeSelectors; exclusion takes precedence. |
pdf | object | { shouldParse: true } | PDF-page controls; same shape as /web/scrape/markdown. |
maxAgeMs | integer | 86400000 | Cache TTL. 0 for fresh. Max 30 days. |
waitForMs | integer | none | Wait after initial load (max 30000). |
headers | object | none | Outbound HTTP headers forwarded to the target URL (e.g. headers[X-Custom]=value). When provided, caching is bypassed. |
timeoutMS | integer | none | Abort with a 408 if the request exceeds this many milliseconds. Min 1000, max 300000 (5 min). |
| Field | Type | Description |
|---|---|---|
success | boolean | true when the scrape completed. |
url | string | The URL that was scraped. |
html | string | Rendered HTML for normal pages. For sitemaps and feeds behind an XSL stylesheet, the underlying XML. For Excel workbooks, the extracted sheets as HTML <table> elements (one per sheet, headed by an <h2>). For PowerPoint decks, the extracted slides as HTML (each slide headed by <h2>Slide N: Title</h2>, followed by paragraphs, <table> elements, and an <h3>Notes</h3> block when speaker notes are present). |
type | enum | Detected content type of html. One of html, xml, json, text, csv, markdown, svg, pdf, docx, doc, xlsx, xls, pptx, ppt. |
Crawl a whole site
POST /web/crawl takes a seed URL and returns an array of scraped pages in one call. That’s exactly the shape you want for seeding a RAG index or building a knowledge base.
Request Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
url | string (URI) | none | Required. Starting URL for the crawl. |
maxPages | integer | 100 | Maximum pages to crawl. Hard cap: 500. |
maxDepth | integer | none | Maximum link depth from the starting URL (0 = only the seed). |
urlRegex | string | none | Only URLs matching this regex are followed and scraped. Example: ^https?://[^/]+/blog/. |
followSubdomains | boolean | false | When true, follow links on subdomains (docs.example.com from example.com). www and apex are always treated as equivalent. |
includeLinks | boolean | true | Preserve hyperlinks in each page’s Markdown. |
includeImages | boolean | false | Include image references in each page’s Markdown. |
shortenBase64Images | boolean | true | Truncate base64 image data. |
useMainContentOnly | boolean | false | Strip nav/footer/sidebars on every page. |
includeFrames | boolean | false | Render iframes on every page. |
includeSelectors | string[] | none | CSS selectors. When provided, only matching HTML subtrees (and their descendants) are kept before each page is converted to Markdown. |
excludeSelectors | string[] | none | CSS selectors to remove before each page is converted to Markdown. Applied after includeSelectors; exclusion takes precedence. |
pdf | object | { shouldParse: true } | PDF-page controls. Set shouldParse: false to skip PDFs entirely. |
maxAgeMs | integer | 86400000 | Per-page cache TTL. |
waitForMs | integer | none | Per-page wait after initial load. Max 30000. |
stopAfterMs | integer | 80000 | Soft time budget for the entire crawl (10000–110000). The crawler returns what it has so far when exceeded. |
timeoutMS | integer | none | Hard abort: returns a 408 if the request exceeds this many milliseconds. Min 1000, max 300000 (5 min). |
Response
| Field | Type | Description |
|---|---|---|
results[] | array | One entry per crawled page. |
results[].markdown | string | The page body as GitHub-Flavored Markdown. |
results[].metadata.url | string | The URL that was fetched (after redirects). |
results[].metadata.title | string | The page’s <title> tag value. |
results[].metadata.crawlDepth | number | Link-hops from the seed URL (0 for the seed itself). |
results[].metadata.statusCode | number | HTTP status of the underlying fetch. |
results[].metadata.success | boolean | false for pages that failed to render; markdown may be empty. |
metadata.numUrls | number | Total URLs the crawler attempted. |
metadata.maxCrawlDepth | number | Deepest hop reached during the crawl. |
metadata.numSucceeded | number | Pages fetched successfully. Matches the credit cost. |
metadata.numFailed | number | Pages that errored. |
metadata.numSkipped | number | Pages skipped (e.g. by urlRegex or pdf: { shouldParse: false }). |
Get all URLs of a domain
GET /web/scrape/sitemap reads sitemap.xml from a domain root, follows any nested sitemap indexes, and returns a de-duplicated URL list without rendering any of the pages. Use it for cheap coverage of large sites or to feed a downstream scraper with a curated list.
Request Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
domain | string | none | Required. Domain to build a sitemap for (e.g. example.com). No protocol required; the API validates and normalizes the input. |
maxLinks | integer | 500 | Maximum URLs to return (effective range 1–500). The response’s urls[] array is hard-capped at 500 entries, so values above 500 are clamped. |
urlRegex | string | none | Filter the discovered URLs by regex pattern. |
headers | object | none | Outbound HTTP headers forwarded to the target URL (e.g. headers[X-Custom]=value). When provided, caching is bypassed. |
timeoutMS | integer | none | Abort with a 408 if the request exceeds this many milliseconds. Min 1000, max 300000 (5 min). |
Response
| Field | Type | Description |
|---|---|---|
success | boolean | true when the sitemap crawl completed. |
domain | string | The normalized domain that was crawled. |
urls[] | string[] | Discovered page URLs, de-duplicated. Bounded by maxLinks and capped at 500 entries per response. |
meta.sitemapsDiscovered | number | Total sitemap XML files discovered (root + nested indexes). |
meta.sitemapsFetched | number | Sitemaps actually fetched and parsed. |
meta.sitemapsSkipped | number | Sitemaps skipped (404s, malformed XML, etc.). |
meta.errors | number | Errors encountered during crawling. |
Extract every image on a page
GET /web/scrape/images takes a URL and returns a manifest of every image referenced on the page: <img> tags, inline <svg>, CSS background images, <picture> sources, OpenGraph and Twitter card images, favicons.
Opt into enrichment to also get measured dimensions, a CDN-hosted copy, and a visual-type classification per image.
Request Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
url | string (URI) | none | Required. Page URL to inspect. |
maxAgeMs | integer | 86400000 | Cache TTL (0 forces fresh; max 30 days). |
enrichment.resolution | boolean | false | Measure width × height in pixels when possible. |
enrichment.hostedUrl | boolean | false | Host materializable images on Context.dev’s CDN and return their URL + MIME type. |
enrichment.classification | boolean | false | Classify each image as photography, illustration, logo, wordmark, icon, pattern, graphic, or other. |
enrichment.maxTimePerMs | integer | 30000 | Per-image enrichment timeout (1–60000 ms). |
waitForMs | integer | none | Browser wait after initial load (max 30000). |
headers | object | none | Outbound HTTP headers forwarded to the target URL (e.g. headers[X-Custom]=value). When provided, caching is bypassed. |
timeoutMS | integer | none | Abort with a 408 if the request exceeds this many milliseconds. Min 1000, max 300000 (5 min). |
Response
| Field | Type | Description |
|---|---|---|
success | boolean | true when the scrape completed. |
url | string | The page URL that was scraped. |
images[] | array | One entry per image referenced on the page. |
images[].src | string | For type: "url", the absolute image URL. For type: "html", the raw inline SVG/HTML. |
images[].element | enum | DOM origin: img, svg, link, source, video, css, object, meta, or background. |
images[].type | enum | Format of src: url (external image), html (inline markup like SVG), or base64 (data URI). |
images[].alt | string | null | Alt text where present. |
images[].enrichment.width | number | Pixel width. Present when enrichment.resolution=true. |
images[].enrichment.height | number | Pixel height. Present when enrichment.resolution=true. |
images[].enrichment.mimetype | string | MIME type. Present when hosted via enrichment.hostedUrl=true. |
images[].enrichment.url | string | Context.dev CDN URL. Present when enrichment.hostedUrl=true. |
images[].enrichment.type | enum | Visual category. Present when enrichment.classification=true. One of photography, illustration, logo, wordmark, icon, pattern, graphic, other. |
enrichment flag (resolution, hostedUrl, or classification) bumps the entire call to 5 credits, even if only one image qualifies for enrichment.
Use cases
- Build a RAG pipeline from a docs site by crawling and chunking the returned Markdown.
- Cut LLM token bills by feeding clean Markdown instead of raw HTML.
- Seed a vector index without managing scrapers or proxy infrastructure.
- Monitor competitors’ marketing pages by scraping them on a schedule.
Next steps
Prefetch for Faster Response
Hide cold-hit latency from your users.
Handle Rate Limits
Backoff strategies, client cache, and prefetch fallbacks.
Best Practices
Caching, error handling, and key hygiene.
Troubleshooting
Status codes, retry patterns, and common errors.