Extract

Pull structured JSON from a web page or spoken media. For YouTube, podcast feeds, and direct audio/video URLs, Gyrence transcribes the spoken content first; other URLs use the normal HTTP-first fetch pipeline. The resulting text is sent to the extraction model with your prompt and optional schema hint.

Use this when

  • You need a few specific fields from a page (price, title, author, contact email) without writing selectors.
  • The site's HTML changes often and selector-based scraping is too brittle.
  • You want JSON shaped to your own schema, not raw page content.
  • You're prototyping enrichment before committing to a per-domain parser.
  • You need summaries, quotes, chapters, entities, or other fields from a YouTube video, podcast, or media file.
MethodPOST
Path/api/v1/extract
AuthBearer
Credits5 (7 if browser)

Request

ParameterTypeDescription
url
required
stringPublic page, YouTube video, podcast RSS feed, or direct audio/video URL. SSRF-blocked hosts are rejected.
prompt
required
stringNatural-language instruction describing what to extract (e.g. "Return the product title, price in USD, and in-stock status").
schemastringOptional JSON string describing the desired shape. Sent to the model as a target structure. Must be valid JSON — invalid JSON returns `bad_request`.
forceBrowserboolean
default: false
Skip the HTTP-first attempt and render via the headless worker immediately. Use for known JS-heavy SPAs.

Example body

{
  "url": "https://example.com/products/widget",
  "prompt": "Extract the product name, price, currency, and availability.",
  "schema": "{\"name\":\"string\",\"price\":\"number\",\"currency\":\"string\",\"inStock\":\"boolean\"}"
}

Audio and video

Extract automatically recognizes supported media URLs; no extra request field is required. It uses this order:

  1. YouTube caption track, when available.
  2. The newest podcast episode's Podcasting 2.0 transcript (WebVTT, SRT, or JSON), when available.
  3. Speech recognition for a direct media URL or podcast enclosure.
  4. Normal page retrieval when the URL is not a recognized media target.

The console at /app/extract also accepts audio/video files up to 95 MB. File upload is a console workflow; the public /api/v1/extract contract accepts URLs.

{
  "url": "https://www.youtube.com/watch?v=VIDEO_ID",
  "prompt": "Return chapters with title, start time, summary, and notable quotes.",
  "schema": "{\"chapters\":[{\"title\":\"string\",\"startTime\":\"string\",\"summary\":\"string\",\"quotes\":[\"string\"]}]}"
}
Long recordings

Extract sends at most the first 12,000 characters of the transcript to the model. The one-step Extract flow can also time out while long media is still being transcribed. For long recordings, use Fetch transcript mode and its asynchronous status endpoint first, then process the completed segments in your own pipeline.

Response

{
  "ok": true,
  "data": {
    "url": "https://example.com/products/widget",
    "title": "Widget — Example",
    "extractedJson": "{\"name\":\"Widget\",\"price\":29.99,\"currency\":\"USD\",\"inStock\":true}",
    "via": "http"
  }
}
FieldTypeDescription
urlstringThe final URL fetched (after redirects).
titlestringPage title parsed from the fetched HTML.
extractedJsonstringStringified JSON returned by the model. Always a string — parse it client-side. On malformed model output, falls back to `{"_raw": "<original text>"}`.
via"http" | "browser" | "captions" | "podcast_rss" | "asr"How source text was obtained. Media extraction reports its transcript source; normal pages report the fetch tier.
kindstring`transcript` for recognized media inputs; otherwise the fetched source kind.

Example

curl -X POST https://www.gyrence.com/api/v1/extract \
  -H "Authorization: Bearer $GYRENCE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/products/widget",
    "prompt": "Extract the product name, price, currency, and availability.",
    "schema": "{\"name\":\"string\",\"price\":\"number\",\"currency\":\"string\",\"inStock\":\"boolean\"}"
  }'

Errors

CodeHTTPMeaning
bad_request400url missing/invalid, prompt empty, or schema is not valid JSON.
unauthorized401Missing, malformed, or revoked Authorization header.
credits_exhausted402Workspace balance below request cost, or the LLM provider returned 402.
forbidden_url403SSRF guard rejected a private, loopback, or link-local host.
timeout408Request exceeded the 25-second hard deadline.
rate_limited429Per-workspace rate limit, or the LLM provider rate-limited the call.
upstream_error502Page fetch or LLM call returned a 5xx.
unavailable503Any other unmapped error.
{ "ok": false, "error": "Schema must be valid JSON", "code": "bad_request" }
Credits

5 credits when fetched over HTTP, 7 credits when Gyrence escalates to the headless browser. Charged once per call regardless of model response length. See Notes for the full list of escalation triggers.

Limits & known behavior
  • Content is truncated. Only the first 12,000 characters of converted Markdown are sent to the model. Long pages have their tail dropped — narrow the URL (e.g. a product page, not a catalog) for best results.
  • Prompt + page content compete for context. Long prompts reduce the page content the model sees. Aim for prompts under 500 characters; let the schema do the structural work and the prompt focus on what to extract, not how.
  • JSON guarantee is best-effort. The model is instructed to return strict JSON, but malformed output falls back to { "_raw": "<text>" }. Always handle that shape.
  • schema is a hint, not a validator. Gyrence does not enforce types on the model's output. Validate with your own Zod/JSON-schema layer if it matters.
  • One source per call. To extract across many URLs, fan out client-side (use /map to enumerate) and call /extract per URL.
  • YouTube needs captions. If a video has no caption track, Extract returns a transcript-unavailable error; it does not download YouTube audio.
  • Podcast feeds use the newest item. For a specific older episode, provide its direct media URL when available.
  • Media is not persisted. Speech recognition is handled by AssemblyAI and the provider transcript is deleted after delivery.
  • Markdown fidelity. Tables and deeply nested lists may lose structure in HTML→Markdown conversion before the model sees them.

Notes

  • Extract uses Gemini 2.5 Flash — chosen for its 3× cost advantage over comparable models at equivalent extraction quality. The API contract (request/response shape) is stable regardless of underlying model; Gyrence may update the model tier over time. The system enforces strict JSON output — no prose, no markdown fences.
  • Source pipeline: recognized media uses captions, publisher transcripts, or speech recognition before extraction. Other URLs use the /fetch pipeline: HTTP first, with automatic escalation to the headless browser on any of: origin 403/429/503, network error (status 0), body < 500 chars, JS-shell markers (id="root">, id="__next">, <noscript>, etc.), or post-conversion content loss (HTML ≥ 1000 chars producing < 100 markdown chars). forceBrowser: true skips the HTTP attempt.
  • via drives pricing, not the input. Even without forceBrowser, an automatic escalation bills as browser (7 credits).
  • SSRF re-validation runs on the final URL after redirects, not just the input.
  • No retries on model failure. Garbled output is returned as _raw for your inspection rather than re-prompted server-side.
Try it

Test prompts and schemas live in the console at /app/extract — paste a URL, iterate on the prompt, copy the resulting JSON.