Getting Started

OverviewQuick StartInstant PreviewTry on Other SitesWorkspace

Integration

ConfigurationSecurity & PoliciesAI / Agent Tasks

Reference

API ReferenceInstant Preview APIExamplesRoadmap

API Reference

Complete Rover docs for workspace key management, RoverBook Firestore data paths plus private settings callables, public task resources, and browser runtime contracts.

Public task base: https://agent.rtrvr.ai/v1/tasks · 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.
  • task access token for the public task URL returned by /v1/tasks.
  • Firebase auth + Firestore rules for owner-only RoverBook analytics reads in Workspace, plus Firebase-authenticated callables for private settings such as notification subscriptions.

Public Agent Task API (`/v1/tasks`)

Neutral AI / CLI protocol for Rover-enabled sites. The source-visible marker <script type="application/agent+json"> is optional but recommended for raw HTML discovery. Host-only launches still work when callers post directly to https://agent.rtrvr.ai/v1/tasks with only { url, prompt }.

POST/v1/tasks

Create a neutral public task for any Rover-enabled site using only a target URL and prompt or shortcut.

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
promptstringNatural-language task prompt.
shortcutstringExact saved shortcut ID. Use for repeatable flows.
agent{ key?, name?, vendor?, model?, version?, homepage? }Optional self-reported visiting-agent metadata used by Rover and RoverBook attribution.

Success Example

{
  "id": "agt_123",
  "task": "https://agent.rtrvr.ai/v1/tasks/agt_123?access=agt_access_...",
  "workflow": "https://agent.rtrvr.ai/v1/workflows/wf_456?access=wf_access_...",
  "open": "https://www.rtrvr.ai/#rover_receipt=rrc_...",
  "browserLink": "https://www.rtrvr.ai/?rover=get+me+the+latest+blog+post#rover_receipt=rrc_...",
  "status": "pending"
}

Notes

  • Headers drive advanced behavior: `Accept`, `Prefer: wait=15`, `Prefer: execution=auto|browser|cloud`, and `Idempotency-Key`.
  • 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 `auto`: browser attach is preferred. `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` for guaranteed browserless execution today. Explicit cloud tasks omit browser handoff URLs.
GET/v1/tasks/{id}

Read the canonical public task resource as JSON, SSE, or NDJSON.

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

Notes

  • `Accept: application/json` returns latest state or final result.
  • `Accept: text/event-stream` streams uniform task events.
  • `Accept: application/x-ndjson` streams the same events in CLI-friendly NDJSON.
POST/v1/tasks/{id}

Continue a task that is waiting on user input.

Auth: Task access token.

Required Request Fields

FieldTypeDescription
inputstringUser or agent continuation answer.
DELETE/v1/tasks/{id}

Cancel an in-flight public task.

Auth: Task access token.

POST/v1/tasks/{id}/handoffs

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

Auth: Parent task access token.

Required Request Fields

FieldTypeDescription
urlstringTarget Rover-enabled site URL.

Optional Request Fields

FieldTypeDescription
instructionstringDelegation instruction for the target site.
promptstringPrompt alias for instruction when delegating natural-language work.
shortcutIdstringExact shortcut to run on the receiving site.
agent{ key?, name?, vendor?, model?, version?, homepage? }Optional child-task agent identity override. If omitted, the current visiting-agent attribution is inherited.
contextSummarystringStructured summary to carry into the child task.
expectedOutputstringDescribe what the child should return to the parent workflow.

Notes

  • Delegated child tasks are still ordinary task resources; they simply inherit the parent's workflow lineage.
  • Receiving sites must enable `siteConfig.aiAccess.allowDelegatedHandoffs` in Workspace.
GET/v1/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 tasks.

Workspace Management APIs

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

Cloud site config currently persists shortcuts, greeting, voice dictation, and per-site page-capture overrides. UI branding and audio controls such as ui.muted stay in Rover boot config rather than 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/rotate APIs, including `siteMode`, `domainScopeMode`, navigation policy, 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`, and navigation policy updates.
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 rotated key, including `siteMode`, `domainScopeMode`, and navigation policy.
POST/getRoverSiteConfig

Read cloud shortcut, greeting, voice, 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 shortcut, greeting, voice, 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.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.pageConfigRoverPageCaptureConfig | nullSparse per-site page-capture overrides. 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.

RoverBook Workspace Data Paths

RoverBook analytics pages now read Firestore directly under owner-auth rules. Backend callables remain only for private settings that include masked secrets, such as notification subscriptions and interview-question management. These are distinct from public site-tag ingest routes and are not public `siteId` browser APIs.

READFirestore: roverbook_* collections

Owner-facing RoverBook 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_visits`, `roverbook_scores`, `roverbook_reviews`, `roverbook_interviews`, `roverbook_questions`, `roverbook_notes`, and `roverbook_posts` directly.
  • Signed public RoverBook GET routes still exist for runtime/agent surfaces used by `@rover/roverbook`.
POSTgetRoverBookNotificationSettings

Read the private RoverBook 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 RoverBook 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 RoverBook outbound notifications for the site.
webhooksRoverBookWebhookSubscription[]Private per-site webhook subscription list.
interviewQuestionsstring[]Per-site RoverBook 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 RoverBook interview questions for a site.

Auth: Firebase ID token (owner only).

Required Request Fields

FieldTypeDescription
siteIdstringOwned Rover site identifier.
interviewQuestionsstring[]Per-site RoverBook 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
sessionIdstringClient session identifier (auto-generated if omitted).
sessionTokenstringCurrent rvrsess_* token. If invalid/expired and bootstrap token exists, server falls back to bootstrap flow.

Success Example

{
  "success": true,
  "data": {
    "sessionId": "visitor-123",
    "sessionToken": "rvrsess_...",
    "sessionTokenExpiresAt": 1771484403000,
    "streamToken": "rvrsess_...",
    "epoch": 5,
    "capabilities": { "roverEmbed": true },
    "policy": {
      "domainScopeMode": "registrable_domain",
      "externalNavigationPolicy": "open_new_tab_notice",
      "crossHostPolicy": "same_tab",
      "enableExternalWebContext": true,
      "externalScrapeMode": "on_demand",
      "externalAllowDomains": [],
      "externalDenyDomains": []
    },
    "projection": { "sessionId": "visitor-123", "epoch": 5, "events": [], "tabs": [] },
    "siteConfig": {
      "shortcuts": [],
      "greeting": { "text": "Welcome" },
      "voice": { "enabled": true, "language": "en-US", "autoStopMs": 2600 },
      "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.
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/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": "visitor-123",
    "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": "visitor-123", "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": "visitor-123",
    "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": "visitor-123",
    "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: sessionToken (query/body)

Required Request Fields

FieldTypeDescription
sessionIdquery stringSession to stream.

Optional Request Fields

FieldTypeDescription
seqAfternumberStart events after this sequence.

Notes

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

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

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdquery/bodySession to fetch.

Optional Request Fields

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

Upsert compacted checkpoint/snapshot for resume.

Auth: sessionToken

Required Request Fields

FieldTypeDescription
sessionIdstringTarget session.
checkpoint | payloadobjectCompacted snapshot payload.

Optional Request Fields

FieldTypeDescription
visitorIdstringVisitor ID for checkpoint ownership.
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>
  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 AgentTask

type AgentTask = {
  id: string
  status: 'pending' | 'waiting_browser' | 'running' | 'input_required' | 'completed' | 'failed' | 'cancelled' | 'expired'
  open?: string
  input?: { questions?: unknown[]; message?: 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 Task Event Shape

// GET /v1/tasks/{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 navigation policy 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
rtrvr.ai logo
Rover

Browser-native execution for websites and interfaces, plus analytics for the owners improving them.

Product

  • Overview
  • Get Started
  • Test Live
  • Pricing
  • Sweet Shop

Developers

  • GitHub
  • Preview Helper
  • Quick Start
  • Instant Preview
  • Try on Other Sites
  • Instant Preview API
  • Configuration
  • AI / Agent Tasks
  • API Reference
  • Security
  • Examples

Resources

  • Blog
  • Videos
  • SDK Preview Helpers
  • OpenAPI Spec
  • rtrvr.ai Docs
  • rtrvr.ai Cloud

© 2026 rtrvr.ai. All rights reserved.

PrivacyTerms