---
title: "Fetch a web page as clean extracted content"
method: POST
path: "/api/v1/web/fetch"
tags: ["Web"]
---

# Fetch a web page as clean extracted content

`POST /api/v1/web/fetch`

## Request

- Base URL: `https://glim.sh`
- URL: `https://glim.sh/api/v1/web/fetch`
- Auth: one of:
  - none
  - API key in header `x-api-key`
  - HTTP bearer
  - API key in query parameter `apiKey`

Extract content from a web page as markdown, HTML, or JSON.

## Request body

- object
  - `url` string, required: URL to fetch
  - `format` 'markdown' | 'html' | 'json': Output format. 'markdown' (default) clean article text; 'html' raw cleaned HTML; 'json' the structured SSR blob (TikTok, Pinterest, etc.) instead of article text.
  - `selector` string: CSS selector to scope the result. An anchor-id selector (e.g. a docs anchor like '#usage') that lands on a heading expands to the heading's whole section, up to the next same-or-higher-level heading; other selectors return the matched elements themselves.

## Response `200`

Fetched content

- object: FetchResult
  - `status` integer, required
  - `content` string[], required
  - `url` string, required
  - `title` string: Article title, when extracted from the page metadata.
  - `author` string: Article author/byline, when extracted from the page metadata.
  - `published_date` string: Article publication date (ISO 8601), when extracted from the page metadata.
  - `modified_date` string: Last-modified date (ISO 8601), when the page publishes one.
  - `description` string: Page summary, from og:description / meta description.
  - `site_name` string: Publishing site name, from og:site_name.
  - `section` string: Site section/category, from article:section.
  - `lang` string: Page language, from the html lang attribute.
  - `image` string: Lead image URL, from og:image / twitter:image.
  - `favicon` string: Site favicon URL.
  - `outcome` 'success' | 'teaser' | 'thin_content' | 'paywall' | 'bot_challenge' | 'consent_wall' | 'login_wall' | 'rate_limited' | 'timeout' | 'transient_upstream' | 'unsupported_target' | 'not_found' | 'error', required: Classified result type. Use this to branch your retry / strategy logic.
  - `paywalled` boolean: True when the URL is paywalled. Set alongside the real outcome (e.g. teaser, not_found, bot_challenge).
  - `unsupported_reason` string: When outcome=unsupported_target, why the URL pattern is permanently unsupported.
  - `alternatives` string[]: When outcome=unsupported_target, alternative URL patterns or tools that may work.
  - `total_chars` integer: Full extracted content length in characters, before any inline truncation.
  - `truncated` boolean: True when content was truncated to fit the inline cap; full content at download_url.
  - `truncated_chars` integer: Characters NOT included inline (available via download_url).
  - `download_url` string: Presigned HTTPS URL to download the full extracted content. Set when truncated.
  - `file_url` string: Presigned HTTPS URL to download the ORIGINAL file (PDF, docx, pptx, ...) this content was extracted from. Distinct from download_url, which is the extracted text. Set whenever the fetch parsed a real file - including one we identified but declined to convert, so the bytes are still reachable.
  - `file_bytes` integer: Size of file_url's object in bytes.
  - `file_type` string: Content type of file_url's object, e.g. application/pdf.
  - `expires_at` string: ISO 8601 UTC timestamp when download_url / file_url expire (~1h).

## Other responses

- `400`: Bad Request
- `402`: Payment Required
- `429`: Too many concurrent requests
- `502`: Upstream Error

---

[API](https://skmtc.dev/glim/apis/glim-sh.md) · [All operations](https://skmtc.dev/glim/apis/glim-sh/llms.txt) · [OpenAPI document](https://skmtc.dev/glim/apis/glim-sh/revisions/0094e5226d73?raw)
