loading

Getting Started

  • Overview
  • Quick Start
  • Instant Preview
  • Try on Other Sites
  • Workspace

Integration

  • Configuration
  • Security & Policies
  • AI Discovery
  • Agent-to-Web (A2W)

Reference

  • API Reference
  • Instant Preview API
  • Examples
  • Roadmap

Platforms

  • Webflow
  • Wix

[ documentation ]

API Reference

Complete Rover docs for workspace key management, Rover Analytics Firestore data paths plus private settings callables, A2W run resources, and browser runtime contracts.

A2W run base: https://agent.rtrvr.ai/v2/a2w/runs · Runtime base: https://agent.rtrvr.ai/v2/rover/*

Auth Modes

  • Firebase ID token for Workspace management APIs (/generateRoverSiteKey, /listRoverSiteKeys, and related config endpoints).
  • sessionToken (rvrsess_*) for browser runtime calls to /v2/rover/* after session bootstrap.
  • publicKey (pk_site_*) only for bootstrap exchange on /v2/rover/session/open. Do not send sk_site_* to browser runtime.
  • run access token for the public A2W run URL returned by /v2/a2w/runs.
  • Web Bot Auth (RFC 9421) HTTP Message Signatures for public A2W calls: sign with Signature + Signature-Input and point Signature-Agent at your key directory. Anonymous requests are accepted; a verified signature earns a higher trust tier that raises rate limits and unlocks sensitive capabilities.
  • Rover delegation token (rds_*) — a key-bound, scoped, spend-capped human authorization carried as auth: { mode: "delegated_session", token } on A2W run create/continue. Minted by the verify loop (input.links.verify); never a raw site credential.
  • Firebase auth + Firestore rules for owner-only Rover Analytics reads in Workspace, plus Firebase-authenticated callables for private settings such as notification subscriptions.

Agent-to-Web Protocol (A2W) API (`/v2/a2w/runs`)

Neutral AI / CLI protocol for Rover-enabled sites. POST is the structured API-agent path. GET /v2/a2w/runs is the compact URL-fetch chatbot path and can extract one canonical browser selector from the target URL. The source-visible marker <script type="application/agent+json"> stays compact and points agents to the live well-known files and OpenAPI.

POST/v2/a2w/runs

Create a strict v2 A2W run for any Rover-enabled site using a target URL and exactly one launch selector.

Auth: Anonymous public access token minted in response. Initial create call requires no site public key.

Required Request Fields

FieldTypeDescription
urlstringTarget page URL on a Rover-enabled site.

Optional Request Fields

FieldTypeDescription
promptstringCanonical natural-language instruction for the run.
shortcutIdstringExact saved shortcut/capability ID. Use for repeatable flows.
playbookIdstringExact experience playbook ID. Use when the owner has published a guided outcome path.
engagementKind'demo' | 'onboarding' | 'support' | 'task'Optional explicit kind. It must agree with a selected shortcut or playbook.
capabilityIdstringExplicit page/site capability identifier when the caller already knows the target skill.
argsRecord<string, unknown>Structured run arguments for the selected capability.
identity{ userPresent?, sessionId?, agentKey?, memoryKey? }Typed caller and session attribution.
execution{ preference?: 'cloud' | 'browser' | 'auto'; mode?: 'cloud' | 'browser'; allowedModes?: ('cloud' | 'browser')[]; userPresent?: boolean }Structured execution preference for POST callers.
accept{ modes?, primary? }Requested text, markdown, json, observation, or artifacts result modes.
policy{ confirmation?, crossHost?, maxHops? }Execution policy that the site may narrow.
agent{ key?, displayName?, vendor?, model?, version?, homepage?, memoryKey?, clientId? }Typed visiting-agent attribution.
subject / auth / payment / commercetyped objectsSensitive or structured scoping accepted only on POST, never in browser or GET links.
confirmationPolicy / artifactstyped fieldsCharge-confirmation policy and requested artifact names.
Success Example
{
  "id": "a2w_run_123",
  "protocol": "a2w",
  "runId": "a2w_run_123",
  "run": "https://agent.rtrvr.ai/v2/a2w/runs/a2w_run_123?access=a2w_access_...",
  "workflow": "https://agent.rtrvr.ai/v2/a2w/workflows/a2w_wf_456?access=a2w_access_...",
  "status": "running",
  "retryAfterMs": 2000,
  "links": {
    "poll": { "href": "https://agent.rtrvr.ai/v2/a2w/runs/a2w_run_123?access=a2w_access_...", "method": "GET", "headers": { "Accept": "application/json", "Prefer": "wait=10" } },
    "stream": { "href": "https://agent.rtrvr.ai/v2/a2w/runs/a2w_run_123?access=a2w_access_...", "method": "GET", "headers": { "Accept": "text/event-stream" } },
    "ndjson": { "href": "https://agent.rtrvr.ai/v2/a2w/runs/a2w_run_123?access=a2w_access_...", "method": "GET", "headers": { "Accept": "application/x-ndjson" } }
  },
  "open": "https://www.rtrvr.ai/#rover_receipt=a2w_receipt_...",
  "browserLink": "https://www.rtrvr.ai/?rover=get+me+the+latest+blog+post#rover_receipt=a2w_receipt_..."
}

Notes

  • Headers drive advanced behavior: `Accept`, `Prefer: wait=15`, `Prefer: execution=cloud|browser|auto`, and `Idempotency-Key`.
  • Exactly one of `prompt`, `shortcutId`, or `playbookId` is required. Unknown properties and conflicting kinds fail with typed contract errors.
  • If no explicit `agent` object is provided, Rover can still attribute the caller heuristically from `User-Agent`, `Signature-Agent`, `Signature`, `Signature-Input`, and `X-RTRVR-Client-Id`.
  • Default execution mode is `cloud` for URL-fetch agents. `open` is the clean receipt-based browser handoff, while `browserLink` is an optional readable alias when the visible deep link stays within a conservative URL budget.
  • Use `Prefer: execution=cloud, wait=10` for cloud-hosted execution with a short initial wait, then follow `links.stream`, `links.ndjson`, or `links.poll` until terminal or input_required.
GET/v2/a2w/runs?url=<target>&prompt=<task>

Create a hosted-cloud A2W run for URL-fetch chatbots that cannot POST.

Auth: Anonymous public access token minted in response. Target site must have AI access and cloud browser execution enabled.

Required Request Fields

FieldTypeDescription
urlstringAbsolute HTTPS target page URL on a Rover-enabled site.

Optional Request Fields

FieldTypeDescription
promptstringNatural-language task. Use exactly one selector.
shortcutIdstringExact saved shortcut ID. Use exactly one selector.
playbookIdstringExact saved playbook ID. Use exactly one selector.
engagementKind'demo' | 'onboarding' | 'support' | 'task'Optional explicit kind; stored kinds remain authoritative.
execution'cloud' | 'browser'Defaults to cloud.
waitnumberInitial long-poll wait in seconds. Defaults to 25 and caps server-side.
format'markdown' | 'json'Defaults to markdown unless JSON is requested.
Success Example
# Rover A2W run

Status: running
Run: https://agent.rtrvr.ai/v2/a2w/runs/a2w_run_123?access=a2w_access_...

## Still running

Rover is running this task in a hosted cloud browser. Fetch the poll URL until terminal or input_required.

## Links

- Poll: https://agent.rtrvr.ai/v2/a2w/runs/a2w_run_123?access=a2w_access_...&format=markdown&wait=10

Notes

  • This is the no-browser path for ChatGPT, Claude, Gemini, and similar URL-fetch agents.
  • Long-running markdown responses include a self-contained poll URL with `format=markdown&wait=10`.
  • GET executor responses send `X-Robots-Tag: noindex, nofollow, noarchive`.
GET/v2/a2w/runs/{id}

Read the canonical public A2W run resource as JSON, markdown, SSE, or NDJSON.

Auth: Run access token via `?access=` or `Authorization: Bearer ...`.

Notes

  • `Accept: application/json` returns latest state or final result.
  • `format=markdown` returns chatbot-readable markdown.
  • `Accept: text/event-stream` streams uniform run events.
  • `Accept: application/x-ndjson` streams the same events in CLI-friendly NDJSON.
POST/v2/a2w/runs/{id}

Continue a run that is waiting on user input.

Auth: Run access token.

Required Request Fields

FieldTypeDescription
inputstringOrdinary continuation answer. Required unless `answers` is sent.

Optional Request Fields

FieldTypeDescription
answersRecord<string, string>Per-question answers keyed by `input.questions[].key` — use this when the park asked multiple questions. A bare `input` string binds the same text to every key; unknown keys are ignored.

Notes

  • Only for ordinary `input_required` questions. Reasons carrying `input.links.confirm` or `input.links.verify` (payment_confirmation_required, auth_required, action_confirmation_required, ...) complete out-of-band — relay the link to the human and poll; do not POST input to those runs.
  • Sign-in walls (`input.reason=sign_in_link_required`) resume via POST /v2/a2w/runs/{id}/auth-input instead.
POST/v2/a2w/runs/{id}/auth-input

Provide the sign-in magic link or one-time code a human received, so a run parked with input.reason=sign_in_link_required can resume.

Auth: Run access token.

Required Request Fields

FieldTypeDescription
valuestringThe sign-in link or one-time code.

Optional Request Fields

FieldTypeDescription
kind'magic_link' | 'otp' | 'unknown'Required type of the one-shot value.

Notes

  • The value is a secret: stored encrypted, consumed one-shot to resume the run, and never returned in any payload, event, or model context.
  • `run.authInput` describes what is expected (`status`, `kind`, `prompt`, `emailMasked`) and never carries the provided value.
  • Returns the updated run resource; resume is driven asynchronously — keep polling `links.self`.
DELETE/v2/a2w/runs/{id}

Cancel an in-flight A2W run.

Auth: Run access token.

GET/v2/a2w/runs/{id}/artifacts

Mint short-lived signed download URLs for the files a run generated (screenshots, PDFs, sheets).

Auth: Run access token.

Notes

  • The run result lists generated files as opaque storage refs; this endpoint turns them into fetchable URLs on read.
  • Signed URLs expire after ~15 minutes — re-GET to refresh. Runs that produced files advertise this endpoint as `links.artifacts`.
  • Response shape: `{ runId, expiresAt, artifacts: [{ name, contentType, sizeBytes, url, expiresAt }] }`.
GET/v2/a2w/capabilities?url=<site>

List a Rover-enabled site's published capabilities as MCP-shaped tools.

Auth: Anonymous. RFC 9421 Web Bot Auth signing raises the trust tier.

Required Request Fields

FieldTypeDescription
urlstringTarget site URL. Required unless `host` or `siteId` is passed.

Optional Request Fields

FieldTypeDescription
hoststringSite host, as an alternative to `url`.
siteIdstringExplicit Rover site identifier.

Notes

  • Returns `{ protocol: 'mcp', serverInfo, executor: { contract: 'a2w', runEndpoint }, mcp: { transport: 'streamable-http', url }, tools }`.
  • Every tool executes Rover-mediated through the canonical A2W run contract; MCP-native agents can instead connect to the returned live MCP server URL.
POST/v2/a2w/runs/{id}/handoffs

Create a delegated child run on another Rover-enabled site and keep the same workflow lineage.

Auth: Parent run access token.

Required Request Fields

FieldTypeDescription
urlstringTarget Rover-enabled site URL.

Optional Request Fields

FieldTypeDescription
promptstringDelegation request. Use exactly one selector.
shortcutIdstringExact shortcut to run on the receiving site.
playbookIdstringExact playbook to run on the receiving site.
engagementKind'demo' | 'onboarding' | 'support' | 'task'Optional explicit kind; it must agree with stored configuration.
capabilityIdstringExplicit child-run capability identifier.
argsRecord<string, unknown>Structured arguments for the delegated capability.
identity{ userPresent?, sessionId?, agentKey?, memoryKey? }Typed child-run identity hints.
execution{ preference?, mode?, allowedModes?, userPresent? }Cloud/browser execution policy for the child run.
accept{ modes?: ('text' | 'markdown' | 'json' | 'observation' | 'artifacts')[] }Requested child-run result modes.
policy{ confirmation?: 'auto' | 'required' | 'site_policy'; crossHost?: 'allow' | 'same_host' | 'site_policy' }Execution-policy hints for the child run.
agent{ key?, displayName?, vendor?, model?, version?, homepage?, memoryKey?, clientId? }Optional child-run agent identity override. If omitted, parent attribution is inherited.
contextSummarystringStructured summary to carry into the child run.
expectedOutputstringDescribe what the child should return to the parent workflow.
lastObservationRecord<string, unknown>Latest structured parent observation when needed for delegation.

Notes

  • Delegated child runs are still ordinary A2W run resources; they simply inherit the parent's workflow lineage.
  • Receiving sites must enable `siteConfig.aiAccess.allowDelegatedHandoffs` in Workspace.
GET/v2/a2w/workflows/{id}

Read the aggregated cross-site workflow resource as JSON, SSE, or NDJSON.

Auth: Workflow access token via `?access=` or `Authorization: Bearer ...`.

Notes

  • `Accept: application/json` returns the latest workflow snapshot and final result when available.
  • `Accept: text/event-stream` or `Accept: application/x-ndjson` streams workflow-level lineage across parent and child runs.

Workspace Management APIs

Used by Rover Workspace for key lifecycle and site config management. These remain Firebase-authenticated control-plane endpoints.

Cloud site config persists shortcuts, business type, sparse Rover V3 experience overrides, greeting, voice dictation, AI access policy, agent discovery policy, per-site page-capture overrides, and site-owned mascot appearance controls. Runtime-owned defaults still control the seed CTA, bottom-center anchor, transparent live-action mode, and default live-card count unless you explicitly override those fields. Explicit boot-only overrides such as deepLink.* still stay outside these workspace endpoints.

POST/generateRoverSiteKey

Create a new Rover site key and persisted policy/profile.

Auth: Firebase ID token (Bearer)

Required Request Fields

FieldTypeDescription
siteId | siteNamestringExisting siteId or a siteName for server-generated siteId.
labelstringHuman-readable key label.
allowedDomainsstring[]Allowed host/domain patterns (`example.com`, `*.example.com`, `=app.example.com`, or URL-shaped entries normalized to host). In `registrable_domain`, plain `example.com` covers the apex host and subdomains.

Optional Request Fields

FieldTypeDescription
ttlDaysnumberExpiration days, use 0 for no expiry.
environment'production' | 'development' | 'test'Deployment environment label.
capabilities{ roverEmbed?, externalWebContextScrape?, cloudAgent?, cloudScrape? }Capability profile for this key.
roverPolicyRoverSitePolicyPolicy persisted and returned in list/replace APIs, including `siteMode`, `domainScopeMode`, `cloudSandboxEnabled`, mascot settings, and shortcut limits.
POST/listRoverSiteKeys

List all Rover site keys for the authenticated workspace user.

Auth: Firebase ID token (Bearer)

POST/updateRoverSiteKeyPolicy

Patch a key's allowed domains, active status, capabilities, and Rover policy.

Auth: Firebase ID token (Bearer)

Required Request Fields

FieldTypeDescription
keyIdstringTarget key identifier.

Optional Request Fields

FieldTypeDescription
siteIdstringOptional site assertion/update.
allowedDomainsstring[]Replacement domain pattern set (`example.com`, `*.example.com`, `=app.example.com`, or URL-shaped entries). In `registrable_domain`, plain `example.com` covers the apex host and subdomains.
activebooleanEnable/disable key.
capabilitiesApiKeyCapabilitiesCapability patch.
roverPolicyPartial<RoverSitePolicy>Policy patch, including `siteMode`, `domainScopeMode`, `cloudSandboxEnabled`, mascot settings, and shortcut limits.
POST/rotateRoverSiteKey

Rotate a key (invalidate old key and issue a new pk_site_* value).

Auth: Firebase ID token (Bearer)

Required Request Fields

FieldTypeDescription
keyIdstringKey being rotated.

Optional Request Fields

FieldTypeDescription
siteIdstringOptional site assertion/update.
labelstringOptional new label.
capabilitiesApiKeyCapabilitiesCapability patch applied to rotated key.
roverPolicyPartial<RoverSitePolicy>Policy patch applied to the replacement key, including `siteMode`, `domainScopeMode`, `cloudSandboxEnabled`, mascot settings, and shortcut limits.
POST/deleteRoverSite

Delete a Rover site, all owned site keys, and Rover-owned config while retaining historical Rover Analytics.

Auth: Firebase ID token (Bearer)

Required Request Fields

FieldTypeDescription
siteIdstringRover site identifier to delete.

Notes

  • Deletes all owned Rover site keys for the site, plus Rover-owned site config and Rover Analytics owner settings/questions.
  • Historical Rover Analytics, visits, reviews, interviews, notes, posts, and aggregates are retained.
  • Webflow-managed sites are detached from the live managed Webflow install before Rover-owned resources are removed.
POST/getRoverSiteConfig

Read cloud shortcuts, business type, sparse experience overrides, greeting, voice, AI access, discovery, and page-capture config for a key/site.

Auth: Firebase ID token (Bearer)

Required Request Fields

FieldTypeDescription
keyIdstringSite key ID.

Optional Request Fields

FieldTypeDescription
siteIdstringOptional site assertion.
POST/upsertRoverSiteConfig

Write cloud shortcuts, business type, sparse experience overrides, greeting, voice, AI access, discovery, and page-capture config.

Auth: Firebase ID token (Bearer)

Required Request Fields

FieldTypeDescription
keyIdstringSite key ID.

Optional Request Fields

FieldTypeDescription
siteIdstringOptional site assertion.
siteConfig.shortcutsRoverSiteShortcut[]Persisted shortcuts/journeys.
siteConfig.businessTypeRoverBusinessTypeTunes runtime placeholder hints and generated quick actions when the site has few explicit shortcuts.
siteConfig.experienceRoverSiteExperience | nullSparse Rover V3 surface overrides only. Runtime defaults still own the seed, centered stage, and focus stream when a field is omitted. Use null to clear overrides.
siteConfig.greeting{ text?, delay?, duration?, disabled? } | nullGreeting config.
siteConfig.voice{ enabled?: boolean; language?: string; autoStopMs?: number } | nullBrowser dictation config. autoStopMs is the post-speech silence window in milliseconds. Use null to clear persisted voice settings.
siteConfig.aiAccessRoverSiteAiAccess | nullPublic launch/runtime guardrails for A2W run entry, browser deep links, cloud browser use, and delegated handoffs.
siteConfig.analytics{ enabled?: boolean; consent?: { provider: 'wix'; category: 'analytics' } } | nullPer-site Activity analytics switch and optional host consent gate. Wix installs use this to keep Activity default-on for owners while requiring Wix analytics consent from visitors.
siteConfig.agentDiscoveryRoverSiteAgentDiscovery | nullPersisted public discovery policy, well-known artifact paths, host-surface binding, and seed/presence-led display settings. Use null to clear.
siteConfig.pageConfigRoverPageCaptureConfig | nullSparse per-site page-capture overrides. New generated installs default disableAutoScroll to true; use null to clear overrides.
POST/updateApiKeyCapabilities

Patch capability flags for user or site keys.

Auth: Firebase ID token (Bearer)

Required Request Fields

FieldTypeDescription
keyIdstringTarget key identifier.
capabilitiesApiKeyCapabilitiesBoolean capability patch fields.

Rover Analytics Workspace Data Paths

Rover Analytics pages now read aggregate-first Firestore summaries directly under owner-auth rules, including first-party identity/account filters backed by hashed join keys. Backend callables remain for private settings and Storage-backed trajectory hydration. These are distinct from public site-tag ingest routes and are not public `siteId` browser APIs.

READFirestore: roverbook_* collections

Owner-facing Rover Analytics now read Firestore directly under ownership rules instead of calling a backend read facade.

Auth: Firebase auth + Firestore rules (`ownerUid` scoped).

Notes

  • Workspace reads `roverbook_sites`, `roverbook_interactions`, daily aggregate docs, identity/account profile summaries, `roverbook_visits`, `roverbook_scores`, `roverbook_reviews`, `roverbook_interviews`, `roverbook_questions`, `roverbook_notes`, and `roverbook_posts` directly.
  • Raw event docs and anonymous-to-known identity links remain backend-only. User/account IDs are stored as hashed join keys unless a site explicitly opts into display PII.
  • Signed public analytics GET routes still exist for runtime/agent surfaces used by the internal `@rover/roverbook` package.
POSTgetRoverBookInteractionDetail

Hydrate one Rover Analytics interaction detail, including Storage-backed trajectory data, after owner access is verified.

Auth: Firebase ID token (owner only).

Required Request Fields

FieldTypeDescription
siteIdstringOwned Rover site identifier.
interactionIdstringRover Analytics interaction identifier.

Notes

  • Workspace uses this for on-demand detail drawers so browser clients never read `roverbook-interactions/...` Storage blobs directly.
POSTgetRoverBookNotificationSettings

Read the private Rover Analytics setup payload for a site, including interview questions and masked webhook subscriptions.

Auth: Firebase ID token (owner only).

Required Request Fields

FieldTypeDescription
siteIdstringOwned Rover site identifier.
POSTupsertRoverBookNotificationSettings

Write Rover Analytics interview questions and webhook subscriptions for a site.

Auth: Firebase ID token (owner only).

Required Request Fields

FieldTypeDescription
siteIdstringOwned Rover site identifier.

Optional Request Fields

FieldTypeDescription
enabledbooleanEnable or disable Rover Analytics outbound notifications for the site.
webhooksRoverAnalyticsWebhookSubscription[]Private per-site webhook subscription list.
interviewQuestionsstring[]Per-site Rover Analytics interview prompts.

Notes

  • Webhook secrets are masked on read and preserved unless explicitly replaced.
  • These settings are stored privately by owner + site and are not exposed through public embed config.
POSTupsertRoverBookQuestions

Write just the Rover Analytics interview questions for a site.

Auth: Firebase ID token (owner only).

Required Request Fields

FieldTypeDescription
siteIdstringOwned Rover site identifier.
interviewQuestionsstring[]Per-site Rover Analytics interview prompts.

Rover Runtime APIs (`/v2/rover/*`)

Server-authoritative runtime contract for embedded Rover. All run-state changes are keyed bysessionId + runId + epoch + seq.

POST/v2/rover/session/open

Bootstrap or refresh a browser runtime session and return the initial projection.

Auth: Body token. Preferred: bootstrapToken/publicKey (pk_site_*). Optional: sessionToken refresh path.

Required Request Fields

FieldTypeDescription
siteIdstringWorkspace site identifier.
host | urlstringCurrent host/url for domain and policy checks.
bootstrapToken | publicKeystringPublic Rover key (pk_site_*). Required when no valid sessionToken is supplied.

Optional Request Fields

FieldTypeDescription
sessionIdstringOptional local correlation hint. Public-key bootstrap always returns a new backend-minted random session ID.
sessionTokenstringCurrent rvrsess_* token. If invalid/expired and bootstrap token exists, server falls back to bootstrap flow.
visitor.contextRoverExperienceContextV1Safe data-only profile, account, intent, success, support, recent-activity, and primitive-fact hints. Sanitized and capped at 2 KB; recent activity is historical background and limited to three requests.
visitor.contextTokenstringOpaque site-server-minted token, max 2,048 chars. Exchanged once when context_token_v1 is enabled; never persisted raw.
Success Example
{
  "success": true,
  "data": {
    "sessionId": "8ef5202c-6e2b-4f1b-9fc7-925564f65e77",
    "sessionToken": "rvrsess_...",
    "sessionTokenExpiresAt": 1771484403000,
    "streamToken": "rvrstream_...",
    "epoch": 5,
	    "capabilities": { "roverEmbed": true },
	    "policy": {
	      "domainScopeMode": "registrable_domain",
	      "cloudSandboxEnabled": true,
	      "externalAllowDomains": [],
      "externalDenyDomains": []
    },
	    "projection": { "sessionId": "8ef5202c-6e2b-4f1b-9fc7-925564f65e77", "epoch": 5, "events": [], "tabs": [] },
	    "siteConfig": {
	      "shortcuts": [],
	      "businessType": "saas",
	      "experience": {
	        "presence": { "ctaText": "Do it with Rover" },
	        "inputs": { "voice": false }
	      },
	      "greeting": { "text": "Welcome" },
	      "voice": { "enabled": true, "language": "en-US", "autoStopMs": 2600 },
	      "aiAccess": { "enabled": true },
	      "agentDiscovery": {
        "enabled": true,
        "preferExecution": "cloud",
        "roverSiteUrl": "/.well-known/rover-site.json",
        "agentCardUrl": "/.well-known/agent-card.json",
        "discoverySurface": {
          "mode": "beacon",
          "branding": "site",
          "hostSurface": "auto",
          "actionReveal": "click",
          "beaconLabel": "Use AI"
        }
      },
      "pageConfig": { "disableAutoScroll": true, "adaptiveSettleMaxWaitMs": 480 }
    },
    "sseUrl": "https://agent.rtrvr.ai/v2/rover/stream?..."
  }
}

Typed Conflict/Auth Errors

Example 1
{
  "success": false,
  "error": "SESSION_TOKEN_EXPIRED",
  "data": {
    "code": "SESSION_TOKEN_EXPIRED",
    "message": "Token expired",
    "retryable": true,
    "next_action": "Pass bootstrapToken/publicKey (pk_site_*) to /v2/rover/session/open to re-bootstrap the session."
  }
}
Example 2
{
  "success": false,
  "error": "BOOTSTRAP_REQUIRED",
  "data": {
    "code": "BOOTSTRAP_REQUIRED",
    "message": "bootstrapToken/publicKey (pk_site_*) is required.",
    "retryable": false,
    "next_action": "Provide a valid pk_site_* key in bootstrapToken/publicKey."
  }
}

Notes

  • Server mints short-lived sessionToken (~10 min).
  • Browser runtime should not send long-lived bearer keys.
  • Standard owner-facing Workspace installs rely on Rover's built-in tab behavior instead of owner-selected tab overrides.
POST/v2/rover/session/open

Refresh an existing rvrsess_* token and SSE URL.

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdstringSession to refresh (defaults to token sid).

Notes

  • Use when token is near expiry or after SSE auth failures.
POST/v2/rover/session/context

Refresh sanitized experience context after login, account, plan, or journey changes.

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdstringActive Rover session.

Optional Request Fields

FieldTypeDescription
visitor.contextRoverExperienceContextV1Safe immediate hints only. Send visitor: null to clear local and server personalization on logout.
visitor.contextTokenstringNew opaque site-server-minted token.

Notes

  • The resolver fails open. Raw tokens and raw resolver payloads never enter prompts, logs, checkpoints, receipts, or URLs.
POST/v2/rover/command

Submit user input and create/continue an authoritative run.

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdstringTarget session.
messagestringUser message.
expectedEpochnumberRequired in strict mode for stale-epoch protection.
clientEventIdstringIdempotency key for retries and dedup.

Optional Request Fields

FieldTypeDescription
continueRunbooleanContinue active run. Reserved for ask_user answer continuation in the same task boundary.
forceNewRunbooleanCancel active run and create a fresh run. Normal user sends should set this true.
expectedSeqnumberRequired in strict mode when active run exists.
requestedMode'act' | 'planner' | 'auto'Routing preference. `act`/`planner` force backend mode; `auto` uses heuristic routing.
taskBoundaryIdstringOptional client task boundary identifier.
Success Example
{
  "success": true,
  "data": {
    "runId": "run-uuid",
    "acceptedMode": "act",
    "state": "running",
    "continuePrompt": false,
    "requestedMode": "act",
    "epoch": 5,
    "seq": 1
  }
}

Typed Conflict/Auth Errors

Example 1
{
  "success": false,
  "error": "stale_epoch",
  "data": {
    "sessionId": "8ef5202c-6e2b-4f1b-9fc7-925564f65e77",
    "runId": "run-uuid",
    "expectedEpoch": 2,
    "currentEpoch": 5,
    "decisionReason": "stale_epoch_retryable",
    "conflict": { "type": "stale_epoch", "currentEpoch": 5, "retryable": true }
  }
}
Example 2
{
  "success": false,
  "error": "active_run_exists",
  "data": {
    "continuePrompt": true,
    "runId": "run-uuid",
    "state": "running",
    "acceptedMode": "act",
    "decisionReason": "active_run_exists",
    "conflict": { "type": "active_run_exists", "retryable": false }
  }
}

Notes

  • One active run per session is enforced server-side.
  • No local silent fallback should run when this call is not accepted.
POST/v2/rover/command

Control run lifecycle (`cancel`, `end_task`, `new_task`, `continue`).

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdstringTarget session.
action'cancel' | 'end_task' | 'new_task' | 'continue'Requested run control action.
expectedEpochnumberRequired in strict mode.
clientEventIdstringIdempotency key.

Optional Request Fields

FieldTypeDescription
runIdstringRequired for `cancel` and `end_task` when active run is not implied.
expectedSeqnumberStrict stale-seq guard for run-scoped actions.
reasonstringAudit reason for control action.
Success Example
{
  "success": true,
  "data": {
    "action": "cancel",
    "runId": "run-uuid",
    "currentSeq": 18,
    "projection": { "sessionId": "8ef5202c-6e2b-4f1b-9fc7-925564f65e77", "epoch": 6, "activeRunId": "", "events": [], "tabs": [] }
  }
}

Notes

  • Use clientEventId for idempotent retries.
  • Strict mode requires expectedEpoch and enforces stale rejection before state transitions.
POST/v2/rover/command

Submit navigation/tab intent and receive authoritative policy decision.

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdstringTarget session.
targetUrl | urlstringNavigation destination.
expectedEpochnumberRequired in strict mode.
clientEventIdstringIdempotency key used for silent retry recovery.

Optional Request Fields

FieldTypeDescription
runIdstringIntended active run (defaults to session active run).
expectedSeqnumberStrict stale-seq guard for run-scoped events.
currentUrlstringCurrent browser URL.
currentHost/targetHost/isCrossHost/navigationClasshintsClient hints. Server computes authoritative class regardless.
logicalTabIdstringLogical tab identifier for run tab graph.
messagestringPrompt context used for adversarial scoring.
adversarialScorenumberOptional explicit score (merged with server score).
Success Example
{
  "success": true,
  "data": {
    "decision": "allow_same_tab",
    "decisionReason": "allow_same_tab",
    "decisionHint": "allow_same_tab",
    "notice": "In-scope navigation allowed.",
    "staleRun": false,
    "sessionId": "8ef5202c-6e2b-4f1b-9fc7-925564f65e77",
    "sessionEpoch": 5,
    "runId": "run-uuid",
    "currentSeq": 3,
    "clientEventId": "evt-uuid",
    "currentHost": "www.rtrvr.ai",
    "targetHost": "rtrvr.ai",
    "isCrossHost": true,
    "crossDomain": false,
    "navigationClass": "cross_host_in_scope",
    "adversarial": { "score": 0, "reasons": [] }
  }
}

Typed Conflict/Auth Errors

Example 1
{
  "success": false,
  "error": "stale_seq",
  "data": {
    "sessionId": "8ef5202c-6e2b-4f1b-9fc7-925564f65e77",
    "runId": "run-uuid",
    "expectedSeq": 2,
    "currentSeq": 3,
    "currentEpoch": 5,
    "decisionReason": "stale_seq_retryable",
    "clientEventId": "evt-uuid",
    "conflict": { "type": "stale_seq", "currentSeq": 3, "currentEpoch": 5, "retryable": true }
  }
}
Example 2
{
  "success": true,
  "data": {
    "decision": "stale_run",
    "decisionReason": "stale_run",
    "staleRun": true,
    "staleRunReason": "run_terminal",
    "currentRunId": "new-active-run-id",
    "currentActiveRunId": "new-active-run-id",
    "sessionEpoch": 6,
    "decisionHint": "sync_projection_and_ignore"
  }
}

Notes

  • Server keeps strict stale checks and returns typed 409 envelopes.
  • SDK should do one silent retry on stale conflicts with same clientEventId.
  • Stale/missing run is non-fatal via `decision=stale_run` (200).
GET/v2/rover/stream

SSE stream for projection updates and keepalive pings.

Auth: Short-lived, stream-only rvrstream_* ticket in the query. The session token is never placed in the URL.

Required Request Fields

FieldTypeDescription
streamTicketquery stringOpaque audience-limited stream ticket.

Optional Request Fields

FieldTypeDescription
seqAfternumberStart events after this sequence.

Notes

  • SSE events: `ready`, `projection`, `ping`, `error`.
  • Use POST /v2/rover/state as polling fallback.
POST/v2/rover/state

Fetch latest projection (session/run/tabs/events/snapshot metadata).

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdbodyBackend-minted session identifier.
sessionTokenbodySigned session credential. Never place it in a URL.

Optional Request Fields

FieldTypeDescription
seqAfternumberReturn events after this sequence only.
POST/v2/rover/snapshot

Upsert byte-compacted checkpoint/snapshot for resume. Firestore stores metadata and small inline checkpoints; oversized payloads are offloaded to backend storage.

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdstringTarget session.
checkpoint | payloadobjectCompacted snapshot payload.

Optional Request Fields

FieldTypeDescription
visitorIdstringOptional non-authoritative analytics correlation only; signed session claims own the checkpoint.
updatedAtnumberClient timestamp in ms.
versionnumberSnapshot schema version.
seqnumberLast stable seq captured in snapshot.
compactedPrevStepsunknown[]Compacted execution history.
chatSummarystringConversation summary text.
ttlHoursnumberTTL for snapshot document.
POST/v2/rover/context/external

Fetch/act on external context through policy-scoped cloud integrations.

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdstringTarget session.
runIdstringActive run ID.
urlstringExternal target URL.
intent'open_only' | 'read_context' | 'act'External action intent.
expectedEpochnumberStrict stale-epoch guard.
expectedSeqnumberStrict stale-seq guard.

Optional Request Fields

FieldTypeDescription
logicalTabIdstringLogical external tab id.
message | userInputstringUsed for adversarial gating and context.
timeoutMsnumberExternal fetch timeout.

Notes

  • Policy/capability checks are enforced server-side for each call.
  • High adversarial score can block external context/action even when policy allows it.
POST/v2/rover/telemetry/ingest

Ingest runtime telemetry batches (diagnostics/observability).

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdstringTarget session.
eventsunknown[]Telemetry event batch (server truncates to safe limits).

Optional Request Fields

FieldTypeDescription
runIdstringActive run association.
flushReasonstringFlush reason (`interval`, `manual`, etc.).
pageUrlstringCurrent page url.
sampleRatenumberClient telemetry sample rate.
sdkVersionstringSDK version marker.

Notes

  • This endpoint is automatic; users do not need manual setup for normal onboarding.
  • Telemetry ingestion does not replace run/state APIs.

Canonical Runtime Envelopes

RoverSuccessResponse<T>
type RoverSuccessResponse<T> = {
  success: true
  data: T
}
RoverErrorResponse
type RoverErrorResponse = {
  success: false
  error: string
  data?: {
    code?: string
    message?: string
    retryable?: boolean
    next_action?: string
    decisionReason?: string
    conflict?: {
      type: 'stale_seq' | 'stale_epoch' | 'active_run_exists'
      currentSeq?: number
      currentEpoch?: number
      retryable: boolean
    }
  }
}
TabEventDecisionResponse
type TabEventDecisionResponse = RoverSuccessResponse<{
  decision: 'allow_same_tab' | 'open_new_tab' | 'block' | 'stale_run'
  decisionReason: 'allow_same_tab' | 'open_new_tab' | 'policy_blocked' | 'stale_run'
  decisionHint: string
  notice?: string
  staleRun: boolean
  staleRunReason?: string
  currentRunId?: string
  currentActiveRunId?: string
  sessionId: string
  sessionEpoch: number
  runId?: string
  currentSeq?: number
  clientEventId?: string
  currentHost?: string
  targetHost?: string
  isCrossHost?: boolean
  crossDomain?: boolean
  navigationClass?: 'same_host_in_scope' | 'cross_host_in_scope' | 'cross_registrable_external'
  adversarial?: { score: number; reasons: string[] }
}>
RunInputResponse
type RunInputResponse = RoverSuccessResponse<{
  runId?: string
  acceptedMode?: 'act' | 'planner'
  state?: 'queued' | 'running' | 'awaiting_user' | 'cancel_requested' | 'cancelled' | 'completed' | 'failed'
  continuePrompt?: boolean
  requestedMode?: 'act' | 'planner' | 'auto'
  epoch?: number
  seq?: number
  routing?: { score: number; reason: string }
}>
RunControlResponse
type RunControlResponse = RoverSuccessResponse<{
  action: 'cancel' | 'end_task' | 'new_task' | 'continue'
  runId?: string
  currentSeq?: number
  projection: SessionProjectionResponse
}>
RunTransitionPayload
type RunTransitionPayload = {
  runId: string
  status: 'queued' | 'running' | 'awaiting_user' | 'cancel_requested' | 'cancelled' | 'completed' | 'failed'
  continuationReason?: 'loop_continue' | 'same_tab_navigation_handoff' | 'awaiting_user'
}
SessionProjectionResponse
type SessionProjectionResponse = {
  sessionId: string
  epoch: number
  activeRunId?: string
  runStatus?: 'queued' | 'running' | 'awaiting_user' | 'cancel_requested' | 'cancelled' | 'completed' | 'failed'
  runMode?: 'act' | 'planner'
  events: Array<{ seq: number; type: string; ts: { _seconds: number; _nanoseconds: number }; data?: Record<string, unknown> }>
  tabs: Array<{ logicalTabId: string; parentLogicalTabId?: string; scope: 'in_scope' | 'external'; status: 'open' | 'blocked' | 'scraped' | 'acted' | 'closed'; url?: string; reason?: string; updatedAt: number }>
  snapshot?: Record<string, unknown> // present only for bootstrap/resync; large snapshots may be hydrated from storage
  snapshotUpdatedAt?: number
}
SSE Event Shape
// GET /v2/rover/stream emits:
// event: ready      data: { sessionId, ts }
// event: projection data: SessionProjectionResponse
// event: ping       data: { ts }
// event: error      data: { message }
Public A2WRun
type A2WInputReason =
  | 'auth_required'
  | 'sign_in_link_required'
  | 'account_link_required'
  | 'payment_method_required'
  | 'payment_confirmation_required'
  | 'action_confirmation_required'
  | 'human_verification_required'
  | 'browser_takeover_required'
  | 'merchant_policy_blocked'
  | 'risk_review_required'
  | 'terms_acknowledgement_required'
  | 'offer_claim_required'

type A2WRun = {
  id: string
  protocol?: 'a2w'
  runId: string
  run: string
  status: 'pending' | 'waiting_browser' | 'running' | 'input_required' | 'completed' | 'failed' | 'cancelled' | 'expired'
  open?: string
  links?: {
    // self, poll, stream, ndjson, workflow, continue, cancel, open, browserLink ...
    // artifacts appears when the run produced files — GET it for signed download URLs.
    artifacts?: { href: string; method?: 'GET' }
    [rel: string]: unknown
  }
  input?: {
    reason?: A2WInputReason
    message?: string
    questions?: unknown[]
    // Confirm/verify links live HERE, never on top-level links:
    // relay them to the human and poll — do not POST input for those reasons.
    links?: { confirm?: string; verify?: string; open?: string }
    expiresAt?: string
  }
  authInput?: {
    // Sign-in resume status (sign_in_link_required). Never carries the provided value.
    status?: 'awaiting' | 'provided' | 'consumed'
    kind?: 'magic_link' | 'otp' | 'unknown'
    prompt?: string
    emailMasked?: string
  }
  result?: {
    text?: string
    blocks?: unknown[]
    summary?: string
    observation?: { url?: string; title?: string; host?: string; summary?: string }
    transcript?: { messages?: Array<{ role?: string; text?: string; ts?: number }> }
    artifacts?: Record<string, unknown>[]
  }
}
Public A2W Event Shape
// GET /v2/a2w/runs/{id} with SSE or NDJSON emits:
// ready
// status
// step
// tool
// message
// observation
// input
// done
// error
//
// Uniform envelope:
// { id, type, ts, data, chunked?, chunkIndex?, chunkCount?, artifactRef? }

Conflict and Auth Semantics

  • 409 stale_seq when expectedSeq is stale/missing (strict mode) for mutable run-scoped calls.
  • 409 stale_epoch when expectedEpoch is stale/missing (strict mode) for mutable calls.
  • 409 active_run_exists on concurrent run creation races (typed conflict, no generic unknown error).
  • 200 decision='stale_run' for non-fatal stale/missing run in POST /command with type='TAB_EVENT'.
  • If command-based tab preflight is temporarily unavailable, SDK falls back to local smart-tab checks instead of hard-blocking navigation.
  • 401 SESSION_TOKEN_EXPIRED, 401 SESSION_TOKEN_INVALID, and 401 BOOTSTRAP_REQUIRED for typed auth flows.

Run Lifecycle and Continuity Semantics

  • Hard invariant: one active run per session, enforced in backend store/ledger.
  • requestedMode in POST /command payloads with type='RUN_INPUT': act and planner force backend mode; auto uses heuristic routing.
  • SDK default: normal user sends are fresh task boundaries with forceNewRun=true (fresh prevSteps + tab scope).
  • continueRun=true is used only for ask_user answer submission on the active boundary.
  • Heuristic follow-up chat carryover is cue-only (followupChatLog in worker payloads), and never carries prior task state.
  • Worker-to-SDK continuation semantics:loop_continue, same_tab_navigation_handoff, awaiting_user.
  • Navigation outcome semantics:same_tab_scheduled, new_tab_opened, blocked.
  • Stale seq/epoch races are expected under concurrent navigation/events; SDK should perform one silent retry for command-based tab stale conflicts.
Quick StartConfigurationOpen Workspace