Docs

Call an indexed website

Every website Unbrowse has compiled is an HTTP API: one POST per tool, typed inputs, a verified result. This page is the contract — the endpoint, auth, the answer, the options and the errors — with the same call in curl, TypeScript and Python.

What each site gives you

For a host such as docs.rs:

WhatWhere
Tools, with ready-to-copy callsGET https://unbrowse.ai/api/v1/sites/docs.rs (no key needed)
OpenAPI 3.1 documentGET https://unbrowse.ai/api/v1/sites/docs.rs/openapi.json (no key needed)
One toolPOST https://unbrowse.ai/api/v1/sites/docs.rs/call/<tool>
The same tools as an MCP serverhttps://unbrowse.ai/api/v1/sites/docs.rs/mcp
The page people readhttps://unbrowse.ai/sites/docs.rs

Find a site with GET /api/v1/sites?q=<words>. A site Unbrowse has not compiled yet can be learned: see the Quickstart.

The OpenAPI document

openapi.json is a complete OpenAPI 3.1 description, so any OpenAPI tool can read it:

Generate a client with any OpenAPI generator, for example:

npx openapi-typescript https://unbrowse.ai/api/v1/sites/docs.rs/openapi.json -o docs-rs.d.ts

Signed in (with your key), the document also lists your own tools on that site (my__…) and your organisation's (org__…). Add ?minVersion=YYYY.MM.DD to leave out tools an older Unbrowse version generated.

Auth

Every call takes your API key as a bearer token. Mint one in MCP & keys; keys start with ub_live_.

Authorization: Bearer ub_live_…

An OAuth access token (from the MCP sign-in) works the same way. With an organisation key, add X-Unbrowse-End-User: <their id> to run as one of your users, in their own workspace with their own logins.

Call a tool

The body is the tool's inputs. Nothing else is required.

curl -s 'https://unbrowse.ai/api/v1/sites/docs.rs/call/docs_rs__get_search' \
  -H "authorization: Bearer $UNBROWSE_API_KEY" \
  -H "content-type: application/json" \
  -d '{"query":"serde"}'

TypeScript, with the SDK (npm i @unbrowse/sdk):

import { Unbrowse } from "@unbrowse/sdk";

const ub = new Unbrowse(); // reads UNBROWSE_API_KEY
const run = await ub.callTool("docs.rs", "docs_rs__get_search", { query: "serde" });
if (run.status === "succeeded") console.log(run.result);

Python:

import os, requests

r = requests.post(
    "https://unbrowse.ai/api/v1/sites/docs.rs/call/docs_rs__get_search",
    headers={"Authorization": f"Bearer {os.environ['UNBROWSE_API_KEY']}"},
    json={"query": "serde"},
    timeout=120,
)
r.raise_for_status()
run = r.json()
if run["status"] == "succeeded":
    print(run["result"])

The answer

Every call answers with the run:

{
  "runId": "lrun_12meih1",
  "status": "succeeded",
  "capabilityId": "public.docs_rs.get_search",
  "result": { "title": "…", "text": "…", "links": [{ "text": "serde", "href": "https://docs.rs/serde" }] },
  "via": "http"
}
statusHTTPMeaningBilled
succeeded200result is the site's answer, verifiedonce
failed200error says why (the site refused, changed, or did not answer)never
input_required202the tool needs a choice it found on the site: answer requirements with POST /api/v1/runs/{runId}/responseswhen it succeeds

Only verified successes bill. A tool marked x-unbrowse-personal runs signed in as you on its site: its answers are your account's.

Options

OptionHowWhat it does
Deadlineheader x-unbrowse-deadline-ms, or deadlineMs in the body (5,000–300,000; default 60,000)Answer within this time. Past it: 504 run_timeout with a runId; the run keeps going, poll GET /api/v1/runs/{runId}
Retry safelyheader Idempotency-Key: <your id>A repeat with the same key returns the same run instead of starting another
Smaller answersselect in the body: ["results[].{title,url}", "total"]Keep only these parts of the result. Results over 40,000 characters are shortened (truncated)
Act for an end userheader X-Unbrowse-End-User (organisation keys)Runs in that user's workspace

A tool that has an input named deadlineMs or select keeps it; the option then goes in the header (deadline) or is not available (select).

Errors

Errors answer { "error": { "code", "message" } }; the message says what to do.

HTTPcodeWhat to do
400bad_request, invalid_inputSend JSON; fix the value the message names
401unauthorizedSend Authorization: Bearer <key>
402quota_exceeded, insufficient_paid_creditsOut of verified calls this month, or out of paid credits: top up
404not_foundNo such tool on this site: list them with GET /api/v1/sites/<host>
409tool_quarantinedThe tool failed its checks and is rechecked automatically; the message names what to use now
422unknown_argumentAn input the tool does not take; the message lists the ones it does
429rate_limitedRetry after Retry-After
504run_timeoutPoll the runId it gives, or raise the deadline

Every code: Errors & statuses.

Which tools you see

Tools are checked on a schedule. One that keeps failing is quarantined: it leaves listings and the OpenAPI document until it passes again, and calling it answers 409 tool_quarantined. A tool that needs a sign-in is offered only when your workspace has a saved login or a live session for that site.

Or use MCP

The same tools are an MCP server per site, for agents that speak MCP:

claude mcp add --transport http docs-rs https://unbrowse.ai/api/v1/sites/docs.rs/mcp

All sites at once, with discovery and the cloud browser: https://unbrowse.ai/mcp.