API reference
Four endpoints, one header. Every request is a POST with a JSON body and returns either the file you asked for or a JSON error.
Authentication
Create a key in the dashboard and send it as a bearer token. It is shown once, at creation, and stored only as a hash — we cannot read it back to you, so if you lose it, revoke it and make another.
Authorization: Bearer bv_live_…Base URL
https://browsevra-gateaway.onrender.comEndpoints
POST /v1/screenshotimage/png or image/jpeg{
"url": "https://example.com",
"fullPage": true,
"type": "png",
"width": 1280,
"height": 900,
"waitUntil": "load",
"timeout": 30000
}POST /v1/pdfapplication/pdf{
"url": "https://example.com",
"format": "A4",
"landscape": false,
"printBackground": true
}POST /v1/contenttext/html — the DOM after JavaScript has run{
"url": "https://example.com",
"waitUntil": "networkidle2"
}POST /v1/scrapeapplication/json{
"url": "https://example.com",
"selectors": ["h1", "p.lead", "a[href^='/pricing']"]
}Common options
waitUntil—load(default),domcontentloaded,networkidle0,networkidle2.timeout— 1,000–120,000 ms. Defaults to 30,000. Your plan's maximum session length still applies and is the lower of the two.
Errors
Every error is JSON with a stable error code, a human message, and a request_id that appears in our logs. Branch on the code, not the message.
| code | status | meaning |
|---|---|---|
invalid_api_key | 401 | Missing, malformed, unknown or revoked key. |
plan_required | 402 | The account has no active Evra subscription. |
usage_limit_reached | 429 | Browser minutes or requests exhausted for the period. |
concurrency_limit_reached | 429 | Already at your plan's simultaneous-browser limit. |
invalid_url | 400 | The url was missing or unparseable. |
blocked_target | 403 | The target resolves to a private or link-local address. |
invalid_request | 400 | A field was the wrong shape. The message names it. |
navigation_timeout | 504 | The page did not finish loading in time. |
page_error | 502 | The browser could not load that page. |
service_unavailable | 503 | Browsers are busy or restarting. Retry. |
Metering
You are billed for browser time actually spent, in wall-clock milliseconds, returned on every successful response as x-browsevra-browser-ms. Failed requests count against your monthly request quota and against browser minutes for however long the browser really ran — a navigation that times out held a browser for that whole timeout, so it is not free.
Not available yet
There is no CDP / WebSocket endpoint, so Puppeteer and Playwright cannot connect directly yet. Attempting a protocol upgrade returns 501 rather than appearing to work. It is not shipped because on a raw browser session the target checks above cannot apply, and the honest fix is network-level egress filtering rather than a partial guard.