Getting Started

OverviewQuick StartInstant PreviewTry on Other SitesWorkspace

Integration

ConfigurationSecurity & PoliciesAI DiscoveryAI / 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 a canonical envelope like { url, goal, capabilityId, args, target, identity, execution, accept, policy }. Compatibility aliases such as { url, prompt } and { url, shortcutId } still work.

POST/v1/tasks

Create a neutral public task for any Rover-enabled site using a target URL plus a canonical goal or shortcut envelope.

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

Required Request Fields

FieldTypeDescription
url | targetUrlstringTarget page URL on a Rover-enabled site.

Optional Request Fields

FieldTypeDescription
goalstringCanonical natural-language goal for the task.
promptstringCompatibility alias for `goal`.
shortcutId | shortcutstringExact saved shortcut/capability ID. Use for repeatable flows.
capabilityIdstringExplicit page/site capability identifier when the caller already knows the target skill.
argsRecord<string, unknown>Structured task arguments for the selected capability.
target{ pageId?, route?, capabilityId?, entityId?, formId? }Optional page/entity/form targeting hints.
identity{ userPresent?, signature?, signatureInput?, verificationMethod? }Structured caller/user-presence and verification hints.
execution{ mode?: 'auto' | 'browser' | 'cloud'; userPresent?: boolean }Requested execution path and user-presence hints.
accept{ modes?: ('text' | 'markdown' | 'json' | 'observation' | 'artifacts')[] }Requested result modes.
policy{ confirmation?: 'auto' | 'required' | 'site_policy'; crossHost?: 'allow' | 'same_host' | 'site_policy' }Execution-policy hints that the site may honor or narrow.
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`.
  • Compatibility aliases like `prompt` and `shortcut` still work, but `goal`, `shortcutId`, `capabilityId`, `args`, `target`, `identity`, `execution`, `accept`, and `policy` are the canonical task shape.
  • 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.
goalstringCanonical goal for the delegated child task.
promptstringCompatibility alias for delegated natural-language work.
shortcutIdstringExact shortcut to run on the receiving site.
capabilityIdstringExplicit child-task capability identifier.
argsRecord<string, unknown>Structured arguments for the delegated capability.
target{ pageId?, route?, capabilityId?, entityId?, formId? }Optional page/entity/form targeting hints on the receiving site.
identity{ userPresent?, signature?, signatureInput?, verificationMethod? }Structured user-presence and verification hints for the child task.
execution{ mode?: 'auto' | 'browser' | 'cloud'; userPresent?: boolean }Requested execution path for the child task.
accept{ modes?: ('text' | 'markdown' | 'json' | 'observation' | 'artifacts')[] }Requested child-task result modes.
policy{ confirmation?: 'auto' | 'required' | 'site_policy'; crossHost?: 'allow' | 'same_host' | 'site_policy' }Execution-policy hints for the child task.
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 persists shortcuts, business type, sparse Rover V3 experience overrides, greeting, voice dictation, AI access policy, agent discovery policy, and per-site page-capture overrides. 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. Boot-only flags such as ui.mascot.soundEnabled and ui.muted 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/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/deleteRoverSite

Delete a Rover site, all owned site keys, and Rover-owned config while retaining historical RoverBook 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 RoverBook owner settings/questions.
  • Historical RoverBook 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 ATP task entry, browser deep links, cloud browser use, and delegated handoffs.
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. 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": [],
	      "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": "auto",
        "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.
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
  • Live Test
  • 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