---
title: "Structured Data Extraction API (Distill): Exact JSON"
description: "POST /v2/distill extracts fields from up to 50 URLs into the JSON Schema you send. A free CSS pass runs first and a capped LLM pass fills the rest, in exactly the shape you asked for."
canonical: "https://www.enconvert.com/de/structured-data-extraction-api"
locale: "de"
---

# Distill, the structured data extraction API

Send URLs and a schema, get JSON back in that shape.

[See the plans](/de/pricing.md)[Read the docs](/docs/endpoints/distill.md)

Distill runs on paid plans, from $29 a month.

`POST /v2/distill`

Copy

```
curl -X POST https://api.enconvert.com/v2/distill \
  -H "X-API-Key: sk_your_private_key" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://www.enconvert.com/pricing"],
    "schema": { "type": "object", "properties": { "plans": {
      "type": "array", "items": { "type": "object", "properties": {
        "name": { "type": "string" },
        "price_usd": { "type": "number" },
        "ops_per_month": { "type": "integer" } } } } } }
  }'
```

`200 OK, results[0]`

Trimmed

```
{
  "status": "completed",
  "extraction_tier": "llm",
  "data": { "plans": [
    { "name": "Founding", "price_usd": 0, "ops_per_month": 500 },
    { "name": "Indie", "price_usd": 29, "ops_per_month": 3000 },
    { "name": "Studio", "price_usd": 99, "ops_per_month": 15000 },
    { "name": "Production", "price_usd": 299, "ops_per_month": 50000 }
  ] }
}
```

## The schema you send, filled

The data matches the shape you asked for, key for key.

The schema, as sent

```
{
  "type": "object",
  "properties": {
    "plans": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "price_usd": { "type": "number" },
          "ops_per_month": { "type": "integer" }
        }
      }
    }
  }
}
```

The result row, with what it cost

```
{
  "url": "https://www.enconvert.com/pricing",
  "status": "completed",
  "data": { "plans": [ […] ] },
  "extraction_tier": "llm",
  "fields_from_css": 0,
  "fields_from_llm": 1,
  "render_quality": 1.0,
  "tokens": { "input": 4317, "output": 175 },
  "cost_cents": 0.5192,
  "warnings": []
}
```

Real output, captured 2026-11-11. \[…\] marks a cut.

## What you send and get

| Field | What it does |
| --- | --- |
| `urls` | Up to 50 URLs a request, or discover\_from a seed URL to find up to 50 pages first. |
| `schema` | A JSON Schema object, or a flat map of field names to descriptions. |
| `css_schema` | Optional selectors. The fields they fill are free, and only the empty ones go to the LLM pass. |
| `data` | Normalized to exactly your schema’s keys. A missing value is null and a missing list is empty. |
| `cost_cents` | The LLM pass spends AI credits, capped at $0.05 a call and $0.50 a request. |

## What one call replaces

-   ### A scraper for every site

    You describe the fields, and selectors are optional.

-   ### A prompt chain

    The LLM pass runs only for fields the free CSS pass left empty.

-   ### A shape check

    The data comes back in your schema’s exact keys.

![Left: a box of buttons, spools, clips and bolts in a jumble. Right: the same pieces sorted into a tray, one compartment green.](/landing/distill-720.webp)

## Your first extraction

1.  ### Pick a paid plan

    [`Indie, Studio or Production`](/de/pricing.md)
2.  ### Send URLs and a schema

    [`POST /v2/distill`](/docs/endpoints/distill.md)
3.  ### Read the data, key for key

    [`results[0].data`](/docs/endpoints/distill#response)

## More of the same API

-   [URL to Markdown API](/de/url-to-markdown-api.md)

    Any URL as clean Markdown, with a score.

    `Perceive POST /v2/perceive`
-   [Web Scraping API](/de/web-scraping-api.md)

    One render, every output, each read scored.

    `Perceive POST /v2/perceive`
-   [RAG Ingestion API](/de/rag-ingestion-api.md)

    A site or a set of files in, one chunked JSONL out.

    `Ingest POST /v2/ingest`
-   [Web Search API](/de/web-search-api.md)

    A query in, ranked results and their pages out.

    `Lookup POST /v2/lookup`
-   [Website Change Monitoring API](/de/website-change-monitoring-api.md)

    Watch a URL and get a webhook when it changes.

    `Watch POST /v2/watch`

## Questions about structured extraction

### How do I extract structured data from a website with an API?

Send POST /v2/distill with urls (up to 50 a request) and a schema, either a JSON Schema object or a flat map of field names to descriptions. The response data comes back normalized to exactly your schema’s top-level keys.

### Do I have to write CSS selectors?

No. css\_schema is optional, and without it every field goes to the LLM pass. Supplying one fills the selector-addressable fields for free and escalates only the fields it left empty.

### How is the LLM cost capped?

The caps are layered: $0.05 per LLM call, $0.50 per request, at most 50 escalations a request, and your monthly AI-credit balance. LLM extraction spends credits, not ops. Hitting a cap never fails the request: the affected fields come back null with a warning.

### Why are some fields null in the response?

Missing values are normalized to null, and missing lists to empty, to keep the shape guarantee. The LLM pass is skipped, with a warning, when the page was flagged as blocked or a budget cap was reached.

### Can I extract the same schema from a whole site?

Yes. Send discover\_from with a seed url, a mode (sitemap, crawl or hybrid) and max\_pages from 1 to 50 instead of urls.

### Which plans include it?

Distill requires a paid plan, and on the free plan the request is rejected with a 402. Each completed URL is one op, and the LLM pass spends monthly AI credits: $5, $15 or $40 on Indie, Studio and Production.

## Get JSON in your shape

[See the plans](/de/pricing.md)[Read the docs](/docs/endpoints/distill.md)
