Examples
Common integration patterns for different use cases.
Rover v2 task boundaries are strict: normal sends always start a fresh task boundary. Only ask_user answers continue the current boundary.
Basic Setup
Minimal latency-first ACT setup to get Rover running quickly.
<script>
(function(){ var r = window.rover = window.rover || function(){ (r.q = r.q || []).push(arguments); }; r.l = +new Date(); })();
rover('boot', {
siteId: 'my-site',
publicKey: 'pk_site_your_public_key',
allowedDomains: ['example.com'],
navigation: { crossHostPolicy: 'same_tab' },
taskRouting: { mode: 'act' }, // Force ACT routing (no planner routing heuristics)
});
</script>
<script src="https://rover.rtrvr.ai/embed.js?v=your_site_key_id" async></script>Journeys + Async Identify
Blend workspace journeys with runtime overrides and personalize greeting after login.
<script>
(function(){ var r = window.rover = window.rover || function(){ (r.q = r.q || []).push(arguments); }; r.l = +new Date(); })();
rover('boot', {
siteId: 'my-app',
publicKey: 'pk_site_your_public_key',
siteKeyId: 'your-site-key-id',
allowedDomains: ['app.example.com'],
navigation: { crossHostPolicy: 'same_tab' },
// Workspace journeys are fetched by default via /v2/rover/session/open.
// Optional override in boot config:
ui: {
shortcuts: [
{ id: 'onboard', label: 'Onboard me', prompt: 'Guide me through onboarding', routing: 'planner', enabled: true }
],
greeting: { text: 'Hey {name}! Need setup help?', delay: 2000, duration: 8000 }
},
});
// Later, when auth completes:
rover('identify', { name: 'Alex', email: 'alex@example.com' });
</script>
<script src="https://rover.rtrvr.ai/embed.js?v=your_site_key_id" async></script>Voice Dictation
Enable browser dictation so visitors can speak requests, edit the transcript, and manually send.
<script>
(function(){ var r = window.rover = window.rover || function(){ (r.q = r.q || []).push(arguments); }; r.l = +new Date(); })();
rover('boot', {
siteId: 'my-app',
publicKey: 'pk_site_your_public_key',
allowedDomains: ['app.example.com'],
navigation: { crossHostPolicy: 'same_tab' },
ui: {
voice: {
enabled: true,
language: 'en-US',
autoStopMs: 2600
}
}
});
</script>
<script src="https://rover.rtrvr.ai/embed.js?v=your_site_key_id" async></script>Onboarding Flow
Auto-routing setup with planner fallback only when ACT has no usable outcome.
<script>
(function(){ var r = window.rover = window.rover || function(){ (r.q = r.q || []).push(arguments); }; r.l = +new Date(); })();
const isNewUser = !localStorage.getItem('onboarded');
rover('boot', {
siteId: 'my-app',
publicKey: 'pk_site_your_public_key',
allowedDomains: ['app.example.com'],
navigation: { crossHostPolicy: 'same_tab' },
openOnInit: isNewUser,
taskRouting: {
mode: 'auto',
plannerOnActError: true, // Planner fallback runs only if ACT has no usable result
actHeuristicThreshold: 5
},
checkpointing: { enabled: true, autoVisitorId: true },
});
</script>
<script src="https://rover.rtrvr.ai/embed.js?v=your_site_key_id" async></script>Checkout Assistant
Help users complete checkout by filling addresses, applying promos, and handling payment flows.
<script>
(function(){ var r = window.rover = window.rover || function(){ (r.q = r.q || []).push(arguments); }; r.l = +new Date(); })();
rover('boot', {
siteId: 'my-store',
publicKey: 'pk_site_your_public_key',
allowedDomains: ['shop.example.com', 'checkout.example.com'],
domainScopeMode: 'registrable_domain',
navigation: { crossHostPolicy: 'same_tab' },
externalNavigationPolicy: 'block',
allowActions: true,
taskRouting: { mode: 'auto', plannerOnActError: true },
});
</script>
<script src="https://rover.rtrvr.ai/embed.js?v=your_site_key_id" async></script>Form Assistance
Guide users through complex multi-step forms with validation and auto-fill.
<script>
(function(){ var r = window.rover = window.rover || function(){ (r.q = r.q || []).push(arguments); }; r.l = +new Date(); })();
rover('boot', {
siteId: 'my-portal',
publicKey: 'pk_site_your_public_key',
allowedDomains: ['portal.example.com'],
navigation: { crossHostPolicy: 'same_tab' },
sessionScope: 'tab',
taskRouting: { mode: 'planner' },
checkpointing: { enabled: true, autoVisitorId: true },
});
</script>
<script src="https://rover.rtrvr.ai/embed.js?v=your_site_key_id" async></script>Read-Only Support Agent
Rover helps users find information and navigate, but doesn't take actions.
<script>
(function(){ var r = window.rover = window.rover || function(){ (r.q = r.q || []).push(arguments); }; r.l = +new Date(); })();
rover('boot', {
siteId: 'my-help',
publicKey: 'pk_site_your_public_key',
allowedDomains: ['help.example.com'],
navigation: { crossHostPolicy: 'same_tab' },
allowActions: false,
externalNavigationPolicy: 'open_new_tab_notice',
});
</script>
<script src="https://rover.rtrvr.ai/embed.js?v=your_site_key_id" async></script>Strict Security Mode
Maximum lockdown: host-only match, no external navigation, strict scoping.
<script>
(function(){ var r = window.rover = window.rover || function(){ (r.q = r.q || []).push(arguments); }; r.l = +new Date(); })();
rover('boot', {
siteId: 'secure-app',
publicKey: 'pk_site_your_public_key',
allowedDomains: ['app.example.com'],
domainScopeMode: 'host_only',
navigation: { crossHostPolicy: 'same_tab' },
externalNavigationPolicy: 'block',
sessionScope: 'tab',
});
</script>
<script src="https://rover.rtrvr.ai/embed.js?v=your_site_key_id" async></script>AI / Agent Task Examples
Use POST https://agent.rtrvr.ai/v1/tasks when you need structured results back. Deep links like ?rover=... stay browser-first convenience.
Browser-first query param
Fastest way to make Rover run in the page UI. Use the task protocol instead when you need structured results back.
https://www.rtrvr.ai/?rover=get%20me%20the%20latest%20blog%20postCreate a public task
Machine path for any AI, CLI, or agent that needs progress and a final result back.
curl -X POST 'https://agent.rtrvr.ai/v1/tasks' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"url": "https://www.rtrvr.ai",
"prompt": "get me the latest blog post"
}'Guaranteed browserless execution
Use cloud execution explicitly when the caller cannot open a real browser.
curl -X POST 'https://agent.rtrvr.ai/v1/tasks' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Prefer: execution=cloud' \
-d '{
"url": "https://www.rtrvr.ai",
"prompt": "get me the latest blog post"
}'Stream or continue the task
Use the canonical task URL for SSE, NDJSON, polling, continuation, and cancel.
# SSE
curl -N 'https://agent.rtrvr.ai/v1/tasks/agt_123?access=agt_access_...' \
-H 'Accept: text/event-stream'
# Continue input_required
curl -X POST 'https://agent.rtrvr.ai/v1/tasks/agt_123?access=agt_access_...' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{ "input": "Use the newest post from the blog index page." }'
# Cancel
curl -X DELETE 'https://agent.rtrvr.ai/v1/tasks/agt_123?access=agt_access_...' \
-H 'Accept: application/json'Cross-site handoff
Delegate a child task to another Rover-enabled site and keep one shared workflow lineage.
# Create the root task first
curl -X POST 'https://agent.rtrvr.ai/v1/tasks' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"url": "https://x.com",
"prompt": "Start checkout and hand off shipping selection when needed"
}'
# Later, delegate from the parent task
curl -X POST 'https://agent.rtrvr.ai/v1/tasks/agt_parent/handoffs?access=agt_access_parent' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"url": "https://y.com",
"instruction": "Continue the checkout flow and return the shipping options.",
"contextSummary": "User already selected product and entered address on x.com.",
"expectedOutput": "Return the cheapest valid shipping option and ETA."
}'
# Read the shared workflow
curl 'https://agent.rtrvr.ai/v1/workflows/wf_456?access=wf_access_...' \
-H 'Accept: application/json'Node fetch
Self-contained browserless example for agents running in Node 18+.
const createResponse = await fetch('https://agent.rtrvr.ai/v1/tasks', {
method: 'POST',
headers: {
'content-type': 'application/json',
'accept': 'application/json',
'prefer': 'execution=cloud',
},
body: JSON.stringify({
url: 'https://www.rtrvr.ai',
prompt: 'get me the latest blog post',
}),
});
const created = await createResponse.json();
const taskUrl = created.task;
for (;;) {
const taskResponse = await fetch(taskUrl, {
headers: { accept: 'application/json' },
});
const task = await taskResponse.json();
console.log(task.status, task.result?.text ?? '');
if (['completed', 'failed', 'cancelled', 'expired'].includes(task.status)) break;
await new Promise((resolve) => setTimeout(resolve, 1500));
}Python
Simple requests-based polling loop for hosted execution.
import time
import requests
create = requests.post(
"https://agent.rtrvr.ai/v1/tasks",
headers={
"Content-Type": "application/json",
"Accept": "application/json",
"Prefer": "execution=cloud",
},
json={
"url": "https://www.rtrvr.ai",
"prompt": "get me the latest blog post",
},
)
create.raise_for_status()
task_url = create.json()["task"]
while True:
current = requests.get(task_url, headers={"Accept": "application/json"})
current.raise_for_status()
payload = current.json()
print(payload["status"], payload.get("result", {}).get("text", ""))
if payload["status"] in {"completed", "failed", "cancelled", "expired"}:
break
time.sleep(1.5)Shell helper
Create a cloud task and stream NDJSON events. Requires jq.
rover_task() {
local url="$1"
local prompt="$2"
local created task_url
created="$(curl -sS -X POST 'https://agent.rtrvr.ai/v1/tasks' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Prefer: execution=cloud' \
-d "$(jq -nc --arg url "$url" --arg prompt "$prompt" '{url:$url,prompt:$prompt}')")" || return 1
task_url="$(printf '%s' "$created" | jq -r '.task')"
curl -sS "$task_url" -H 'Accept: application/x-ndjson'
}
rover_task "https://www.rtrvr.ai" "get me the latest blog post"Need a pattern not listed here? Check the Configuration Reference for all available options, or reach out on Discord.