Skip to content
Web data APIsExtract

Web data APIs

On this page
POST/api/v1/extract

Extract

Extract structured data from raw HTML you already have. Same service as /api/v1/scrape minus the fetch step. An API key is required — there is no keyless sample path here, and the key is checked before the request body is parsed.

Parameters

ParameterTypeRequiredDescription
htmlstringRequiredThe raw HTML to extract from. Keep the whole request body under 4.5 MB: the hosting platform refuses a larger body with a plain-text HTTP 413 before Contrie reads it. Contrie's own limit is 5,000,000 UTF-8 bytes, and it reads at most the first 100,000 characters of the HTML's markdown; metadata.evidenceCoverage.sourceTruncated is true when it cut.
urlstringOptionalSource URL, used as context and to resolve relative links. Not fetched.
extractstringOptionalNatural language description of what to extract. Max 4,000 characters.
schemaobjectOptionalJSON Schema subset to enforce the output shape. Same rules as /api/v1/scrape. Max 10 KB.
formatstringOptionaljson (default), markdown, or both.

Safe retries

Authenticated JSON requests support the same optional Idempotency-Key contract as Scrape: 8–200 visible ASCII characters, one account and input identity, and an encrypted response replayed for 24 hours with no new inference or credits. A changed request, an expired response or work still in progress returns HTTP 409. Use a new key only for deliberately new work, as in Scrape's example. Streaming requests do not accept this header.

Request Example

curl
curl -X POST https://www.contrie.com/api/v1/extract \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ck_live_your_key_here" \
  -d '{
    "html": "<html><body><h1>Hello World</h1><p>Price: $29.99</p></body></html>",
    "extract": "Get the heading and price",
    "url": "https://example.com/product"
  }'

Response

Same response shape as /api/v1/scrape, including the full metadata object and trace array contains only high-level request progress. That includes metadata.groundingFields, the per-value grounding receipts behind grounding — see Scrape for the full field shape. The scores in this abridged example are what the acceptance checks compute for this answer on this HTML: a natural-language request scores at most 80, because without a schema the requested fields are not counted. The receipt names the source as provided_html: Contrie did not fetch it. Accepted model answers from current deployments also carry metadata.binding: here the price was judged against the passages about it and none stated a different value. A conflict path marks a field as unconfirmed; see Scrape.

200 OK
{
  "success": true,
  "data": {
    "heading": "Hello World",
    "price": "$29.99"
  },
  "metadata": {
    "url": "https://example.com/product",
    "qualityScore": 80,
    "qualityScoreKind": "structural_and_textual",
    "valid": true,
    "coverageMeasured": false,
    "completeness": 1,
    "grounding": 1,
    "latencyMs": 1820,
    "trace": [
      { "stage": "loading", "detail": "Loading source" },
      { "stage": "processing", "detail": "Processing request" },
      { "stage": "complete", "detail": "Request complete" }
    ],
    "groundingCoverage": { "total": 2, "checkable": 2, "grounded": 2 },
    "binding": { "judged": 1, "conflicts": [], "truncated": false },
    "source": { "mode": "provided_html", "url": "https://example.com/product" },
    "cached": false,
    "credits": 1
  }
}

Streaming

Same as /api/v1/scrape: send Accept: application/x-ndjson for high-level request progress. See Streaming.

When to Use Extract vs Scrape

Use CaseEndpoint
You have a URL and want data from it/api/v1/scrape
You already fetched the HTML yourself/api/v1/extract
You need custom fetch headers or auth cookies/api/v1/extract
The page is a JavaScript-only shell (server HTML has no content)/api/v1/scrape (renders by default), or render it yourself and use /api/v1/extract
You want a single endpoint that handles everything/api/v1/scrape

/api/v1/scrape renders a JavaScript-only page in a browser by default (render: "auto", 2 extra credits when the rendered answer is accepted). Send HTML here instead when you need your own browser session, cookies or interactions, or when scrape returns RENDER_REQUIRED (see Error Codes).