API Reference
Base URL: https://api.roveapi.com
The machine-readable reference for every route below, with request and response schemas and each problem type, is the OpenAPI document.
All requests require an API key passed as a Bearer token:
Authorization: Bearer rvp_live_your_key_here
Browser Sessions
POST /v1/browser/session
Create a new browser session. Returns a session ID for subsequent actions.
Request:
{
"viewport": { "width": 1280, "height": 720 },
"record_video": false,
"user_agent": "optional custom UA string",
"locale": "en-US",
"timezone": "America/New_York",
"block_resources": ["image", "font"],
"supervised": false,
"stealth": false,
"action_delay_ms": { "min": 200, "max": 800 }
}
All fields are optional. Defaults: 1280×720 viewport, en-US locale, no video, no stealth, and ordinary (non-supervised) control. Set supervised: true to opt in to exclusive human takeover. Supervised sessions require an rvp_live_ key; test-mode keys use deterministic mock actions and cannot produce a live stream.
Response (201):
{
"session_id": "sess_a1b2c3d4e5f6",
"connection_token": "ct_xxxxxxxxxxxx",
"expires_at": "2026-04-13T11:30:00Z",
"environment": "live",
"supervised": false
}
Credit cost: 1 credit
Supervised viewer lifecycle
For a session created with supervised: true:
- If you use the hosted shell, mint its code with the API origin:
{ "origin": "https://api.roveapi.com" }. The 201 response contains a one-timeadmission_code;expires_in_secondssays how long it stays valid (10 minutes by default). - Open
https://api.roveapi.com/v1/browser/viewer-shelland enter the code. The shell exchanges it throughPOST /viewer-admissionsand connects to/v1/browser/stream. A custom viewer must instead use its own exact HTTPS origin for both the grant and browser request. - The viewer calls
POST /viewer-controlwithaction: "take"and the currentexpected_generation. Agent mutation is refused with 409 while the human has exclusive control. - The viewer calls the same endpoint with
action: "return". The agent must obtain a fresh observation before its next mutation; stale operations receive 409. - Stop through the viewer or
POST /viewer-stop, then close the session. A closed session releases its browser context;GET /v1/browser/session/:session_idreportsstatus: "closed".
Admission codes are one-time and origin-bound. Viewer credentials are short-lived. A stale generation, foreign origin, replayed code, or non-owner control request fails closed.
GET /v1/browser/session/:session_id
Get the status of an existing session.
Response (200):
{
"session_id": "sess_a1b2c3d4e5f6",
"status": "active",
"created_at": "2026-04-13T10:00:00Z",
"expires_at": "2026-04-13T11:30:00Z"
}
Credit cost: 0
POST /v1/browser/action
Execute a DSL command against an active session. See Actions DSL for the full command reference.
Request:
{
"session_id": "sess_a1b2c3d4e5f6",
"action": "navigate",
"params": {
"url": "https://example.com",
"wait_until": "networkidle"
}
}
Response (200):
{
"success": true,
"result": { },
"credits_used": 1,
"credits_remaining": 9846,
"duration_ms": 847,
"environment": "live"
}
The result shape varies by action type — see Actions DSL.
POST /v1/browser/screenshot
One-shot screenshot. Creates an ephemeral session internally — no existing session required.
Request:
{
"url": "https://example.com",
"selector": "#main-content",
"full_page": false,
"format": "png",
"viewport": { "width": 1280, "height": 720 }
}
Response (200):
{
"url": "https://s3.amazonaws.com/rove-artifacts/screenshots/scr_xxxx.png?...",
"expires_at": "2026-04-20T10:00:00Z",
"credits_used": 2
}
Credit cost: 2 (includes ephemeral session)
POST /v1/browser/extract
One-shot structured data extraction. No persistent session required.
Request:
{
"url": "https://example.com/product/123",
"schema": {
"title": "string",
"price": "number",
"in_stock": "boolean"
},
"wait_for_selector": ".product-price"
}
Response (200):
{
"data": {
"title": "Acme Widget Pro",
"price": 49.99,
"in_stock": true
},
"credits_used": 3
}
Credit cost: 3 (session + navigation + extraction)
GET /v1/browser/artifacts/:session_id
Retrieve signed URLs for session artifacts (video recordings, screenshots).
Response (200):
{
"session_id": "sess_a1b2c3d4e5f6",
"artifacts": [
{
"type": "video",
"url": "https://s3.amazonaws.com/rove-artifacts/videos/sess_xxxx.webm?...",
"expires_at": "2026-04-20T10:00:00Z",
"duration_seconds": 47
}
]
}
Artifacts expire after 7 days. Credit cost: 0
Account
GET /v1/account/usage
Returns credit balance and usage stats for the authenticated API key.
Response (200):
{
"api_key": "rvp_live_xxxx...xxxx",
"plan": "free_tier",
"credits_total": 10000,
"credits_used": 153,
"credits_remaining": 9847,
"current_period_actions": {
"sessions": 12,
"navigations": 87,
"interactions": 43,
"screenshots": 8,
"extractions": 3
},
"credits_expire": null
}
GET /v1/account/keys
List all API keys for your account.
Response (200):
{
"keys": [
{
"id": "key_xxxx",
"token_prefix": "rvp_live_a3f8...",
"name": "Production",
"plan": "free_tier",
"revoked": false,
"created_at": "2026-03-15T10:00:00Z",
"last_used_at": "2026-04-13T09:45:00Z"
}
]
}
POST /v1/account/keys
Create a new API key.
Request:
{
"name": "CI Pipeline",
"test": false
}
Response (201):
{
"id": "key_xxxx",
"token": "rvp_live_full_token_shown_once",
"name": "CI Pipeline",
"plan": "free_tier",
"test": false,
"created_at": "2026-04-13T10:00:00Z"
}
The full token is shown only once — copy it immediately.
POST /v1/account/keys/revoke
Revoke an API key permanently.
Request:
{ "token": "rvp_live_xxxx" }
POST /v1/account/keys/rotate
Revoke an existing key and create a new one atomically.
Request:
{ "token": "rvp_live_old_key" }
Response: Same as POST /v1/account/keys — returns the new key.
Billing
Credit purchases by an API key, within limits the account owner sets. The full guide, with the retry rules, the out-of-credits answers and test purchases, is Billing API; schemas are in the OpenAPI document.
| Method and path | What it does | Credit cost |
|---|---|---|
GET /v1/billing/catalogue | Credit packs, subscription tiers, operation costs and the supervised rate. Public, no key | 0 |
GET /v1/account/balance | Exact balance, and whether this key may buy credits, within what limits and which packs | 0 |
POST /v1/billing/purchases | Buy a pack: { "item_id": "pack_1k", "payment": "auto" } with a required Idempotency-Key header. 201 with the purchase; a replay of the same key answers 200 | 0 |
GET /v1/billing/purchases | Purchases this key made, newest first (?limit=1..100&cursor=) | 0 |
GET /v1/billing/purchases/{id} | One purchase this key made, with next_action when a person must pay | 0 |
POST /v1/billing/purchases/{id}/cancel | Cancel an unpaid purchase | 0 |
POST /v1/billing/purchases/{id}/simulate | Test keys only: drive a test purchase to paid, expired, failed or authentication_required | 0 |
The owner's settings (agent purchasing, key grants, the saved card, auto top-up) are under /v1/account/billing/... and use the signed-in web session, not an API key; see Owner setup.
Rate Limits
| Plan | Requests/min | Concurrent sessions |
|---|---|---|
| Pay as you go | 10 | 1 |
| Builder | 60 | 5 |
| Scale | 300 | 20 |
Accounts on an earlier plan keep the limits they had. POST /v1/billing/purchases has its own limit: 10 purchases per key and 20 per account per hour.
Rate limit headers are returned on every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1712134800