Skip to content

POST /extract

Extract structured data from a single URL.

POST https://api.scrapewithruno.com/v1/extract
X-API-Key: sk_live_...
Content-Type: application/json

Request Body

json
{
  "url": "https://example.com/profile/rachel-mcadams",
  "schema": [
    { "field": "firstName",  "type": "string",        "example": "Rachel" },
    { "field": "age",        "type": "integer",       "example": 35 },
    { "field": "netWorth",   "type": "float",         "example": 12500000.00 },
    { "field": "isVerified", "type": "boolean",       "example": true },
    { "field": "tags",       "type": "array<string>", "example": ["actress"] }
  ],
  "options": {
    "render_js": "auto",
    "locale": "en-US",
    "timeout_ms": 15000,
    "process_images": false
  }
}
FieldTypeRequiredNotes
urlstringyesAbsolute URL to fetch
schemaarraydynamic keys onlySee Defining a Schema. Static keys must omit it
options.render_js"auto" | "always" | "never"noDefault "auto"
options.localestringnoBCP-47 tag passed to the browser context (e.g., "en-US", "de-DE")
options.timeout_msintegernoPer-page deadline; default 15000
options.process_imagesbooleannoVision pass on null fields. Scale only

Response

json
{
  "url": "https://example.com/profile/rachel-mcadams",
  "status": "success",
  "render_mode": "headless",
  "data": {
    "firstName": "Rachel",
    "age": 45,
    "netWorth": 8000000.00,
    "isVerified": true,
    "tags": ["actress"]
  },
  "images_processed": null
}
FieldNotes
status"success" or "error"
render_mode"fetch" | "headless" | "structured" | "cache"
dataObject keyed by your schema's field names. Unresolvable fields are null
images_processedNumber of images consumed by the vision pass; null when the pass didn't run
warnings(optional) Coercion warnings; omitted when empty

The job ID for the request is on the response headers as X-Job-ID. See Jobs.

Errors

Most errors come back with status: "error" and a top-level error object:

json
{
  "status": "error",
  "error": { "code": "FETCH_BLOCKED", "message": "...", "retryable": true }
}

Common codes for /extract:

CodeWhen
SCHEMA_INVALIDSchema malformed
SCHEMA_REQUIREDDynamic key without schema
SCHEMA_NOT_ALLOWEDStatic key with inline schema
URL_UNREACHABLEDNS / network failure
TIMEOUTPage exceeded timeout_ms
FETCH_BLOCKEDAnti-bot defeated both fetch and headless
TIER_REQUIREDSite needs T4/T5 bypass (Pro/Scale only)
RATE_LIMITEDPer-minute limit hit
QUOTA_EXCEEDEDMonthly quota exhausted
LLM_*Various LLM failures, see Errors & Retries

Examples

bash
curl -X POST https://api.scrapewithruno.com/v1/extract \
  -H "X-API-Key: $RUNO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/p/123",
    "schema": [
      { "field": "title", "type": "string", "example": "Example product" },
      { "field": "price", "type": "float",  "example": 19.99 }
    ]
  }'
js
const res = await fetch('https://api.scrapewithruno.com/v1/extract', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.RUNO_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    url: 'https://example.com/p/123',
    schema: [
      { field: 'title', type: 'string', example: 'Example product' },
      { field: 'price', type: 'float',  example: 19.99 },
    ],
  }),
})

const jobId = res.headers.get('X-Job-ID')
const json = await res.json()
console.log(jobId, json.data)
py
import os, requests

res = requests.post(
    "https://api.scrapewithruno.com/v1/extract",
    headers={"X-API-Key": os.environ["RUNO_API_KEY"]},
    json={
        "url": "https://example.com/p/123",
        "schema": [
            {"field": "title", "type": "string", "example": "Example product"},
            {"field": "price", "type": "float",  "example": 19.99},
        ],
    },
    timeout=60,
)
print("job:", res.headers.get("X-Job-ID"))
print(res.json()["data"])

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