Skip to content

Core Concepts

A short tour of the ideas that shape every Runo request.

Schema-as-JSON

A schema is a flat array of fields. Each field declares what it is and not where to find it on the page.

json
[
  { "field": "title", "type": "string",  "example": "MacBook Pro 14\"" },
  { "field": "price", "type": "float",   "example": 1999.00 },
  { "field": "inStock", "type": "boolean", "example": true }
]

Three pieces matter:

KeyRequiredPurpose
fieldyesOutput key in the response data object.
typeyesOne of: string, integer, float, boolean, date, array<string>, array<integer>, array<float>.
exampleyesA representative value. Acts as a one-shot anchor for the LLM. Examples strongly improves accuracy on ambiguous fields.
hintnoFree-form guidance ("Use sale price if present").

Runo extracts by semantic meaning, so when a site re-skins or restructures its HTML, your call keeps working.

Static vs. Dynamic Keys

Two key types, picked when you create a key in the dashboard.

TypePrefixSchema SourceWhy Pick It
Dynamicsk_live_schema in every request bodyYou extract many different shapes, or are still iterating
Staticsk_static_Bound to the key at creationOne shape, lots of pages

Rules:

  • Dynamic key without schema422 SCHEMA_REQUIRED.
  • Static key with inline schema400 SCHEMA_NOT_ALLOWED.
  • Static-key schema is editable later (PATCH from the dashboard); the prompt cache is invalidated on edit.

The Null Sentinel

Runo never silently drops fields. If a value cannot be resolved, it returns null explicitly:

json
{
  "data": {
    "title": "Stonehenge",
    "population": null,
    "founder": null
  }
}

This means data always has the same keys as your schema. Your downstream code can be null-aware instead of undefined-aware.

Type Coercion

Declared types are enforced. Common cases:

DeclaredPage ContainsCoerced to
integer"35 years old"35
float"$1.2M"1200000.0
boolean"✓ Verified"true
date"March 14, 2024""2024-03-14" (ISO 8601)

If a value cannot be coerced cleanly, you'll get either null (preferred) or a TYPE_COERCION_FAILED error for that record. Coercion warnings appear in warnings: [...] on the response when present.

Render Modes

Many pages need JavaScript to render their content. Runo handles this for you with three modes via options.render_js:

render_jsBehavior
"auto" (default)Plain HTTP fetch first; auto-escalate to a stealth headless browser if the page is empty, JS-gated, or actively blocking bots.
"always"Skip the fetch - go straight to headless. Slower, more reliable for SPAs.
"never"Plain fetch only. Fastest, but fails on JS-heavy pages.

In practice, "auto" is the right default. See JS Rendering & Bypass for details on the escalation triggers and the paid-tier bypass for hardened sites.

Three Modes For Three Jobs

EndpointWhen to Use It
POST /extractOne URL, one record back.
POST /batchMany URLs, same schema. Returns an array of /extract responses.
POST /crawlSeed URL + a follow_pattern. Runo follows links up to max_pages/max_depth, respects robots.txt, and refunds unused units.

/batch and /crawl accept async_mode: true. Useful when you don't need results immediately and want to fire-and-forget a large batch. See Async Mode & Cancellation.

What Counts As a Request

EndpointCost
/extract1 request
/batch1 request per URL
/crawlReserves max_pages upfront; refunds whatever it doesn't use

Crawl reservations are also capped by your remaining quota, see Plans, Rate Limits & Overage.

Released under the terms of Runo’s Terms of Use.