---
title: "Scrape one URL"
method: POST
path: "/v1/scrape"
tags: ["scrape"]
---

# Scrape one URL

`POST /v1/scrape`

## Request

- Base URL: `https://api.fastcrw.com`
- URL: `https://api.fastcrw.com/v1/scrape`
- Auth: one of:
  - HTTP bearer
  - none

## Request body

- ScrapeRequest
  - `url` string, uri, required
  - `formats` OutputFormat[]
  - `onlyMainContent` boolean: Strip navigation, ads, and boilerplate; keep main article content only
  - `renderJs` boolean, nullable: null = auto-detect, true = force JS rendering, false = skip JS rendering
  - `waitFor` integer: Milliseconds to wait after JS rendering before extracting content
  - `includeTags` string[]: CSS selectors / HTML tags to include in extraction
  - `excludeTags` string[]: CSS selectors / HTML tags to remove before extraction
  - `jsonSchema` object: JSON Schema describing the structured output shape for the 'json' format
  - `basis` boolean: Return per-field evidence alongside the 'json' format: each top-level scalar schema property comes back as a Basis with an honest status. Requires a JSON schema; off by default, and when off the request sent to the model is unchanged.
  - `headers` object: Custom HTTP request headers forwarded to the target URL
  - `cssSelector` string: CSS selector to narrow content extraction to a specific element
  - `xpath` string: XPath expression to narrow content extraction to a specific element
  - `chunkStrategy` ChunkStrategy: Strategy for chunking extracted markdown before query-based filtering
    - `type` 'sentence' | 'regex' | 'topic', required: Chunking algorithm: sentence = split on .!?, regex = split on pattern, topic = split on markdown headings
    - `maxChars` integer: Maximum characters per chunk (merges short chunks up to this limit)
    - `overlapChars` integer: Character overlap between adjacent chunks
    - `dedupe` boolean: Remove duplicate chunks
    - `pattern` string: Regex pattern to split on (required when type = 'regex')
  - `query` string: Query string for BM25/cosine chunk filtering (used with chunkStrategy)
  - `filterMode` 'bm25' | 'cosine': Filtering algorithm to rank chunks against query
  - `topK` integer: Number of top chunks to return after filtering (default: 5)
  - `proxy` string: Per-request proxy URL (http/https/socks5). Overrides global config.
  - `proxyList` string[]: Per-request proxy pool to rotate among (BYOP). Takes precedence over proxy and server config.
  - `proxyRotation` 'round_robin' | 'random' | 'sticky_per_host': Rotation strategy for proxyList (default: sticky_per_host)
  - `country` string: 2-letter ISO 3166-1 alpha-2 country code for residential proxy egress (e.g. 'us', 'gb')
  - `stealth` boolean: Override stealth mode for this request (null = use global config)
  - `actions` object: Unsupported Firecrawl parameter — returns a clear error if supplied
  - `extract` ExtractOptions: Firecrawl-compatible extraction options sub-object
    - `schema` object: JSON Schema for structured extraction. Used as jsonSchema when jsonSchema is not set directly.
  - `llmApiKey` string: BYOK: LLM provider API key for structured extraction (overrides server key)
  - `llmProvider` 'anthropic' | 'openai' | 'deepseek' | 'azure' | 'openai-compatible' | 'openai-responses': Per-request LLM provider override
  - `llmModel` string: Per-request LLM model identifier override
  - `baseUrl` string: Per-request LLM base URL override for Chat Completions-compatible or Responses-compatible providers (e.g. https://api.deepseek.com/v1)
  - `summaryPrompt` string: User-supplied instructions appended to the summary system prompt (capped at 500 chars)
  - `maxContentChars` integer: Maximum bytes of scraped content sent to LLM for 'summary' format (capped at 200 KB)
  - `renderer` 'auto' | 'lightpanda' | 'chrome' | 'chrome_proxy' | 'playwright' | 'camoufox' | 'impersonated-http': Pin this request to a specific renderer. A non-auto browser tier implies renderJs:true unless renderJs:false is set. impersonated-http is a JS-less tier that presents a real Chrome TLS fingerprint; it never implies renderJs, and combining it with renderJs:true is rejected.
  - `deadlineMs` integer: End-to-end deadline budget in milliseconds (default: 8000, max: 60000)
  - `debug` boolean: When true, response includes debugExtraction trace with every candidate the extractor considered
  - `changeTracking` ChangeTrackingOptions
    - `modes` string[]: Diff surfaces. gitDiff = markdown unified diff + AST; json = per-field diff; both = mixed.
    - `schema` object: JSON schema of tracked fields (json/mixed mode)
    - `prompt` string
    - `previous` ChangeTrackingSnapshot
      - `markdown` string: Present for gitDiff/mixed mode
      - `json` object: Present for json/mixed mode
      - `contentHash` string: Mode-aware hash; persist + supply on the next check
      - `capturedAt` string: Caller-stamped capture time, echoed untouched
    - `tag` string: Opaque caller tag echoed on the result
    - `contentType` string: MIME type; non-text content is hashed, not diffed
  - `goal` string: Plain-language monitor goal for the meaningful-change judge
  - `judgeEnabled` boolean: Run the LLM meaningful-change judge on a changed page (requires goal)
  - `parsers` ParserSpec[]: Document parser directives. Omit = auto-parse PDFs. Empty array = disable parsing.
    - `type` 'pdf', required: Parser type (only 'pdf' is supported)
    - `mode` 'auto' | 'fast' | 'ocr': Parsing strategy (auto = text-first; ocr degrades to text extraction with a warning)
    - `maxPages` integer: Optional cap on the number of pages to parse
  - `screenshotFullPage` boolean: Capture the whole page rather than the viewport, for `formats: ["screenshot"]`.
  - `maxAge` integer: How old a cached copy of this fetch may be, in milliseconds. 0 always fetches. Clamped to a 24 hour ceiling. Extraction options (formats, schema, selectors) are not part of the cache key, so a second pass over the same page reuses the fetch.
  - `storeInCache` boolean: Set false to read the cache without writing to it.

## Response `200`

Scrape result

- ScrapeResponse
  - `success` boolean, required
  - `warning` string: Top-level advisory (e.g. fallback render notice)
  - `data` object, required
    - `markdown` string
    - `html` string
    - `rawHtml` string
    - `links` string[]
    - `json` object
    - `metadata` PageMetadata
      - `title` string
      - `description` string
      - `sourceURL` string, uri
      - `statusCode` integer
    - `warning` string
    - `warnings` string[]
    - `renderDecision` object: How the renderer was chosen. A tagged object: `kind` is one of `userPinned`, `autoDefault`, `autoPromoted`, `breakerSkipped`, `failover`, and the remaining fields depend on it.
      - `kind` string
    - `creditCost` number
    - `basis` Basis[]: Per-field evidence for the 'json' format; present only when the request set basis:true.
      - `basisVersion` integer, required
      - `field` string, required
      - `value` unknown, required
      - `status` 'supported' | 'unverified' | 'unsupported' | 'notFound', required: How well an extracted field is attributed to its source. Honest: a field whose attribution could not be verified is 'unverified'/'unsupported' rather than given a fabricated citation.
      - `confidence` 'low' | 'medium' | 'high'
      - `citations` EvidenceCitation[], required
        - `url` string, required: The document the engine fetched.
        - `title` string
        - `excerpt` string: Verbatim span from the canonical source text. Absent when the span could not be established (status 'unverified').
        - `sourceHash` string, required: 'sha256:<hex>' of the exact text sent to the model.
        - `sourceTextKind` string, required: Which text sourceHash covers. 'llmInput' for extraction basis (the truncated markdown sent to the model).
    - `basisWarnings` BasisWarning[]
      - `field` string, required
      - `code` string, required
    - `llmInputHash` string: 'sha256:'-prefixed hash of the canonical text sent to the extraction LLM. The independent record a consumer checks a citation's sourceHash against, so the check is not circular.
    - `sourceHash` string: Fingerprint of the canonical markdown, for dedup and caching.
    - `plainText` string: Plain-text view; present when `formats` includes `plainText`.
    - `images` object[]: Present when `formats` includes `images`.
      - `url` string, uri, required
      - `alt` string
    - `summary` string: LLM summary; present when `formats` includes `summary`.
    - `llmUsage` object: Token usage for the LLM call, when one ran.
    - `chunks` object[]: Chunked content, when a `chunkStrategy` was requested.
    - `contentType` string: MIME type of the fetched resource.
    - `changeTracking` object: Diff result; present when `formats` includes `changeTracking`.
    - `screenshot` string: PNG capture as a `data:image/png;base64,...` URL; present when `formats` includes `screenshot`.
    - `block` object: Anti-bot verdict. Present only when the page was a block or challenge shell, in which case `success` is false.
    - `debugExtraction` object: Extraction trace; present only when `debug: true`.

## Other responses

- `400`: Invalid request body
- `401`: Missing or invalid bearer token (hosted only)

---

[API](https://skmtc.dev/fastcrw/apis/crw-rest-api.md) · [All operations](https://skmtc.dev/fastcrw/apis/crw-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/fastcrw/apis/crw-rest-api/revisions/9bc1842aa048?raw)
