---
title: "Extract structured data from URLs"
method: POST
path: "/v1/web/extract"
tags: ["Extract"]
---

# Extract structured data from URLs

`POST /v1/web/extract`

## Request

- Base URL: `https://api.hydrafetch.com`
- URL: `https://api.hydrafetch.com/v1/web/extract`
- Auth: API key in header `X-API-Key`

Pull schema-shaped JSON out of one or many pages in a single call. An LLM maps each page onto your schema and/or prompt. Point at a single page, a list, or a crawl scope with a trailing `/*` wildcard; optionally let web search find extra source pages, return per-field confidence with the source passage behind each value, and merge everything into one deduplicated collection of entities. Charged per page that returns data.

## Request body

- ExtractRequestDto
  - `urls` string[], required: The pages to extract from. Each must be an http(s) URL. A trailing `/*` marks a crawl scope: every page discovered under that path is extracted and merged into the result.
  - `schema` object: JSON Schema describing the shape you want back. Optional if `prompt` is given; when both are present the schema fixes the field names and types while the prompt guides what to pull.
  - `prompt` string: Natural-language instruction for what to extract. Use with or instead of a schema.
  - `preferStructure` boolean: Preserve document structure (headings, lists, tables) over prose density when reading the page — good for listing and catalog pages. Default off.
  - `enableWebSearch` boolean: Pull in extra source pages by web-searching your prompt, to fill fields your URLs do not cover. Requires a `prompt`.
  - `showSources` boolean: Return the concrete list of URLs that were actually extracted, after any wildcard and web-search expansion. Default off.
  - `showConfidence` boolean: For each field, return a confidence score and the exact source passage the value was drawn from. Default off.
  - `mergeEntities` boolean: Merge the per-page results into one deduplicated collection — one row per entity, with its contributing source URLs — instead of a separate result per page. Default off.
  - `maxAge` number: Reuse a recent capture of each page if it is younger than this many milliseconds. Omit or 0 to always fetch fresh. Capped at 7 days.
  - `location` LocationDto
    - `country` string: ISO 3166 alpha-2 country to fetch the page as if from.
    - `languages` string[]: Preferred content languages, most-preferred first.
  - `headers` object: Extra request headers to send when fetching each page, such as a cookie that picks the store or delivery area a site prices by.

## Response `200`

The extracted data.

- ExtractResponseDto
  - `data` ExtractResultDto, required
    - `results` ExtractItemResultDto[], required: One result per extracted page.
      - `url` string, required: The page this result came from.
      - `data` object, nullable, required: The extracted data, shaped by your schema and/or prompt. Null when nothing matched.
      - `fields` object: Per-field confidence and source passage, keyed by field name. Present only when `showConfidence` is set.
      - `error` object, nullable, required: Set when this page could not be extracted; null on success.
    - `sources` string[]: The concrete URLs actually extracted, after wildcard and web-search expansion. Present only when `showSources` is set.
    - `collection` MergedEntityDto[]: The deduplicated collection, one row per entity. Present only when `mergeEntities` is set.
      - `data` object, required: The unioned data for one entity, filled across every contributing page.
      - `sources` string[], required: Every source URL that contributed to this entity.

## Other responses

- `400`: The request body or query failed validation.
- `401`: The X-API-Key header is missing, malformed, or names a key that no longer exists.
- `402`: The workspace has no credits left for this request. Nothing was charged and nothing was fetched.
- `403`: The key is valid but the workspace may not make this request.
- `404`: No such job, or the id belongs to another workspace.
- `422`: The target site did not respond, or we could not read that page. This is a fact about that URL rather than a fault on our side, and retrying it will not change the answer. When details.retryAfterSeconds is present, asking again before then returns this same answer. Nothing was charged.
- `429`: The workspace exceeded its per-minute request limit. Read the RateLimit headers, or Retry-After on this response, and retry after the window resets.
- `500`: Unexpected server error. Nothing was charged.
- `503`: A dependency needed for the requested formats is unavailable. Safe to retry.

---

[API](https://skmtc.dev/hydrafetch/apis/hydrafetch-api.md) · [All operations](https://skmtc.dev/hydrafetch/apis/hydrafetch-api/llms.txt) · [OpenAPI document](https://skmtc.dev/hydrafetch/apis/hydrafetch-api/revisions/b28322984b4b?raw)
