The web, as your agent reads it.
vision answers from its cache when it can, fetches over plain HTTP when that is enough, and claims a warm Chrome only when a page needs JavaScript. Pages come back as Markdown, HTML, links or screenshots. Sessions give an agent its own browser over CDP.
- API
- /v1/vision
- CLI
- b3os scrape · b3os session
- MCP tools
- vision_*
[01/03] What it does
Scrape
One URL in, Markdown out. The response says what served it: the cache, a plain fetch or a browser.
POST /v1/vision/scrape
Crawl and map
Crawl up to 500 pages per job with robots.txt honored, or list a site's URLs from its sitemaps without fetching them.
POST /v1/vision/crawls · /map
Read a URL with GET
Put any URL after /r/ and get Markdown back, for tools that can only issue a GET.
GET /v1/vision/r/{url}
Browser sessions
One browser process per session. Connect Playwright or Puppeteer over CDP, or send navigate, click, type, scroll, evaluate and screenshot steps in one act call.
POST /v1/vision/sessions
Profiles
Save cookies and storage from a session and load them into the next one. A profile never leaves its organization.
/v1/vision/profiles
Firecrawl compatible
The Firecrawl v1 and v2 APIs under /compat/firecrawl. Point the Firecrawl SDK at B3OS by changing two environment variables.
/compat/firecrawl/v1 · /v2
Cache
A fresh copy answers first. The shared cache only serves requests without custom headers, cookies, a profile or actions.
Plain fetch
HTML over HTTP through the egress guard, converted to Markdown in Rust.
Warm browser
Only when the page needs JavaScript: a pre-created context in a running Chrome.
Response
The tier and cache.state fields say which one answered; timing says where the time went.
curl -sS -X POST https://beta-api.b3os.org/v1/vision/scrape \
-H "Authorization: Bearer $B3OS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/pricing","formats":["markdown","links"]}' \
-D - # print response headers, including Server-Timingconst res = await fetch("https://beta-api.b3os.org/v1/vision/scrape", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.B3OS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com/pricing",
formats: ["markdown", "links"],
}),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const data = await res.json();
console.log(res.headers.get("server-timing"));import os
import httpx
res = httpx.post(
"https://beta-api.b3os.org/v1/vision/scrape",
headers={"Authorization": f"Bearer {os.environ['B3OS_API_KEY']}"},
json={
"url": "https://example.com/pricing",
"formats": ["markdown", "links"],
},
timeout=65,
)
res.raise_for_status()
data = res.json()
print(res.headers.get("server-timing")){
"name": "vision_scrape",
"arguments": {
"url": "https://example.com/pricing",
"formats": [
"markdown",
"links"
]
}
}- Every fetch and navigation goes through the egress guard: no loopback, private networks, tailnet or metadata addresses.
- robots.txt and Content Signals are respected by default.
[02/03] Measured
What we measure for vision
Values appear here only from published benchmark runs, each with its raw data. A row that says measuring has no published run yet.
Scrape from cache
A scrape answered from the shared cache, server side.
Plain-fetch overhead
Time added over the origin's time to last byte, for HTML up to 300 KB at a stated concurrency. Extraction is timed separately.
Browser scrape
Navigate, wait for ready, read HTML and convert to Markdown, against a recorded (HAR replay) origin on a named corpus.
Browser context claim
Claiming a pre-created context from the scrape pool, with the pool depth stated.
Browser context claim, p99
The same claim at the 99th percentile.
Session browser claim
Creating a browser session from the pool of whole browsers.
Act overhead
Time per action in a batched act call, beyond the browser's own work.
[03/03] Beta limits
Free during the beta, with caps
Caps per organization
- Scrapes per minute
- 60
- Scrapes in flight
- 5
- Pages per crawl
- 500
- Crawls at once
- 1
- Browser sessions at once
- 5
- Browser session lifetime
- 30 min
Metered units
- Pages scraped
- vision.page
- Browser session time
- vision.browser_ms