# rtrvr.ai (Retriever AI) — Full Documentation > DOM-native AI web agent platform for browser automation. > Full documentation corpus for LLM ingestion — every page concatenated below. > Source: https://runrover.tech/docs · Per-page Markdown at https://runrover.tech/docs/.md ## Retriever AI: free browser agent Retriever AI (rtrvr.ai) works across the open web and signed-in sites in Chrome, with a separate Cloud browser and API/MCP access. Free Mode includes supported AI models and Cloud browser time for tasks you start in the extension or Cloud dashboard. No AI API key or paid AI subscription is required. Sponsored cards and a daily fair-use allowance apply. Your account shows the current allowance and reset time. When you reach it, wait for the reset, use your own AI provider, or choose a paid plan. Your provider may charge for its usage. One schedule that runs once a day or less often, in the Cloud or in your Chrome, is included, paid from the daily allowance. More schedules, faster schedules, triggers, cookie sync, API runs, rtrvr's agent over MCP, and WhatsApp tasks require a paid plan. Browser tools that let your own AI drive your Chrome over MCP are free on every plan. Data enrichment and managed proxies can use credits separately. On the free plan, Cloud API calls made with an API key, the MCP Cloud tools (cloud_agent, cloud_scrape, and agent or scrape when they run in Cloud), and WhatsApp tasks need a paid plan, as does running rtrvr's agent in your Chrome through API or MCP. Free Mode covers the tasks you start in the extension or Cloud dashboard. On a paid plan, API, MCP, and WhatsApp runs use credits for the resources they consume. Welcome credits are a one-time balance, separate from the recurring Free Mode allowance. Free Mode involves sponsored content in both the Chrome extension and Cloud, as described in the Terms and Privacy Notice. Using your own AI provider avoids model-credit charges and the Free Mode allowance. Cloud resources and managed services may still use credits. Sponsored cards still appear on the free plan. Paid plans offer ad-free runs. - [Free and paid plans](https://rtrvr.ai/pricing) - [Chrome extension](https://rtrvr.ai/extension) - [Collect website data](https://rtrvr.ai/use-cases/ai-web-scraping) - [Fill forms from documents](https://rtrvr.ai/use-cases/ai-form-filling) - [Research prospects](https://rtrvr.ai/use-cases/lead-enrichment) - [Prepare job applications](https://rtrvr.ai/use-cases/job-applications) - [API documentation](https://rtrvr.ai/docs/api) - [MCP setup](https://rtrvr.ai/docs/mcp) - [Free Mode terms](https://rtrvr.ai/terms#free-mode) - [Privacy notice](https://rtrvr.ai/privacy) ## Contents - Overview: https://runrover.tech/docs - Quick start: https://runrover.tech/docs/quick-start - For you: https://runrover.tech/docs/for-you - Web agent: https://runrover.tech/docs/web-agent - Jev: https://runrover.tech/docs/jev - Sheets workflows: https://runrover.tech/docs/sheets-workflows - Recordings: https://runrover.tech/docs/recordings - Tool calling: https://runrover.tech/docs/tool-calling - Connectors: https://runrover.tech/docs/connectors - Skills: https://runrover.tech/docs/skills - Enrichment datasets: https://runrover.tech/docs/enrichment-datasets - CLI and SDK: https://runrover.tech/docs/cli - API overview: https://runrover.tech/docs/api - Agent API: https://runrover.tech/docs/agent - Scrape API: https://runrover.tech/docs/scrape - Browser API and MCP: https://runrover.tech/docs/mcp - Browser profiles: https://runrover.tech/docs/profiles - Tailscale tunnels: https://runrover.tech/docs/tailscale - Shortcuts: https://runrover.tech/docs/shortcuts - Triggers: https://runrover.tech/docs/triggers - Webhooks: https://runrover.tech/docs/webhooks - Schedules: https://runrover.tech/docs/schedules - Secure logins: https://runrover.tech/docs/cookie-sync - Permissions and privacy: https://runrover.tech/docs/permissions-privacy - FAQ: https://runrover.tech/docs/faq - Changelog: https://runrover.tech/changelog --- # Get rtrvr running. Docs # Get rtrvr running. Start in Chrome, run in Cloud, or call the agent from your product. Pick a path and finish the first job. [Search docs⌘ K](/docs/search) Start in Free Mode, with supported AI included. Choose a subscription for schedules, triggers, or ad-free runs. [Compare plans →](/pricing#free-mode) Free usage, ads, and data terms Free Mode includes supported AI models and Cloud browser time for tasks you start in the extension or Cloud dashboard. No AI API key or paid AI subscription is required. Sponsored cards and a daily fair-use allowance apply. Your account shows the current allowance and reset time. When you reach it, wait for the reset, use your own AI provider, or choose a paid plan. Your provider may charge for its usage. One schedule that runs once a day or less often, in the Cloud or in your Chrome, is included, paid from the daily allowance. More schedules, faster schedules, triggers, cookie sync, API runs, rtrvr's agent over MCP, and WhatsApp tasks require a paid plan. Browser tools that let your own AI drive your Chrome over MCP are free on every plan. Data enrichment and managed proxies can use credits separately. On the free plan, Cloud API calls made with an API key, the MCP Cloud tools (cloud\_agent, cloud\_scrape, and agent or scrape when they run in Cloud), and WhatsApp tasks need a paid plan, as does running rtrvr's agent in your Chrome through API or MCP. Free Mode covers the tasks you start in the extension or Cloud dashboard. On a paid plan, API, MCP, and WhatsApp runs use credits for the resources they consume. Free Mode involves sponsored content in both the Chrome extension and Cloud, as described in the Terms and Privacy Notice. Using your own AI provider avoids model-credit charges and the Free Mode allowance. Cloud resources and managed services may still use credits. Sponsored cards still appear on the free plan. Paid plans offer ad-free runs. [Free Mode terms](/terms#free-mode) · [Privacy notice](/privacy) Start here ## Choose how you want to work. Pick the environment closest to the job. You can add another one when you need it. [ 01 ### Start in Chrome. Work in the browser where you are already signed in. Ask for a table, a filled form, or a completed update. Install the extension](https://chromewebstore.google.com/detail/retriever-ai-web-agent/jldogdgepmcedfdhgnmclgemehfhpomg)[ 02 ### Give your product a browser. Call the agent from your app, CLI, SDK, or MCP client. Send the job and starting URLs. Get structured output back. See APIs and MCP](/docs/api)[ 03 ### Run beyond your laptop. Run a task in a separate Cloud browser. Choose a subscription when it needs to run on a schedule. Open the quick start](/docs/quick-start) 04 For your coding agent ### Give your agent the docs. Install the rtrvr skill in Claude Code or Codex. Your agent loads these docs whenever you ask about rtrvr, from writing tasks to calling the API. [Download skill.zip](/skill.zip) [Or point any agent at llms-full.txt](/llms-full.txt) Install in Claude Code mkdir -p ~/.claude/skills && curl -fsSL https://rtrvr.ai/skill.zip -o /tmp/rtrvr.zip && unzip -o /tmp/rtrvr.zip -d ~/.claude/skills Using Codex? Unzip into `~/.codex/skills` instead. The first prompt ## Say what you need done. Give rtrvr the goal and the page or starting URL. It plans the route, does the work, and returns what you asked for. Try this Compare the current plans on this page. Return a table with plan, price, billing period, and source links. RESULT · TABLE **plan****price****billing period****source** 01 02 03 3 rows · 4 fields**source links kept** ready to use Side by side ## One task. Three outcomes. Browser Use gets stuck repeating steps. Firecrawl dumps scraped URLs and hallucinates the answer. rtrvr plans the research, traverses the right sources, and returns a cited answer. [Read the full comparison](/blog/rtrvr-vs-browser-use-vs-skyvern-vs-firecrawl) Recorded head-to-head browser agent comparison. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Quick start Finish the first job from Chrome, Cloud, or your product. Start in Free Mode, with supported AI included. Choose a subscription for schedules, triggers, or ad-free runs. [Compare plans →](/pricing#free-mode) Free usage, ads, and data terms Free Mode includes supported AI models and Cloud browser time for tasks you start in the extension or Cloud dashboard. No AI API key or paid AI subscription is required. Sponsored cards and a daily fair-use allowance apply. Your account shows the current allowance and reset time. When you reach it, wait for the reset, use your own AI provider, or choose a paid plan. Your provider may charge for its usage. One schedule that runs once a day or less often, in the Cloud or in your Chrome, is included, paid from the daily allowance. More schedules, faster schedules, triggers, cookie sync, API runs, rtrvr's agent over MCP, and WhatsApp tasks require a paid plan. Browser tools that let your own AI drive your Chrome over MCP are free on every plan. Data enrichment and managed proxies can use credits separately. On the free plan, Cloud API calls made with an API key, the MCP Cloud tools (cloud\_agent, cloud\_scrape, and agent or scrape when they run in Cloud), and WhatsApp tasks need a paid plan, as does running rtrvr's agent in your Chrome through API or MCP. Free Mode covers the tasks you start in the extension or Cloud dashboard. On a paid plan, API, MCP, and WhatsApp runs use credits for the resources they consume. Free Mode involves sponsored content in both the Chrome extension and Cloud, as described in the Terms and Privacy Notice. Using your own AI provider avoids model-credit charges and the Free Mode allowance. Cloud resources and managed services may still use credits. Sponsored cards still appear on the free plan. Paid plans offer ad-free runs. [Free Mode terms](/terms#free-mode) · [Privacy notice](/privacy) ## 1Create an account Create the workspace first. Generate an API key only when you need programmatic access; API runs need a paid plan. [Create a workspace](/cloud) workspace_01_ **Your team** Cloud access API key when needed ready to run ## 2Choose where it runs Pick the surface closest to the job. You can move the same outcome between them later. [ 01 active tab Find every open support ticket from Acme. signed-in page ready ### Chrome extension Work in the Chrome browser already on your device, including sites behind logins, SSO, and internal tools. Install extension ](https://chromewebstore.google.com/detail/retriever-ai-web-agent/jldogdgepmcedfdhgnmclgemehfhpomg)[ 02 scheduled**08:00**_every weekday_ result → webhook ### Cloud Run and observe browser jobs away from your laptop. Schedule them or send the result to another system. Run in Cloud ](/cloud)[ 03 `POST /agent`200 { "result": "…" } ### API and MCP Call the agent from an app, CLI, SDK, or MCP client. Start with one job and one returned result. Read the API reference ](/docs/api) On the website, open **Routing** below your prompt and pick your online browser under **From your computer**. Sign in to the extension and website with the same account, and keep Chrome open. To run in Cloud, choose an option under **From the cloud**. [Watch from 0:00](https://www.youtube.com/watch?v=wvO6YR8RXDk&t=0s), or follow the [routing and Instagram walkthrough](/docs/web-agent#run-in-your-chrome-or-in-cloud). Saving results to Google Sheets or using another app? [Connect your apps](/docs/connectors). Drive asks for file access separately from Google sign-in. ## 3Know the endpoints 01`/scrape` **Read the page** Returns page content and the accessibility tree for your own model. _POST_ 02`/agent` **Finish the job** Plans and runs a job in a Cloud browser, then returns the result. _POST_ 03`/mcp` **Connect a client** Lets an MCP client use your signed-in Chrome session or Cloud tools. _POST_ ## 4Send the first request Call `/agent` with one job, one or more URLs, and the response detail you need. cURL ``` curl -X POST "https://api.rtrvr.ai/agent" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Return the top 10 products with price and source URL", "urls": ["https://example.com/products"], "response": { "verbosity": "final" } }' ``` one job, one returned result YOUR NEXT RUN ## Run the example on a real site. Use Chrome for the page in front of you. Use Cloud when the run should continue on a schedule or across many pages. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # For you Find tasks to hand to Retriever. Choose the context behind your ideas. For you suggests complete workflows Retriever can help with, based on your recent work and browsing. Each idea includes a task prompt you can review and edit before starting. [Open For you](/cloud?view=for-you). [Video: For you in Cloud and Chrome](https://www.youtube.com/watch?v=L4C1Lp4LRbs) ## Try your first suggestion - Open For you from the Cloud sidebar or the Chrome extension. Sign in to your Retriever account. - Select a task to read the idea and its prompt. For personal ideas, Cloud also shows why it came up and the activity behind it. - Edit the task details, then select Let’s do it when you are ready to start. Opening the feed or reviewing an idea does not run a task. New here? Try a template: find 20 LinkedIn jobs, compare a product’s price at five stores, review an X profile, or catch up on five AI stories. Cloud shows two examples at a time. Personalized ideas replace them when ready. ## What powers your ideas - Starter templates: the extension can match known sites in your current and open tabs locally. This adds no upload. Turn browsing off in preferences to use context-free examples instead. - Recent Retriever tasks: short task requests and outcomes from your account in Chrome and Cloud. - Open tabs: the extension shares titles and URLs from up to 500 normal tabs once a day, when you first open it. This is on by default. Turn it off in For you preferences. - Browsing history: optional Chrome permission. The first read samples up to 500 recent URL records from the last 30 days. Later daily reads add new activity. History replaces the open-tab snapshot. It includes titles, URLs, visit times and available visit counts. Browsing collection excludes incognito tabs, URL queries and fragments, page contents, cookies and passwords. Extension Private Mode pauses collection. Titles and URL paths can still contain personal information. Retriever’s AI providers process the shared context to prepare your ideas. ## Choose what to share Enable browsing history in the extension. Chrome asks for permission when you click. You can turn history off, stop browsing collection, exclude sites, or clear For you context in [preferences](/cloud?view=for-you#preferences). Excluding a site also removes its saved browsing context. Clearing For you does not delete your original tasks. Context is retained for up to 30 days. Ideas expire after seven days, including saved ideas. [Privacy policy](/privacy). ## Refresh and task execution Open For you or click Refresh to check for ideas. Retriever reuses prepared ideas and only generates again when eligible and the context has changed. Generation runs at most once a day after a successful preparation. Clicking Refresh does not start an agent task, scan your tabs again, or send an email. Select an idea to review its task prompt. Let’s do it starts the handoff to the agent. Your normal model and task costs apply; supported interactive runs are available in [Free Mode](/pricing#free-mode), with sponsored cards and a daily fair-use allowance. ## Email previews Emails are optional. Enable them in Cloud preferences to receive a short preview and a link to your ideas. Kit delivers these emails. Choose up to one or two per week. Retriever only sends new ideas and slows down or pauses when you stop engaging. Unsubscribe from the email or turn previews off in preferences. Read [why we built the For you feed](/blog/for-you-ai-feed) or [watch the short demo](https://www.youtube.com/shorts/DLYQ0wtUtLI). --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Web Agent The core DOM-native intelligence engine that powers every rtrvr.ai surface: extension, cloud, and API. # The Web Agent [Video: Web Agent Demo](https://www.youtube.com/watch?v=BqDy6st7iGA) Retriever AI collects information, fills forms, and takes actions across websites. It reads the page structure to find links, fields, and buttons. Describe a task, choose the tabs it can use, and review the result. ## Free Mode and paid plans Free Mode includes supported AI models and Cloud browser time for tasks you start in the extension or Cloud dashboard. No AI API key or paid AI subscription is required. Sponsored cards and a daily fair-use allowance apply. Your account shows the current allowance and reset time. When you reach it, wait for the reset, use your own AI provider, or choose a paid plan. Your provider may charge for its usage. New accounts receive 100 one-time welcome credits for paid usage. They are separate from the recurring Free Mode allowance. One schedule that runs once a day or less often, in the Cloud or in your Chrome, is included, paid from the daily allowance. More schedules, faster schedules, triggers, cookie sync, API runs, rtrvr's agent over MCP, and WhatsApp tasks require a paid plan. Browser tools that let your own AI drive your Chrome over MCP are free on every plan. Data enrichment and managed proxies can use credits separately. On the free plan, Cloud API calls made with an API key, the MCP Cloud tools (cloud_agent, cloud_scrape, and agent or scrape when they run in Cloud), and WhatsApp tasks need a paid plan, as does running rtrvr's agent in your Chrome through API or MCP. Free Mode covers the tasks you start in the extension or Cloud dashboard. On a paid plan, API, MCP, and WhatsApp runs use credits for the resources they consume. Free Mode involves sponsored content in both the Chrome extension and Cloud, as described in the Terms and Privacy Notice. [Compare plans](/pricing#free-mode), read the [Free Mode terms](/terms#free-mode), or see the [Privacy Notice](/privacy). ## Run in your Chrome or in Cloud You can start a task on [rtrvr.ai/cloud](/cloud) and run it in the Chrome browser on your computer. Open **Routing** below the prompt and choose your online browser under **From your computer**. Once selected, the button shows your browser's name, such as **Chrome on MacIntel**. Starting a Chrome task from the website is separate from paid API/MCP access. Eligible interactive tasks can use Free Mode. - Install the rtrvr extension, then sign in to the extension and website with the same rtrvr account. - Keep that Chrome profile open and signed in to the site you want to use. - Select the browser in Routing, write your task, and send it. The website shows the progress and result. - To run in Cloud instead, open the same menu and choose an option under From the cloud. Choose the accounts the task can use in [Secure logins](/docs/cookie-sync). | Where it runs | When to use it | | --- | --- | | Your Chrome | Use the account and sites already open in that Chrome profile. Keep Chrome open during the run. | | Cloud | Run away from your laptop. [Add the logins](/docs/cookie-sync) the task needs before starting. | ## Find Instagram creators Search Instagram by topic, find a creator, and ask rtrvr to follow, like, or comment. This walkthrough runs from the website through a Chrome profile already signed in to Instagram. [Video: Find Instagram creators and engage with their posts](https://www.youtube.com/watch?v=wvO6YR8RXDk&t=75s) | Jump to | What you'll see | | --- | --- | | [0:00](https://www.youtube.com/watch?v=wvO6YR8RXDk&t=0s) | Choose your Chrome browser from the website. | | [1:15](https://www.youtube.com/watch?v=wvO6YR8RXDk&t=75s) | Find a creator and engage with their posts. | | [2:18](https://www.youtube.com/watch?v=wvO6YR8RXDk&t=138s) | Open Cookie Sync to use your logins in Cloud. | ```text Search Instagram for matcha. Pick a creator from one of the top posts and follow them. Like one of their posts and leave a comment about that post. Return the profile link, post link, and what you did. ``` Choose the Chrome profile signed in to the Instagram account you want to use. Tell rtrvr which actions to take, then check the profile and post links in the result. To save a creator list to Google Sheets, [connect Google Drive](/docs/connectors#connect-google-drive). ## Agentic Architecture When you issue a command, the Planner agent orchestrates 20+ specialized sub-agents to complete the task: - Action Agent: Handles clicks, typing, and navigation - Extraction Agent: Identifies and structures data from the DOM - Crawl Agent: Manages pagination and multi-page discovery - PDF / File Agent: Reads and fills complex forms, uploads documents > **info**: For repeated tasks, skip the planning step entirely by using Shortcuts or Replay for deterministic, consistent results. ## Example Prompts ```text "Go to Amazon and find the price of iPhone 15 Pro" "Fill out this contact form with my information" "Add everyone on this event page as a professional connection" "Extract all email addresses from this company's team page" "Go to ChatGPT, ask about top restaurants in SF, extract the response" ``` > **info**: The agent handles complex multi-step workflows and will ask for clarification when needed. It operates identically whether running in the Chrome Extension, on Cloud headless browsers, or via the API. ## Multi-Tab Orchestration The agent can reference multiple open tabs simultaneously: comparing data across sites, moving information between systems, or processing dozens of URLs in parallel via Sheets Workflows. ## Deterministic Replay Once a multi-step workflow succeeds, you can replay its recorded steps without another planning pass. Shortcuts, Schedules, and Triggers can build on that recording; results still depend on the page and inputs available at run time. ## Models & Bring Your Own Key Free Mode includes the supported models shown in Model Settings. You do not need your own AI subscription or API key to start. Paid plans unlock additional managed models and features; your account shows the current choices. Save credits by bringing your own key: the "Add your LLM API" flow accepts keys from any major provider: OpenAI GPT models, Google Gemini, Meta Model API (Muse Spark), DeepSeek, OpenRouter models (MiniMax, Hunyuan, and more), or your own local/custom endpoint. You can also sign in with your ChatGPT plan directly. Keys are stored encrypted and work in cloud runs too. For Gemini specifically, typing /add-gemini-key in the extension walks you through getting a free key from Google AI Studio. If your own provider errors mid-task, the run falls back to a platform model so it completes: covered by Free Mode on the free plan while today's allowance lasts, billed in credits otherwise. Your key runs the model, so nothing deducts from the free plan's daily Free Mode allowance. To try Jev alongside your selected model, turn on **Try Jev** in the same model picker. This experimental option lets Jev choose browser actions while your model continues to plan and write. It is off by default and paused in Private Mode. See the [Jev setup guide](/docs/jev) for screenshots, a walkthrough, and what to expect. ## Credit Ceiling per Task Every task carries a credit ceiling: a cap on what one run may spend before it stops to check with you. It exists because a task that loops, crawls further than expected, or gets stuck retrying can otherwise burn through credits unattended. The default is 100 credits on paid plans and 25 on the Free plan; the typical task finishes in well under 15. When a run reaches the ceiling it pauses and shows what it has spent, what it produced so far, and what is still outstanding. Answer "Continue" and it resumes from exactly where it stopped with a fresh budget (nothing already done is repeated), or "Stop here" to keep the result and end the task. Scheduled runs are the exception: nobody is watching a cron run, so they stop at the ceiling and report their partial work instead of waiting forever for an answer. ### Raising or turning off the ceiling The ceiling is yours to set. If your work genuinely costs 200-400 credits a run, raise it once and the agent stops interrupting you: - Extension: Settings (the gear at the bottom of the side panel) → Agent Settings → "Credit Ceiling / Task". - Cloud: [Settings → Storage & Execution → Credit Ceiling / Task](/cloud?view=settings§ion=storage). - API: `maxCredits` on a single `/agent` call (shorthand for `options.limits.creditCeiling.credits`), which overrides the saved setting for that run. See [Agent API](/docs/agent). - MCP: `max_credits` on an `agent`, `planner` or `cloud_agent` call, the same budget for that one run. See [MCP](/docs/mcp). Setting the value to 0 turns the check off entirely. Blank (cloud) or the extension's disabled state falls back to the plan default. Each surface keeps its own value: the extension's setting governs extension runs, the cloud setting governs cloud and API runs. > **warning**: With the ceiling off, nothing bounds a single run but your credit balance, including scheduled runs nobody is watching. Prefer a high ceiling over no ceiling. ## Files & PDFs Drag and drop files into the chat or attach them via the toolbar. The agent has specialized capabilities for PDFs: reading content, filling form fields, and generating new documents. It can also upload attached files to web pages when prompted (e.g., "fill this job application and upload my resume"). ### File size limits - Signed in, you can attach files up to 128 MB each: in the extension side panel, the cloud composer, the Agent API (`files`) and MCP file parameters. In the extension's Private Mode the limit is 20 MB. - The model reads files up to 20 MB. For a larger file it sees only the name, type and size, and the agent can still upload that file into a web page or pass it on to tools and later steps. - The agent can also upload a file into a page straight from a link (for example a signed download URL). Files up to 1 GB work this way, and the file is downloaded once. ### Where downloaded files go When the agent saves a file (a PDF it opened, or a document it generated and you asked it to download), it uses Chrome's normal download flow, so the file lands in your browser's Downloads folder. The run's result lists each file (`Downloaded: name.pdf`) and shows a 💾 chip; click it, or open `chrome://downloads` in a new tab, to see every file with a "Show in folder" link. - Extension runs: files are on your computer, in Chrome's Downloads folder, and `chrome://downloads` is the quickest way to find them. - Cloud runs: the browser isn't yours, so downloaded files are backed up to your [Files](/cloud?view=files) and attached to the run as file artifacts you can open or download. - Generated PDFs and webpages are stored for you and linked from the result (`PDF:` / `Webpage:`); say "and download it" to also save a local copy. > **warning**: Saving several files in one task? Chrome allows one automatic download per site and blocks the rest until you approve them: look for the blocked-downloads icon at the right end of the address bar, click it, choose "Always allow", and re-run the task. The agent cannot see that block, so it may report files as saved when Chrome held them back. ## Context Tips Everything in your chat (messages, files, images) becomes context for the AI. Keeping context clean leads to better results. - Start fresh chats for new tasks: stale context can confuse the planner - Only enable the MCP/custom tools you actually need for the current task - Use Personal Context in settings to store persistent info (resume, company details) the agent remembers across all chats - Click the ✨ Enhance button (Cmd/Ctrl+P) to have a specialized model rewrite your prompt for clarity before sending > **success**: Enhancing prompts lets you co-plan with the agent. It's especially powerful for complex multi-step tasks where precise instructions matter. ## Cloud & Mobile The Chrome Extension is where you build and test workflows. Export successful workflows to rtrvr.ai Cloud for 24/7 headless execution, no laptop required. Recordings, tools, and KB context travel with the workflow automatically. - Export any workflow from the extension to Cloud with one click - Scale to thousands of parallel URLs via the API - Connect your account to WhatsApp: send text or voice messages to trigger automations and receive results on your phone - Share your best automations via link: recipients import with one click, including recordings, tools, and all context ## Platform Availability | Capability | Extension | Cloud | API | | --- | --- | --- | --- | | Natural-language planning | ✅ | ✅ | ✅ | | Multi-tab orchestration | ✅ | ✅ | ✅ | | Authenticated site access | ✅ (your sessions) | ✅ (saved logins or Chrome sync) | ✅ (saved logins or Chrome sync) | | Real-time feedback & steering | ✅ | No | No | | Deterministic replay | ✅ | ✅ | ✅ | | Files & PDF handling | ✅ | ✅ | ✅ | | WhatsApp trigger & results | No | ✅ | No | | Share & import workflows | ✅ | ✅ | ✅ | --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Try Jev in rtrvr.ai Let Jev choose browser actions alongside your usual AI model. Turn it on in Chrome or Cloud and try it on a task you know. **Experimental** Optional. Off by default. ## Turn on Jev Open the [Chrome extension](https://chromewebstore.google.com/detail/retriever-ai-web-agent/jldogdgepmcedfdhgnmclgemehfhpomg) or [rtrvr.ai Cloud](/cloud). Click the model name beside the prompt box, then turn on **Try Jev**. Keep your preferred model selected. Chrome extension 1 Click the model name beside the prompt box. 2 Turn on **Try Jev**. Cloud 1 Click the model name beside the prompt box. 2 Turn on **Try Jev**. The screenshots show Jev on. You can turn it off in the same menu. It is available in Free Mode and paid plans, with no separate TypeSafe account or API key. ## What Jev does Jev is [TypeSafe’s model for structured decisions](https://typesafe.ai/blog/introducing-system-one-models-and-jev). It chooses from options supplied by software and returns probabilities. In rtrvr, it helps choose the next browser action. 1. **Your selected model plans the task.** It writes code and text, handles open-ended steps, and prepares the work. 2. **rtrvr reads the page and builds the choices.** Each choice contains a tool call with its parameters already filled in. 3. **Jev selects a choice or hands the step back.** Your selected model handles steps that need its capabilities. 4. **rtrvr runs the action and reads the result.** The updated page informs the next step. Turning Jev on lets it participate where supported. Your selected model keeps its full planning context and handles steps that need generation or cannot be expressed by the supplied choices. How rtrvr prepares an action rtrvr builds complete choices from the current page: click an observed element, type an exact supplied value, or select an available option. It supplies element IDs and arguments, maps logical tabs to real browser tabs, and checks that the page observation still matches before returning the choice for execution. Jev’s **Choice** operation selects one of those calls or delegates. If the action request is too large, rtrvr can first use one batch of **Score** requests to select relevant page context, then ask Choice once. Planner prompts skip that scoring step. Explicit typed judgments can also use Jev where supported. Selecting saved site skills with Jev and reusing earlier page-region scores are follow-up ideas. They are not part of this setup. ## Try a familiar task Start with a task whose result you can check. For example: > Find three reusable water bottles under $30 on this site. Return each name, price, and product link. Run it with Jev off, then on, using the same selected model and starting page. Check the result, elapsed time, and credits used. Repeat on a few tasks you actually need; one run can be affected by changing pages, cached context, and different choices. Our first LinkedIn and Amazon comparisons finished sooner and had higher estimated inference costs with Jev. Each configuration ran once. The [full experiment](/blog/jev-browser-agent-benchmark) explains the results and limits; those runs predate the removal of planner-context scoring and do not establish a fixed saving for the current release or other tasks. ## Watch the experiment Jev inside rtrvr: the setup, tasks, results, and tradeoffs. [Watch on YouTube](https://www.youtube.com/watch?v=JsNQwFB9N1Q) or [read the findings and see the recorded data](/blog/jev-browser-agent-benchmark). ## Questions and fixes I can’t find the switch. Open the model picker beside the prompt box and look for **Try Jev**, below Free Mode. In the extension, update to version 37.9.0 or later and reopen the side panel. Should I choose Jev from the model list? Keep the model you normally use. Try Jev is a separate switch that works alongside that choice. See the [model guide](/models) if you need help choosing your main model. Why is it paused in Private Mode? Jev is not covered by rtrvr’s zero-data-retention promise, so Private Mode skips it. Your saved Jev preference is kept. Do I need a TypeSafe key, or does it make my run free? No separate TypeSafe key is needed. Your rtrvr plan’s usage rules still apply. Jev is available in Free Mode within its allowance and on paid plans. Will every task be faster or cheaper? That depends on the page, the task, your selected model, and the work needed to prepare Jev’s choices. Compare the finished result as well as time and cost. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Sheets Workflows Parallel processing for bulk data extraction: feed a spreadsheet, get structured results. # Sheets Workflows [Video: Sheets Workflows Demo](https://www.youtube.com/watch?v=Sas8iWMCBA4) Process hundreds or thousands of rows by connecting a Google Sheet. The agent opens URLs in parallel sub-agent tabs, performs extraction or actions for each row, and writes results back in real-time. It combines the dynamic capabilities of AI agents with the deterministic structure of spreadsheets. > **success**: We only access sheets you explicitly grant via the Google Drive Picker: we use the most restrictive drive.file scope. See Permissions & Privacy for details. ## How It Works - Upload your spreadsheet or connect an existing Google Sheet with input data - Define the task using a natural-language prompt - Specify which columns to use as context (URLs, names, search terms, etc.) - The agent executes the task for each row, opening parallel tabs as needed - Results are written back to new columns in real-time ## Example: Lead Enrichment Input sheet with company URLs. Prompt: "Visit the website and extract the CEO name and company size". To append data from marketplace datasets like LinkedIn or Crunchbase instead of scraping each site, see [Enrichment Datasets](/docs/enrichment-datasets). ```csv Company Name,Website,Industry,CEO Name,Company Size Acme Corp,acme.com,Software,John Smith,50-100 employees Beta Inc,beta.io,Healthcare,Sarah Johnson,100-500 employees Gamma LLC,gamma.co,Finance,Mike Wilson,10-50 employees ``` ## Advanced Use Cases - Price monitoring across multiple e-commerce sites - Contact extraction from company team pages - Social media profile analysis and data collection - Competitive research and market analysis - Form submissions with personalized data per row - Content scraping with structured JSON output ## Tool Mapping in Sheets You can map tool calls to run for every row. The agent intelligently pulls arguments from specific columns to populate tool parameters. Include details in your prompt like: "For each row upload as contact to HubSpot using the loadContact tool." | Column A (Input) | Column B (Agent Action) | | --- | --- | | user@example.com | @hubspot_lookup(email=A1) | | admin@test.org | @hubspot_lookup(email=A2) | ## Best Practices - Use clear column headers that describe the data - Include example rows to guide the agent's extraction pattern - Break complex tasks into smaller, focused workflows - Test with a small subset (5-10 rows) before processing large datasets - Use rate limiting for respectful web scraping > **warning**: Keep your prompts specific and include examples of expected output format for best results. ## Platform Availability | Capability | Extension | Cloud | API | | --- | --- | --- | --- | | Google Sheets integration | ✅ | ✅ | ✅ (via dataInputs) | | CSV / TSV upload | ✅ | ✅ | ✅ | | Parallel sub-agent tabs | ✅ | ✅ | ✅ | | Real-time sheet updates | ✅ | ✅ | No | | Append mode (running logs) | ✅ | ✅ | ✅ | --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Recordings & Grounding Show rtrvr the task once. Replay it anywhere, or turn the captured steps and page requests into a reusable tool. # Recordings & Grounding Perform the task once in Chrome. rtrvr captures the interaction path, then reuses it in Cloud, API calls, shortcuts, schedules, and triggers. ## What Gets Recorded The recorder captures DOM interactions (clicks, typing, navigation, selections), not your screen. This makes it more robust than screen recording (no pixel-matching failures), more private (we never see your screen), and portable across different screen sizes and resolutions. Alongside the interaction trace, the recorder captures the network calls the page makes while you work: the private JSON API behind the rendered HTML. That second layer is what lets rtrvr.ai turn a recording into a subroutine that hits the endpoint directly instead of replaying clicks. See [From Recording to Subroutine](#from-recording-to-subroutine) below. | Layer | What's captured | | --- | --- | | DOM interactions | Clicks, typing, scrolls, selections, navigation, waits, back: with the element selectors and shadow-root paths needed to replay them | | Network calls | `fetch`, `XHR`, `sendBeacon`, and Resource Timing entries: method, URL, request headers, request body, response status, response headers, response body, duration | | Page context | DOM snapshots at key steps plus server-rendered hydration payloads (the JSON already embedded in the page on load) | > **info**: Privacy: We only record DOM interactions and the page's own network traffic. Your screen is never captured, stored, or transmitted. Secrets in captured traffic (`authorization`, `cookie`, `x-api-key`, CSRF and signature headers) are redacted before anything is sent to a model. > **warning**: Capture is bounded: roughly 500 events per capture and ~64 KB per body by default. Larger bodies are kept as head + tail with the middle elided, and binary responses are flagged rather than stored. ## How to Record You do not have to record by hand. Ask for the tool in one sentence, such as "build me a tool that logs into app.example.com and returns this month's usage credits", and the agent arms the recorder, drives the page so it issues the request that carries the data, stops the recording, generates the tool from it, saves it, and calls it once to verify before reporting back. If the site needs a sign-in, the agent asks you to sign in in that tab first (never for a password in chat). To record manually: - Open the Recordings menu in the side panel toolbar and click **Start recording**: nothing to name first - Allow the microphone when Chrome asks: narration is how the agent learns why each step matters. You can also choose to record without it - Perform the task naturally in your browser (click buttons, fill forms, navigate pages) and say what you are doing as you go ("click here, then type the name") - Click Finish, give the recording a name, and it saves - Select the recording in chat to give the AI the perfect example ## Dramatic Success Boost Providing a recording demonstration dramatically increases task completion rates. For complex multi-step forms and interactions that are hard to describe in words, a recording often outperforms even the most detailed prompt. Record once, use forever. > **success**: Recordings often work better than detailed prompts for complex interactions: especially forms with unusual layouts, multi-step wizards, or sites with non-standard UI components. ## From Recording to Subroutine Because the recorder sees the page's own XHR/fetch traffic, it can do more than mimic your clicks. The AI Tool Generator reads the captured calls and compiles the flow into an AI Subroutine: a saved, callable tool that hits the underlying endpoint directly. Once generated it is deterministic code: no model call, and no tokens, per run. See [AI Tool Generator](/docs/tool-calling#ai-tool-generator) and the writeup on [zero-token deterministic automation](/blog/ai-subroutines-zero-token-deterministic-automation). Watch [a recording become a reusable Subroutine](https://www.youtube.com/watch?v=apfR41ru7kY), then follow the four steps below. - Record the task once: click through the flow you want automated - Open the recording and generate a tool from it - The generator ranks the captured calls, picks the one that actually carries the data, and writes a runner for it - Save it, then call it with `@toolName`, from workflows, schedules, and triggers, or over the hosted MCP server > **info**: One-sentence version: type "build me a tool that …" in the side panel chat. The agent runs those four steps itself (record, generate, save, verify with a real call), and its reply names the saved tool, what it returns, how to call it (`@toolName` in chat, `user_` over the MCP server and API) and, if you asked for a cadence, the schedule it created. Add "and run it daily at 8am" or "and make it callable from Zapier" to the same sentence. When the tool needs you signed in to the site, the agent also makes it cloud-ready in the same run: it asks once whether to sync that site's login to your cloud browser, so the scheduled or API-triggered runs work with Chrome closed. Decline and the tool still gets built: the agent just tells you those runs will need this browser open. Both questions (sign in, sync) come up before anything is saved, so answering them never builds a second copy of the tool or a duplicate schedule. > **info**: Saved subroutines are exposed as callable tools on the hosted MCP server at `mcp.rtrvr.ai`, so Claude, Codex, or any MCP client can invoke a discovered endpoint by name, no DOM scraping in the loop. ### How the Generator Picks a Strategy Not every endpoint is safe to call directly. rtrvr.ai classifies each captured request by the auth evidence in its headers, then chooses where the request runs and whether it is replayed at all. Requests that carry a client-computed signature are never forged. | Evidence in the captured request | Where it runs | Strategy | | --- | --- | --- | | No auth headers (public/stateless) | Background worker | Replay | | `authorization` only, no cookie or CSRF | Background worker, captured bearer forwarded | Replay | | `cookie` present | Main world of a real tab on that origin, `credentials: include` | Replay | | `x-csrf-token` / `x-xsrf-token` | Source tab first, so the app's current token is used | Replay | | Same-site request with no explicit auth header (ambient session) | Main world of a real tab | Replay | | Client signature (`x-client-transaction-id`, `x-request-signature`, `x-signature`, `x-bogus`, `x-gorgon`, `x-khronos`) | Source tab: request is never reconstructed | Harvest | Replay means the subroutine issues the request itself. Harvest means it lets the page issue its own signed calls and intercepts the responses, then transforms them. Either way you get the JSON: harvest just refuses to forge a signature it cannot legitimately compute. ### Does Auth Survive the Tab Closing? Yes for session-backed endpoints, but not by storing your session. Cookies are never replayed as a literal header: `cookie` and `set-cookie` are stripped from every generated request template. Instead, a cookie- or session-backed subroutine executes inside a real logged-in page: the runtime opens or reuses a tab on that origin and issues the request with credentials, so the browser attaches the current cookies itself. - The subroutine stays callable after you close the tab, because invoking it opens one. What it depends on is the session, not the tab. - If you are logged out, it fails the way a logged-out user would: there is no stored credential to fall back on. - Bearer tokens and API keys captured in the recording are replayed verbatim from a background worker with no tab at all, but only while that token is valid. When it rotates or expires, regenerate the tool or re-record. - In Cloud, add a saved password, sync from Chrome, or sign in during a task. See [Secure logins](/docs/cookie-sync) for setup and session reuse. - Secrets are redacted at the prompt boundary: the model that writes your tool sees `[REDACTED:x-api-key]`, never the value. The runtime substitutes the real captured header at call time, and captured values always win over anything the model wrote. ### Signed, CSRF, and HMAC'd Parameters CSRF is handled rather than replayed. A stale `x-csrf-token` copied out of a recording would 403 on the next run, so requests carrying one are executed in the source tab where the application's own current token applies. The same holds for double-submit and same-site session patterns. Client-signed and HMAC'd requests are deliberately not replayed. When a captured request carries a signature the client computed (Twitter/X transaction IDs, TikTok's `x-bogus` / `x-gorgon` / `x-khronos`, or a generic `x-request-signature`), replay is prohibited and the generator falls back to harvest. Forging those would break the moment the site rotates its signing algorithm; harvesting the page's own responses does not. Every replay is validated before it is trusted. A `401`, `403`, `407`, `419`, or `440`, a login interstitial, or unexpected HTML where JSON was expected marks the attempt failed and retries it inside the source tab: rather than quietly handing you a login page as if it were data. > **warning**: Rule of thumb: stable first-party JSON APIs replay well and run essentially free. Hashed GraphQL persisted-query IDs and rotating signature schemes drift: prefer a DOM-grounded subroutine or harvest there, and re-record when a site changes its API. ### If a Token or ID Is Invalid First note when the error appears. If generation fails before a draft tool opens, refresh your rtrvr sign-in. If the draft saves but its first run fails, the target site may require a current session, token, or request ID that the generated Subroutine did not carry correctly. Allowing cookies helps only when that site actually uses cookies for authentication. - Confirm the extension and Cloud dashboard are signed in to the same rtrvr account. A Workspace shares credits; it does not merge member sign-ins, target-site sessions, Google connections, or recording libraries - Open the target site in a normal Chrome tab, sign in again, reload it, and complete the action once by hand - Make a new recording from that fresh session, generate a new Subroutine, and test it on one item before adding it to a larger workflow - For a Cloud run, sync cookies only after the fresh sign-in so the cloud browser receives the current session - If the same error returns, stop retrying and send support the exact error text, the run link, the recording or Subroutine name, the target site's domain, and the email used for the Workspace. A repeatable failure may be in the generated request rather than your login. Never send a password, cookie, API key, or token > **info**: One retry is enough to separate an expired session from a repeatable product error. If it fails again, keep the run and send its link to support so we can trace the failing step. ## Cross-Platform Reuse Recordings are a shared primitive: they're created in the extension but reusable across every rtrvr.ai surface. When you use a recording in a workflow, that recording is automatically bundled with the workflow artifact. | Surface | How Recordings Are Used | | --- | --- | | Replay | Recording is included automatically: the agent follows the same steps | | Shortcuts | Recording is bundled with the shortcut for perfect execution every time | | Schedules | Scheduled runs include the recording, no drift over time | | Triggers | Triggered workflows carry the recording for consistent execution | | Cloud | Attach a recording to a cloud run from the composer's Recordings picker, or export a workflow: the recording travels with it for headless execution | | API (replay_workflow) | Replay a workflow by ID: recording is resolved server-side | ## Management & Sharing Recordings sync across your devices when logged in. You can organize, share them via URL with teammates, or import recordings from others. - View all recordings from the Recordings section in the side panel, or from the Recordings panel in the Cloud dashboard: each recording there has a "Use in a run" action that preselects it in the composer - Share via URL: recipients can import with one click - Recordings bundle with workflows when shared, so teammates get the full context ## Platform Availability | Capability | Extension | Cloud | API | | --- | --- | --- | --- | | Create recordings | ✅ | No | No | | Capture page network calls while recording | ✅ | No | No | | Use recordings in workflows | ✅ | ✅ | ✅ | | Generate subroutines from a recording | ✅ | ✅ | No | | Call a generated subroutine | ✅ | ✅ | ✅ | | Share recordings via URL | ✅ | ✅ | ✅ | | Auto-bundle with shortcuts | ✅ | ✅ | ✅ | | Sync across devices | ✅ | ✅ | No | --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Tool Calling Extend your agent with MCP servers, AI Subroutines, custom JavaScript functions, and recording-grounded integrations: shared across extension, cloud, and API. # Tool Calling [Video: Tool Calling Overview](https://www.youtube.com/watch?v=cQN-4kJkjUQ) rtrvr.ai agents aren't limited to browsing. They can call external APIs, query databases, and run custom logic using the Model Context Protocol (MCP) or secure JavaScript tools. Tools are a shared primitive: create them once, use them across the extension, cloud, and API. ## AI Subroutines AI Subroutines are reusable tools generated by rtrvr.ai from natural-language intent, recordings, API docs, or the current webpage context. They are ideal when you want a stable capability such as “send a LinkedIn DM”, “create a HubSpot contact”, or “submit this internal form” without rebuilding the workflow each time. - Generate a subroutine from a natural-language request - Generate a subroutine from a recording to capture a real interaction flow - Point the generator at API docs or an authenticated webpage and let it infer the tool shape - Save the resulting tool once and reuse it from chats, workflows, schedules, and API-triggered runs Every saved tool has an on/off switch in the Tools list (Cloud → Tools, or the Tools panel in the extension). A tool switched off there is off for the agent in the extension and in cloud runs alike: the agent isn't shown the tool and doesn't call it. Switch it back on to use it again. ## Direct Tool Calls When you know exactly which tool to use, bypass the AI planner with the @toolName syntax. This is highly efficient for repetitive tasks and gives you direct control. ```text @act(action="click submit") → Direct browser action @extractToSheets(prompt="get emails") → Fast extraction across open tabs @hubspot_lookup(email="user@example.com") → Call a custom/MCP tool directly ``` ## MCP Servers Connect to any Model Context Protocol server by pasting its URL. Once connected, all MCP tools become available in your chat with @toolname syntax. rtrvr.ai supports SSE (Server-Sent Events), HTTP Streamable, and OAuth-protected servers. - Open the Tools section in extension settings - Paste the MCP server URL (e.g., your company's internal MCP, or a public one) - Authenticate if required (OAuth flow handled in-browser) - All server tools appear instantly: use them with @toolname in chat Or ask for it in chat: "connect my Zapier MCP", "add this MCP server: https://…" or "connect this MCP server" while its URL is on the page. The agent connects it natively: a built-in connector (Zapier, Notion, Slack, GitHub, HubSpot, Gmail) needs no URL; a custom URL or an API-key header pauses once for your confirmation in the panel; OAuth sign-in opens in a browser window. Imported tools are saved as `.` and start switched off so your tool list stays small: say which ones to enable ("enable all of them" / "enable the read actions") or flip them in the Tools panel, which the agent opens for you. "Which MCP servers do I have?" is answered from the same place. > **warning**: OAuth-protected servers require periodic reauthentication. You can manage sessions in the extension settings or via the cloud dashboard. ## AI Tool Generator Don't have an MCP server? The Tool Generator sub-agent can create AI Subroutines automatically. Just describe what you need in plain English, or better yet, point the agent at an API documentation page, an authenticated web app, or a recording and let it build the tool for you. ```text "Find my HubSpot API keys and create a tool to load contacts" "Use this onscreen API docs to create a tool that searches our internal database" "Create a tool that calls the OpenWeatherMap API with a city name and returns the forecast" "Turn this LinkedIn recording into an AI Subroutine that opens Message, writes a DM, and sends it" ``` > **success**: Tools created in the Chrome Extension can be saved and reused in the Cloud environment. They travel with shared workflows. ### Create a Subroutine From a Recording Recordings are one of the fastest ways to create robust AI Subroutines. rtrvr.ai analyzes the DOM interactions and nearby network traffic, then chooses the best replay strategy: semantic DOM automation when the UI flow is the stable source of truth, or network-backed execution when the captured request is clearly first-party and reusable. - Record the task once in the extension - Open the recording and choose to generate a tool/subroutine - The generator uses the recording as grounding context for buttons, composers, waits, and API shape - Save the generated tool and call it directly with @toolName or from workflows > **warning**: For volatile sites, DOM-grounded subroutines are usually safer than replaying internal GraphQL or hashed API endpoints. Recordings help the generator decide which path is actually stable. Recordings capture the page's own XHR/fetch traffic (headers, bodies, and status), which is what makes network-backed subroutines possible. For how auth is handled after the tab closes, and how CSRF and client-signed requests are treated, see [From Recording to Subroutine](/docs/recordings#from-recording-to-subroutine). ## Custom JavaScript Tools Write your own tools in JavaScript or let the AI build them. Subroutines can run as sandboxed JavaScript tools or as webpage tools that execute in the authenticated browser context. Parameters and defaults are available in the selected execution environment, including the Cloud runtime when you run a saved tool in Cloud. ### Two Execution Styles | Style | Best For | Runtime Implications | | --- | --- | --- | | Sandbox tool | Pure computation, public APIs, data transforms, authenticated API calls, and Sheets helpers | Runs in an isolated JavaScript runtime in the extension or Cloud. It can use parameters, defaults, `fetch`, and `rtrvr.*` agent helpers, but it does not read the live page's `document`, `window`, `localStorage`, or application JavaScript state. Cloud helpers use the run's connected Google account. | | Webpage tool / AI Subroutine | Logged-in websites, DOM actions, page cookies, in-page fetch, rich editors, CSRF-protected requests | Opens or reuses a browser tab, waits for load plus any settle delay, injects the runtime, then runs in the authenticated page context with page `window`, `document`, cookies, localStorage, in-page fetch/XHR, and webpage `rtrvr` helpers. | > **info**: Default to sandbox unless the tool needs the live page. A tool that only reads or writes Sheets through `rtrvr.*` helpers should use `executionMode: "sandbox"`; it does not need a webpage URL. Choose webpage when the result depends on browser session state, client-side rendering, DOM interaction, page cookies, localStorage, CSRF tokens, or the app's own JavaScript runtime. ### Webpage URLs and Parameters Webpage tools need a page to run inside. Save at least one `defaultUrls` entry or declare a `url` or `urls` parameter that callers will supply. At call time, URL selection uses this priority: `urls` parameter first, then `url`, then the saved `defaultUrls`. The runtime deduplicates the chosen URLs, opens each page, waits for load, applies `pageExecution.settleMs`, and injects `url`, `urls`, and `tabId` into your code. - `defaultUrls` can contain static URLs, one URL per entry. - Use simple `${paramName}` placeholders when the destination depends on a parameter. - Only simple placeholders are supported. Do not use expressions like `${handle.replace('@', '')}`, ternaries, or nested paths. - If a placeholder is unresolved, execution fails during URL resolution before opening a tab. - If the parameter is a full URL, make it the whole template: `${profileUrl}`. If it is an ID or handle, build the URL around it: `https://x.com/${handle}`. ```javascript // Static page target defaultUrls: ["https://news.ycombinator.com/news"] // Identifier parameter: the runtime opens https://x.com/rtrvr_ai parameters: { handle: { type: "string", description: "X handle without normalization expressions" }, } defaultUrls: ["https://x.com/${handle}"] // Full URL parameter: use the parameter as the whole template parameters: { profileUrl: { type: "string", description: "Complete profile URL" }, } defaultUrls: ["${profileUrl}"] ``` `pageExecution.settleMs` controls the extra wait after the tab reports loaded. Leave it blank to use the runtime default of `1500` ms, set it to `0` to skip the extra wait, or increase it when a single-page app needs more time to render client-side content. ```javascript executionMode: "webpage", defaultUrls: ["https://app.example.com/orders/${orderId}"], pageExecution: { settleMs: 2500, }, code: ` const title = document.querySelector("h1")?.textContent?.trim(); return { url, urls, tabId, title }; ` ``` ### How Parameters Work When you define parameters for a custom function, the runtime makes them available as JavaScript variables in your code. Reference each parameter by its declared name. ```javascript // Parameters defined: firstName (string), lastName (string), apiKey (string, default) // Your code can reference the declared parameters directly: const res = await fetch(`https://api.example.com/users?name=${firstName}+${lastName}`, { headers: { "Authorization": `Bearer ${apiKey}` } }); const data = await res.json(); return data.results; ``` - Define parameters with names, types, and optional defaults - Reference parameters directly as variables (firstName, not params.firstName) - The runtime binds parameter values before your code runs - Return any JSON-serializable value: async/await is fully supported - console.log() output is captured and shown in results for debugging > **info**: Default parameters are part of the saved tool configuration. Values needed by a Cloud tool run are available to the Cloud runtime; storing an API key as a default does not make it local-only. Google Sheets helpers use the connected Google account, so those tools do not need an API key parameter. ### Code Examples ```javascript // Simple greeting return `Hello ${firstName} ${lastName}!`; // Math return price * quantity * (1 + taxRate); // API call const r = await fetch(url); return await r.json(); // Transform return items.map(i => i.name).join(", "); ``` Parameter names must be valid JavaScript identifiers (letters, numbers, underscores, no spaces). ### Webpage Helper Functions (`rtrvr`) Webpage tools and AI Subroutines can use the built-in `rtrvr` helper namespace to interact with the live page without dropping down to brittle manual DOM code. These helpers are especially useful for authenticated flows, contenteditable editors, CSRF-protected requests, and waiting for UI state transitions. | Helper | Use | | --- | --- | | `rtrvr.find({ role, name, text, placeholder })` | Find a semantic page target and return an opaque handle | | `rtrvr.click(handleOrTarget)` | Click a previously found handle or a semantic target | | `rtrvr.type(handleOrTarget, value, { clear, submit })` | Type into inputs or rich contenteditable editors | | `rtrvr.waitFor(targetOrFn, { timeoutMs })` | Wait for the next UI state, modal, composer, or control | | `rtrvr.waitForUrl(match, { timeoutMs })` | Wait for navigation or route changes | | `rtrvr.request(url, init)` | Make authenticated in-page requests using the page context | | `rtrvr.requestJson(url, init)` | Same as request, but parses JSON when available | | `rtrvr.getCsrfToken()` | Read the current page CSRF token for sites that require it | | `rtrvr.getCookie(name)` | Read a cookie value from the current page | | `rtrvr.getPageAuthToken({ forceRefresh })` | Read the signed-in user's live API token when the site keeps its login in an auth SDK (Firebase Auth) rather than a cookie; returns `{ token, provider, expiresAt, refreshed }` or `null`. Send `token` in the `authorization` header exactly as the site's own requests do | ```javascript // Example webpage tool body const button = await rtrvr.find({ role: "button", name: /Connect/i, }); if (!button) { return { success: false, error: "Connect button not found." }; } await rtrvr.click(button); const csrfToken = rtrvr.getCsrfToken(); return await rtrvr.requestJson("/voyager/api/example", { method: "POST", headers: { "content-type": "application/json", "x-csrf-token": csrfToken, }, body: JSON.stringify({ ok: true }), }); ``` ### Agent Capabilities (`rtrvr.*` built-ins) Both sandbox and webpage tools can call the agent's internal capabilities through the `rtrvr` namespace. These helpers share names and parameter shapes with the rtrvr MCP (for example `get_page_data`, `take_page_action`, `list_skills`), so code written against the MCP translates directly inline. They reuse the user's existing Google auth and credit allowance: don't hand-roll OAuth or tree parsing yourself. > **info**: Complete built-in surface: `getPageTree`, `pageAction`, `listTabs`, `createSheet`, `appendRow`, `appendColumn`, `readSheet`, `updateRange`, `readFile`, `searchFile`, `readSkill`, `saveSkill`, `createTool`, `customToolGenerator`, `listRecordings`, `startRecording`, `finishRecording`, `act`, `extract`, and `processText`. Tool-composition helpers are documented below: `callTool`, `listTools`, and `invokeBuiltin`. #### Page data & actions | Helper | Returns / Effect | | --- | --- | | `await rtrvr.getPageTree({ tabId?, onlyTextContent?, disableAutoScroll?, stripMarkers? })` | `{ tabId, url, title, tree, links, elementLinkRecord, metadata }`. `tree` marks each interactive element `[id=N]` and never prints a link's URL: read URLs from `links` (`{ id, name, url, role }[]`) or `elementLinkRecord` (`{ [id]: url }`) by that id. `stripMarkers: true` returns the tree text without markers; `links` keep every URL. | | `await rtrvr.pageAction({ tool, args, tabId? })` | Run a single system tool on a tab; mirrors MCP `take_page_action` | | `await rtrvr.listTabs()` | List browser tabs as `{ tabId, url, title, active, windowId }[]` | Supported `pageAction` tools include: `click_element`, `type_into_element`, `type_and_enter`, `select_dropdown_value`, `clear_element`, `focus_element`, `hover_element`, `right_click_element`, `double_click_element`, `press_key`, `scroll_page`, `scroll_to_element`, `drag_element`, `drag_and_drop`, `adjust_slider`, `goto_url`, `go_back`, `go_forward`, `refresh_page`, `open_new_tab`, `switch_tab`, `close_tab`, `google_search`, `describe_images`, `discover_and_extract_network_data`, `copy_text`, `paste_text`, `upload_file`, `wait_action`, `wait_for_element`, `solve_captcha`. See Browser Tools for argument schemas. #### Google Sheets | Helper | Returns / Effect | | --- | --- | | `await rtrvr.createSheet({ title, tabTitle?, headers? })` | Creates a spreadsheet in the user's Drive. Returns `{ sheetId, sheetTab, sheetUrl }`. | | `await rtrvr.appendRow({ sheetId, sheetTab?, values?, rows?, valueInputOption? })` | Append one row (`values`) or many rows (`rows`). Supply one of these arrays and batch related rows into one call. Set `valueInputOption: "RAW"` to preserve extracted text. Returns `{ appended, updatedRange, updatedRows, updatedCells }` for a Google write; check `localFallback` before reporting delivery. | | `await rtrvr.appendColumn({ sheetId, sheetTab?, values, header?, valueInputOption? })` | Append a new rightmost column. With `header`, the Nth value aligns with the Nth existing data row; without it, the first value lands in the header row. Read the sheet and map its rows in their existing order. Supports `RAW` and `USER_ENTERED`. Returns `{ appended, column, updatedRange, updatedRows, updatedCells }` for a Google write. | | `await rtrvr.readSheet({ sheetId, range? })` | Read an A1 range. Returns `{ range, rows }`. | | `await rtrvr.updateRange({ sheetId, range, rows, sheetTab?, allowFormulas?, clear? })` | Update EXISTING cells in place by A1 range (e.g. `"D2:D16"`, or `"B2"` for one cell); `rows` is an array of row arrays covering the range. Strings starting with `=` `+` `-` `@` are written as literal text (formula-injection guard) unless `allowFormulas: true`. Pass `clear: true` INSTEAD of `rows` to blank the range's values (rows/columns are not structurally deleted). Returns `{ updated, updatedRange, updatedRows, updatedCells, nonEmptyValues }`, or `{ cleared, clearedRange }` for a clear. The way to CHANGE values already in a sheet: never retype cells through the Sheets UI. | Use the actual tab name returned by `createSheet` or selected in the destination settings. Do not translate it or assume it is called Sheet1. Helpers quote tab names for you; when passing an A1 `range`, quote the tab name and double embedded apostrophes, for example `'L''équipe !'!A1:C10`. See Google's [A1 notation guide](https://developers.google.com/workspace/sheets/api/guides/concepts). `RAW` preserves strings such as `00123`, `01/10/2026`, and `1,25` without converting them to dates or numbers. `USER_ENTERED` lets Google parse values using the spreadsheet's settings and can interpret formulas. Existing helpers default to `USER_ENTERED`; Cloud appends to a forced destination default to `RAW`. Set the option explicitly in reusable tools. For intentional formula updates, use `updateRange` with `allowFormulas: true`. See Google's [value input rules](https://developers.google.com/workspace/sheets/api/reference/rest/v4/ValueInputOption). > **info**: The `valueInputOption` append argument requires an extension release that supports it. Older extensions ignore the argument and keep their existing `USER_ENTERED` behavior. Use the updated extension or Cloud when exact text preservation matters. Report a Sheets write only when `localFallback !== true`, `updatedRange` is present, and `updatedCells` is positive. Keep the real returned counts; do not substitute the number of input rows. A timeout or lost response can happen after Google writes the data, so inspect the destination before repeating an append. #### Attached files (full text) | Helper | Returns / Effect | | --- | --- | | `await rtrvr.readFile({ fileIndex, offset?, limit? })` | A slice of an attached file's COMPLETE text, re-extracted from the original upload (docx/xlsx/pptx/pdf/csv/json/txt; files up to 25 MB). Returns `{ text, totalChars, offset, returnedChars, hasMore, nextOffset }`; `limit` ≤ 20,000 chars (default 10,000): page with `offset: nextOffset`. The prompt inlines at most 100,000 chars of a file and ends a cut one with a `[truncated: showing X of Y characters …]` marker; this is how the rest is read. Free, no LLM call. | | `await rtrvr.searchFile({ fileIndex, query, regex?, caseSensitive?, maxMatches?, contextChars? })` | Keyword or regex search over that same complete text (files up to 25 MB). Returns `{ matches: [{ offset, match, line, context }], totalMatches, truncated }` (≤25 matches); seek with `readFile({ fileIndex, offset: match.offset })` instead of paging. Free. | #### User skills (persistent memory) | Helper | Returns / Effect | | --- | --- | | `await rtrvr.readSkill({ name })` | Read one skill file's full markdown as a file-shaped object (`extractedText`). Mirrors MCP `get_skill`. | | `await rtrvr.saveSkill({ name, description?, content })` | Create or replace a skill file (content ≤16K chars). Mirrors the agent's review-pass memory writes. | #### Recordings & tool creation Use recordings when the agent needs an example of the real interaction path. `recordingId` is the convenient form; `recordingContext` is the lower-level backend field. Passing either one to `act`, `extract`, or `createTool` grounds that subroutine in the captured DOM and network context. | Helper | Returns / Effect | | --- | --- | | `await rtrvr.listRecordings()` | List recording metadata as `{ recordingId, recordingName, captureTimestamp }[]`; full recording payloads are not returned. | | `await rtrvr.startRecording({ name, tabId? })` | Start recording DOM interactions and network calls. Returns `{ recordingId, recordingName, state }`. | | `await rtrvr.finishRecording({ recordingId?, timeoutMs? })` | Stop the active recording and wait up to `timeoutMs` (default 15 seconds, maximum 60 seconds). To recover a finished upload, pass its `recordingId` on the originating Chrome device; this retries pending uploads without stopping another recording. Returns `uploadStatus: uploaded | pending | unconfirmed`, capture counts and warnings. Unconfirmed does not prove that an upload is pending. A recording with zero actions and zero network requests needs to be recorded again before tool generation. | | `await rtrvr.createTool({ userInput, tabIds?, recordingId?, recordingContext?, generationMode?, editContext? })` | Generate a custom webpage tool from a code plan. In connected Chrome, `save` persists it and `temp` executes it. In cloud code plans, omit `generationMode`: tools are registered for the current execution, restored on continuation of that execution, then executed explicitly with `callTool`. Webpage tools open their configured URLs in fresh tabs in that browser session; source tab IDs provide generation context. To keep using an existing tab, use page helpers or `act` on that tab. This helper is not part of the `act_on_tab` action loop. Do not call it recursively. | | `await rtrvr.customToolGenerator({ userInput, tabIds?, recordingId?, recordingContext?, generationMode?, editContext? })` | Alias for `createTool`, kept for explicit access to the generator. Prefer `createTool` for new tools; do not generate tools that call either helper recursively. | #### Agent sub-routines When deterministic helpers aren't enough, you can invoke the same planner-backed sub-agents the chat experience uses. These helpers mirror the rtrvr MCP `act_on_tab`, `extract_from_tab`, and `processText` endpoints. | Helper | Returns / Effect | | --- | --- | | `await rtrvr.act({ userInput, tabIds?, schema?, recordingId?, recordingContext? })` | Run the Act agent across one or more tabs (navigation, clicks, form fills), optionally grounded in a recording. Returns `{ data, warnings, creditsUsed }`. Mirrors MCP `act_on_tab`. | | `await rtrvr.extract({ userInput, tabIds?, schema?, recordingId?, recordingContext? })` | Structured extraction across tabs, optionally grounded in a recording. Returns `{ data, jsonData, warnings, creditsUsed }`. Mirrors MCP `extract_from_tab`. | | `await rtrvr.processText({ textInputs, taskInstruction, schema? })` | Summarize or transform text inputs via the LLM. Returns `{ data?, text?, warnings, creditsUsed }`. **Especially useful for parsing structured JSON out of unstructured strings**: pass any text blob plus a `schema` and the helper returns typed `data` matching it. | > **info**: `rtrvr.processText` is the right reach whenever you have raw text (an email, HTML excerpt, model response, chat transcript) and need fielded JSON. It runs no browser tab and no DOM extraction, just LLM-backed string-to-schema parsing, so it's faster and cheaper than `rtrvr.extract` for text-only inputs. > **info**: Agent sub-routine helpers burn credits the same way a chat invocation does. Prefer `rtrvr.pageAction` / `rtrvr.getPageTree` / `rtrvr.callTool` when the task is deterministic and doesn't need planning. ### Cloud Scrape at Scale (`rtrvr.scrape`) When a task needs to scrape *many* URLs (roughly 30+, and especially 100+) or hits sites that rate-limit or bot-block local access, `rtrvr.scrape` runs the whole list on rtrvr's cloud browsers behind rotating proxies instead of in the user's local browser. It chunks large lists into batches of 10 (the per-request cap) and fans them out with bounded concurrency, so a generated plan can hand it the full URL list in one call. The same proxy-backed infrastructure powers the standalone [Scrape API](/docs/scrape). | Helper | Returns / Effect | | --- | --- | | `await rtrvr.scrape({ urls, settings?, timeoutMs?, response?, concurrency?, batchSize? })` | Cloud-scrape an array of URLs of any length behind rotating proxies. Returns `{ tabs, tabCount, succeeded, failed, usageData, creditsUsed, summary }`, where each `tabs[]` entry is `{ url, title, status, content?, tree?, error? }` in input order. `tree` is the same accessibility-tree string `rtrvr.getPageTree` returns; pair it with `rtrvr.processText` for structured extraction. | > **warning**: `rtrvr.scrape` bills cloud browser + proxy **infra credits per URL**: far more than the FREE local `rtrvr.getPageTree` / `fetch`. Reach for it only when the volume is too high to run locally or local access is being blocked; for a handful of reachable URLs, loop `getPageTree` or `fetch` instead. ```javascript // Bulk-scrape 100+ URLs that would be rate-limited locally, then parse the results. const { tabs, succeeded, failed, creditsUsed } = await rtrvr.scrape({ urls: productUrls, // any length: chunked into batches of 10 automatically }); const rows = tabs .filter((t) => t.status === "success") .map((t) => [t.url, t.title ?? ""]); console.log(`Scraped ${succeeded}/${tabs.length} (${failed} failed) for ${creditsUsed} credits`); ``` ```javascript // Compose planner-backed sub-agents with deterministic helpers. const { data: leads } = await rtrvr.extract({ userInput: "Pull each visible lead's name, email, and company", schema: { type: "array", items: { type: "object", properties: { name: { type: "string" }, email: { type: "string" }, company: { type: "string" }, }, }, }, }); // processText shines for string -> JSON: pass raw text + a schema, get typed data. const rawEmailBody = await rtrvr.callTool("fetchInboundEmail", { id: emailId }); const { data: parsed } = await rtrvr.processText({ textInputs: [rawEmailBody.body], taskInstruction: "Extract the sender intent, requested meeting time, and any cited deal names.", schema: { type: "object", properties: { intent: { type: "string" }, requestedMeetingTime: { type: "string" }, dealNames: { type: "array", items: { type: "string" } }, }, required: ["intent"], }, }); if (!Array.isArray(leads) || !leads.length) return { count: 0 }; const { sheetId, sheetTab } = await rtrvr.createSheet({ title: "Lead outreach", headers: ["name", "email", "company", "intent", "deals"], }); const write = await rtrvr.appendRow({ sheetId, sheetTab, valueInputOption: "RAW", rows: leads.map(lead => [lead.name ?? "", lead.email ?? "", lead.company ?? "", parsed.intent ?? "", (parsed.dealNames || []).join(", ")]), }); if (write.localFallback === true || !write.updatedRange || !(write.updatedCells > 0)) { throw new Error("Google Sheets did not confirm the write. Keep the extracted leads and inspect the destination before retrying."); } return { sheetId, sheetTab, updatedRows: write.updatedRows, updatedCells: write.updatedCells, updatedRange: write.updatedRange }; ``` #### Tool composition A subroutine can call **any other tool the user has**: that includes user-authored custom tools and **every MCP server tool the user has connected**. The execution environment looks the tool up by name, dispatches MCP calls through the connected MCP client, and dispatches user tools through the same sandbox or webpage runtime that powers them in chat. There is no separate plumbing to wire up: connect a HubSpot MCP server once and `await rtrvr.callTool('hubspot.createContact', { email })` works inside any subroutine. When the tool generator builds a subroutine, the prompt is given the user's full tool list (custom + MCP, with parameter schemas and `[MCP]` / `[custom]` badges) so the LLM can wire calls correctly without you re-pasting the spec. Use `await rtrvr.listTools()` at runtime if you ever need to introspect what's available. | Helper | Returns / Effect | | --- | --- | | `await rtrvr.callTool(name, params)` | Call another custom tool or **MCP server tool** by name. Resolution: the runtime looks the tool up by name, validates `params` against its schema, and dispatches: MCP tools through the connected MCP client (e.g. HubSpot, Linear), user tools through the same sandbox/webpage runtime they use in chat. Returns the callee's raw result. | | `await rtrvr.listTools()` | List every tool the current user has available to `callTool` (both custom tools and MCP server tools), each with `{ name, description, parameters, source: 'custom' | 'mcp' | 'predefined' }`. | | `await rtrvr.invokeBuiltin(helper, args)` | Escape-hatch that invokes any builtin by name: equivalent to `rtrvr.(args)`. | > **info**: Recursive tool calls are allowed up to a safety depth (5) and guarded against cycles. Prefer composing existing tools over re-implementing logic: especially for repetitive auth flows, MCP-backed CRM/ticketing actions, and sheet writes. ```javascript // MCP + custom-tool composition in a single subroutine. // Assumes the user has connected the HubSpot MCP server and authored a custom // tool called `fetchInboundEmail`. Both surface as `rtrvr.callTool(name, params)` // without any extra glue. const email = await rtrvr.callTool("fetchInboundEmail", { id: emailId }); const { data: parsed } = await rtrvr.processText({ textInputs: [email.body], taskInstruction: "Extract sender intent and any cited deal names.", schema: { type: "object", properties: { intent: { type: "string" }, dealNames: { type: "array", items: { type: "string" } }, }, required: ["intent"], }, }); // Dispatched to the HubSpot MCP server by name — the runtime resolves it. const contact = await rtrvr.callTool("hubspot.createContact", { email: email.from, firstName: email.fromName?.split(" ")[0], lifecycleStage: parsed.intent === "demo_request" ? "lead" : "subscriber", }); return { contactId: contact.id, intent: parsed.intent, deals: parsed.dealNames }; ``` ```javascript // Capture the active tab's tree, write a row to a new sheet, and index in KB. const { tree, title, url } = await rtrvr.getPageTree({}); const { sheetId, sheetTab } = await rtrvr.createSheet({ title: "Page Snapshots", headers: ["url", "title", "capturedAt"], }); const write = await rtrvr.appendRow({ sheetId, sheetTab, valueInputOption: "RAW", values: [url, title, new Date().toISOString()], }); if (write.localFallback === true || !write.updatedRange || !(write.updatedCells > 0)) { throw new Error("Google Sheets did not confirm the snapshot write. Inspect the destination before retrying."); } // Remember what this tool learned for future runs const notes = await rtrvr.readSkill({ name: "page-snapshots" }).catch(() => null); await rtrvr.saveSkill({ name: "page-snapshots", description: "Where page snapshots are archived", content: (notes?.extractedText || "## Page snapshots") + ` Sheet: ${sheetId}`, }); return { sheetId, treeLength: tree.length }; ``` ```javascript // Drive the page via named system tools, no DOM code needed. await rtrvr.pageAction({ tool: "goto_url", args: { url: "https://example.com/orders" }, }); await rtrvr.pageAction({ tool: "wait_for_element", args: { text: "Order list" }, }); const { tree, elementLinkRecord } = await rtrvr.getPageTree({}); // Pick a link in the tree and follow it by element_id await rtrvr.pageAction({ tool: "click_element", args: { element_id: Object.keys(elementLinkRecord)[0] }, }); return { followed: true }; ``` ```javascript // Read a saved skill and use it to steer a summarization step. const playbook = await rtrvr.readSkill({ name: "onboarding-notes" }).catch(() => null); const { items } = await rtrvr.processText({ textInputs: [{ text: playbook?.extractedText || "" }], taskInstruction: "Summarize the latest onboarding changes in one paragraph", schema: { type: "object", properties: { summary: { type: "string" } } }, }); const { sheetId, sheetTab } = await rtrvr.createSheet({ title: "Skill digest", headers: ["question", "answer"], }); const write = await rtrvr.appendRow({ sheetId, sheetTab, valueInputOption: "RAW", values: ["Latest onboarding changes", items[0]?.summary || ""], }); if (write.localFallback === true || !write.updatedRange || !(write.updatedCells > 0)) { throw new Error("Google Sheets did not confirm the digest write. Inspect the destination before retrying."); } return { sheetId, answer: items[0]?.summary }; ``` ## Choosing DOM vs Network Tools The best AI Subroutines pick the right execution strategy for the site. In general: use DOM actions when the UI flow is the stable contract, and use network-backed execution when the request itself is the stable contract. | Prefer DOM Actions When... | Prefer Network Interaction When... | | --- | --- | | The site uses volatile internal APIs, rotating GraphQL IDs, or framework-specific hidden identifiers | You have a clear first-party endpoint with a stable request/response shape | | You need to click, type, open menus, wait for dialogs, or work inside rich editors | The action is fundamentally an API call and does not depend on visible UI state | | The only evidence you have is a recording of buttons, composers, and page transitions | You need structured JSON back and the site’s authenticated page context can safely make the request | - For DOM tools, prefer semantic targets such as role, accessible name, placeholder, and visible text - Use staged waits after each meaningful action: open dialog → wait for composer → type → wait for send button - Avoid brittle CSS selectors and volatile class names in generated tools - For network tools, prefer `rtrvr.request()` / `rtrvr.requestJson()` over copying full captured browser headers - Never hardcode cookies, bearer tokens, CSRF tokens, or volatile query/operation IDs from a recording - If the captured request carried an `authorization` header, cookies alone will not authenticate the replay: call `rtrvr.getPageAuthToken()` at runtime and treat a JSON body reporting `status: 401` as a failed call > **info**: A good rule of thumb: if a human would describe the task as “click this, wait for that, then type here,” generate a DOM subroutine. If they would describe it as “send this authenticated request and parse the JSON,” generate a network-backed tool. ## Sheets Tool Mapping In Sheets Workflows, the agent can map tool calls to run for every row: intelligently pulling arguments from specific columns. Just include instructions in your prompt: ```text "For each row, use the loadContact tool to upload the email in Column A and name in Column B to HubSpot" ``` | Column A (Email) | Column B (Name) | Column C (Result) | | --- | --- | --- | | user@example.com | Jane Doe | ✅ Contact created (ID: 12345) | | admin@test.org | John Smith | ✅ Contact created (ID: 12346) | ## Platform Availability | Capability | Extension | Cloud | API | | --- | --- | --- | --- | | @toolname direct calls | ✅ | No | No | | MCP server connections | ✅ | ✅ | ✅ | | AI Tool Generator | ✅ | ✅ | No | | Custom JavaScript tools | ✅ | ✅ | No | | Sheets tool mapping | ✅ | ✅ | ✅ | | Tools in replayed workflows | ✅ | ✅ | ✅ | --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Connectors Connect Google Drive and your other apps. Save results to Sheets, use app tools, and fix missing access. # Connectors Connect the apps a task needs, then ask rtrvr to use them. Google Drive lets you create Sheets and work with files you select. Other apps add tools for email, contacts, documents, and more. [Video: Connect Google Drive, Slack, Notion, and other apps](https://www.youtube.com/watch?v=TLCPT9Tl9Fw) Watch the [connection walkthrough](https://youtu.be/TLCPT9Tl9Fw). The video shows the earlier Settings layout; Cloud now has Connectors below Tools in the left navigation. ## Connect Google Drive - Open [Connectors in Cloud](/cloud?view=connectors), below Tools in the left navigation. - Find Google Drive and choose **Connect**. Choose **Reconnect** if it says Needs access. - Choose the Google account that owns the files you want to use. On Google’s permission screen, allow file access before continuing. - Return to Retriever and check that Drive says **Connected**. Use **Manage → Check connection** to check authorization. For a scheduled destination, select the file in **Schedules > Options > Update existing files** to check file access and available tabs without starting a paid run. > **info**: Signing in with Google and allowing Drive access are separate steps. You can be signed in to rtrvr while Drive still needs permission. ## Use Drive in the extension Open your profile at the bottom of the extension, then choose **Connectors**. Drive is at the top, with Connect or Reconnect when needed. The info button shows access details and a Check connection action. Apps you have already added appear below it; choose an app to view its tools. Choose **Browse apps** to open the full catalog in Cloud with the same rtrvr account. The extension keeps quick access close to your task; Cloud gives you more room to browse and set up apps. > **info**: If your extension still shows the earlier Connectors card, update it when the new release is available. You can use [Cloud Connectors](/cloud?view=connectors) now. Reconnecting in Cloud does not replace the extension’s separate Google permission; reconnect there too if a local task still needs access. ## Choose the files rtrvr can use Drive access is limited to files rtrvr creates and files you select for it. It does not give rtrvr permission to browse your whole Drive. For an existing Sheet, use the Google file picker in your task to add it. A pasted link alone may not grant file access. Cloud schedules use the saved Cloud Google connection and refresh access tokens on the server. They do not need an open Chrome session. A connected account still needs edit access to the selected file, and the configured tab must exist. See [scheduled Sheets setup and troubleshooting](/docs/schedules#save-scheduled-results-to-google-sheets). Learn how to [run a Sheets workflow](/docs/sheets-workflows) or read the [permission details](/docs/permissions-privacy). ## Add another app In Cloud Connectors, search for an app and select its row under **Available**. Follow its setup steps. The catalog includes Gmail, HubSpot, Notion, Slack, GitHub, and Zapier. Each app has its own connection; Drive access does not grant access to Gmail. Some apps open a sign-in window. Others need details from the app’s settings. If you have an MCP server URL, choose **Custom connector** and enter the connection details your provider gives you. Once added, the app appears under **Your apps**. Choose **View tools** to review, enable, refresh, or remove its tools. Cloud checks connections when you open this page and shows when it last checked. Choose **Manage** beside an app to reveal **Check connection**, **Reconnect**, and **View tools**. Briefly cached results avoid repeated requests; a successful check does not guarantee permission to every file or action. ## Connect more than one Gmail account In Cloud Connectors, choose **Manage** beside Gmail, then **Add account**, and pick the other account in Google’s window. Google shows its account picker only when more than one Google account is signed in to the browser, so if the account isn’t signed in, [sign it in to Google](https://accounts.google.com/AddSession) first. In the extension, choose **Gmail** again in the connect dialog, or ask the agent: “connect my other Gmail account”. Each account appears under **Your apps** with its address and gets its own tools: the first account keeps `gmail_mcp`, and each added one is named after its address, such as `gmail_jane_doe`. Say which inbox to use, for example “draft the reply from jane.doe@gmail.com”; with several accounts connected and none named, the agent asks. ## Fix a connection | What you see | What to do | | --- | --- | | Drive needs access | Reconnect and allow file access on Google’s permission screen. This can happen if you skipped the file-access checkbox the first time. | | Couldn’t check connection | Choose Manage, then Check connection in Cloud, or Retry in the extension. This checks again without opening consent. A temporary connection failure does not mean you removed access. | | Drive says Connected, but one Sheet returns 403 | Check that the selected Google account can open that Sheet, then add it through the file picker. Reconnecting does not change the Sheet’s owner or sharing settings. | | Cloud works, but the extension does not | Check Drive in the extension’s profile too. Google access can differ between the local extension and Cloud. | | Another app stopped working | Choose Manage beside the app in Cloud, then Check connection. If it needs access, choose Reconnect and complete its setup flow. | You can cancel a reconnect without removing an existing working connection. There is no need to sign out of rtrvr to try again. ## Use a website you're signed in to For tasks on Instagram or another signed-in website, [choose your Chrome browser in Routing](/docs/web-agent#run-in-your-chrome-or-in-cloud), or add that account to [Secure logins](/docs/cookie-sync) for Cloud tasks. Browser logins and app connections are separate: syncing a Google login does not grant Drive file access. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Skills Markdown skill files the agent reads on every task and updates as it learns: persistent, user-editable memory across the extension, cloud, and API. # Skills Skills are markdown files that act as the agent's persistent memory. The reserved `general` skill is always shared with the agent: put your standing preferences, context, and defaults there. Every other skill is listed to the agent by name and description; when one matches the task at hand (a site's quirks, a workflow recipe), the agent reads it before working, and on its final review pass it can save what it learned back with `rtrvr.saveSkill`. Skills are the only memory that survives a task. `vars` last one task, sheets hold one deliverable, recordings replay one flow: a skill is what the agent still knows next week. ## What a skill file looks like A skill is plain markdown with optional YAML-style frontmatter. Write it however you like (headings, bullets, code blocks); the agent reads the raw text. `name` and `description` are the only special fields, and both are optional when you create a skill in the UI. ```markdown --- name: linkedin-outreach description: How I run LinkedIn connection + follow-up campaigns, and LI's UI quirks. --- ## Rules - Never send more than 20 invites per day. - Always personalize the note with the prospect's most recent post. ## Site quirks - The "Connect" button is behind the "More" overflow menu on most profiles. - The invite-note modal caps at 300 characters and silently truncates. ## Output - One row per prospect: name, headline, profile URL, note sent, date. ``` Uploading a `.md` file with that frontmatter creates the skill with the right name and description; without frontmatter the file name becomes the skill name. A skill's id is the slugified name, so saving `LinkedIn Outreach` again updates `linkedin-outreach` rather than creating a duplicate. ## The general skill `general` is reserved: it is injected into every task in full, so it is the right home for anything that is true across all your work. It is created for you automatically with a short starter template: three sections to fill in: - **About me**: role, company, the sites and tools you work in. Lets the agent resolve "our CRM" or "the usual sheet" without asking. - **Preferences**: standing defaults such as sheet vs. summary output, tone, language, units, timezone, sources to prefer or avoid. - **Notes the agent has learned**: where the agent appends what it picks up on its review pass. Edit or delete anything there; it is your file. > **info**: Keep `general` short and durable. It is re-sent on every pass of every task, so a bloated general skill costs tokens on work that will never use it: move anything site-specific or workflow-specific into its own named skill. ## Managing skills - **Extension:** the Skills dropdown in the composer lists your skills: click one (or type `/name`) to attach it in full to the next task, upload `.md` files, and jump to the web editor with the pencil or by typing a new name + Enter. - **Cloud:** [rtrvr.ai/cloud?view=skills](/cloud?view=skills) is the full library and the editor: live markdown preview, upload or drag-and-drop `.md` files, and per-skill delete. - **Agent-written updates** are marked `agent` in both UIs, so you can always see and revise what the agent taught itself. Storage is local-first in the extension (skills work offline) and mirrors to your account as one file per skill, newest-write-wins. Edit on the web and the extension picks it up on its next sync; let the agent save one mid-task and it is on the web dashboard immediately. ## Attaching a skill to one task Named skills are normally summoned by the agent on demand. When you want to guarantee one is applied, attach it: attached skills are injected in full, at the same authority as `general`, for that task only: - Click the skill's row in the Skills dropdown: it shows an `attached` badge and a pill above the composer. Click again to detach. - Type `/skill-name` in the composer. Sending `/linkedin-outreach` alone just attaches it; `/linkedin-outreach find 20 prospects` attaches it and runs the task. - Shortcuts win `/name` collisions: if a shortcut and a skill share a name, the shortcut runs. Rename one to disambiguate. ## How the agent sees your skills Your skills are snapshotted once per message and rendered into the task context like this: the general skill and any attached skills in full, everything else as a one-line listing: ```text === User Skills === --- Skill: general (always applied) --- ## Preferences Default to a Google Sheet for anything over 10 rows. --- End skill --- --- Skill: linkedin-outreach (attached by the user for THIS task: apply it) --- ## Rules Never send more than 20 invites per day. --- End skill --- Other skills (read on demand with rtrvr.readSkill({ name })): - hubspot-sync: How our HubSpot deal stages map to the pipeline sheet. - expense-report: Monthly expense report format and the receipts folder. ``` > **warning**: That listing is how the agent decides what to read, so the description is the retrieval key, not the file body. "Notes" retrieves nothing; "How our HubSpot deal stages map to the pipeline sheet" retrieves on any HubSpot or pipeline task. ## How the agent uses skills - `await rtrvr.readSkill({ name })`: read one skill's full markdown (free, no LLM call). The result is file-shaped, so plans can hand it to sub-agents via `fileInputs`. - `await rtrvr.saveSkill({ name, description?, content })`: create or replace a skill (content ≤16K chars). The agent is taught to fold the smallest durable edit into the existing markdown, never secrets or one-off task data. Saves REPLACE the whole file, so the agent is instructed to `readSkill` first and merge. It writes on the review pass (the same script that finishes the task), and only when something durable was learned: a fact you stated about yourself or your setup, a corrected preference, a site quirk that cost a repair pass, a recipe you refined. Most tasks teach nothing durable and save nothing. It also decides WHERE the note goes: facts about you and how you work (your role, company, the accounts and sheets you name, a standing format or tone choice) go into `general`; knowledge scoped to one site, tool, or recurring workflow goes into its own named skill: created on the spot when nothing fits, named `-` like `linkedin-outreach` or `hubspot-sync`. You will see new skills appear in the library marked `agent`. ```javascript // The agent's own write-back pattern, in the final plan script. const existing = await rtrvr.readSkill({ name: "linkedin-outreach" }).catch(() => null); await rtrvr.saveSkill({ name: "linkedin-outreach", description: "How I run LinkedIn outreach, and LI's UI quirks.", content: `${existing?.extractedText ?? "## Site quirks"} - Invite modal caps notes at 300 chars.`, }); return rtrvr.done({ summary: "Sent 20 invites; noted the 300-char cap." }); ``` > **warning**: Skills are memory, not storage. The agent will not write task output, page dumps, credentials, tokens, or sensitive personal data into a skill: deliverables belong in sheets and artifacts. ## Limits | Limit | Value | Notes | | --- | --- | --- | | Skill name | 64 characters | Slugified into the skill's id | | Description | 256 characters | The retrieval key: make it a concrete one-liner | | Content | 16,384 characters | Roughly 4K tokens of markdown per skill | | Skills per account | 100 | Delete unused skills to make room | | Injected block | 64,000 characters | General + attached skills + the listing, per task | ## Skills vs. the other memory | Use | When | Lifetime | | --- | --- | --- | | Skill | Knowledge that should change how FUTURE tasks run | Permanent, across tasks | | Shortcut | A task you re-run with the same steps on demand | Permanent, replayed verbatim | | Recording | Grounding the agent in an exact DOM flow you demonstrated | Permanent, per flow | | `vars` | Expensive intermediates reused by the next pass | One task | | Sheet / artifact | The deliverable itself | One deliverable | ## Getting reliable retrieval - **Write descriptions for matching, not for humans.** Name the sites, tools, and nouns a matching task would mention. - **One skill per topic.** A single 16K "everything" file is listed with one description and matches almost nothing; five focused skills each match their own tasks. - **Attach it when it must apply.** Retrieval is a judgment call the model makes: `/skill-name` removes the judgment and injects the file in full. - **Put cross-cutting rules in `general`.** It is the only skill that never depends on retrieval. - **Smaller models retrieve less.** Lightweight models (Inkling Small, MiMo, Flash-class) follow instructions that are in front of them but summon fewer optional resources on their own. Attach the skill explicitly (or run those tasks on a larger model), and keep `general` tight so the rules that matter are always in context. ## MCP access Skills are exposed on the rtrvr MCP server both as tools (`list_skills`, `get_skill`) and as MCP resources (`rtrvr-skill://{id}`, `text/markdown`), so Claude, Cursor, or any MCP client can read the same memory your agent uses. Cloud-only: no extension session required. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Enrichment Datasets Append external data to your sheets and extractions using Bright Data marketplace datasets: LinkedIn, Crunchbase, Instagram, Amazon, Zillow, Indeed, and Google Maps. # Enrichment Datasets Purchased contact and company data use credits separately from Free Mode. Check the lookup cost before enriching a large list. For website research without a paid lookup, start with public company pages. [Compare plans](/pricing#free-mode). rtrvr Enrich appends external data to your extracted results and sheets by matching them against [Bright Data's dataset marketplace](https://brightdata.com/products/datasets): LinkedIn people and companies, Crunchbase, Instagram, Amazon, Zillow, Indeed, and Google Maps. It runs inside a code plan via the `rtrvr.enrich(...)` helper. Your first 1,000 enrich records and web searches each month are free (one shared allowance), and anything beyond that bills automatically in credits at cost, no approval prompts. > **info**: Enable rtrvr Enrich under Settings → Labs to use it. Discovering datasets and inspecting their fields is always free and never counts against your allowance, only returned lookup records and successful scrape records do. ## Available Datasets Reference a dataset in a plan with the `rtrvr.datasets` constants (e.g. `rtrvr.datasets.linkedinPeople`). The links below open each dataset's page in the Bright Data marketplace. | Dataset | `rtrvr.datasets` key | Modes | | --- | --- | --- | | [LinkedIn people profiles](https://brightdata.com/products/datasets/linkedin/profiles) | `linkedinPeople` | Instant lookup + Live scrape | | [LinkedIn people + business contact info (emails)](https://brightdata.com/products/datasets/linkedin/profiles) | `linkedinPeopleContact` | Instant lookup only (a live scrape on it is served by `linkedinPeople`: profile fields, no email/phone) | | [LinkedIn company information](https://brightdata.com/products/datasets/linkedin/company) | `linkedinCompanies` | Instant lookup + Live scrape | | [Crunchbase companies](https://brightdata.com/products/datasets/crunchbase) | `crunchbaseCompanies` | Live scrape only | | [Instagram profiles](https://brightdata.com/products/datasets/instagram/profiles) | `instagramProfiles` | Live scrape only | | [Amazon products](https://brightdata.com/products/datasets/amazon) | `amazonProducts` | Live scrape only | | [Zillow properties](https://brightdata.com/products/datasets/zillow) | `zillowProperties` | Live scrape only | | [Indeed job listings](https://brightdata.com/products/datasets/indeed) | `indeedJobs` | Live scrape only | | [Google Maps businesses](https://brightdata.com/products/datasets/google-maps) | `googleMaps` | Live scrape only; business details and top reviews | | [Google Maps reviews](https://brightdata.com/products/web-scraper/google-maps/reviews) | `googleMapsReviews` | Asynchronous live review collection | > **warning**: Live-scrape datasets enrich rows you already have a URL for: an Amazon product page, a Zillow listing, an Indeed posting, a Google Maps place. They cannot search or discover ("find homes in 78704"). Only the three LinkedIn datasets support instant lookup by field; Bright Data's Search API rejects every other dataset id outright. ## Fields Each dataset exposes dozens of fields. The most commonly used ones are below: call field discovery (`rtrvr.enrich({ dataset, fields: true })`, free) to get the full, live list before you filter, since wrong field names fail the job. | Dataset | Key fields | | --- | --- | | `linkedinPeople` / `linkedinPeopleContact` | `id` (profile slug: the lookup key), `url`, `name`, `position` (role/title), `current_company_name`, `city`, `about` (bio), `experience`. The contact variant adds `email` and `cellphone_number`: partial coverage, most profiles return null for both. | | `linkedinCompanies` | `url`, `name`, `website`, `industries`, `company_size`, `headquarters` | | `crunchbaseCompanies` | Company profile fields (name, about, industries, founded date, size, region, website, socials): use field discovery for the full list | | `instagramProfiles` | Profile fields (profile name/id, followers, posts, website, bio, verification): use field discovery for the full list | | `amazonProducts` | `asin`, `url`, `title`, `brand`, `initial_price`, `currency`, `availability`, `reviews_count`, `categories`: 113 fields in total, use field discovery | | `zillowProperties` | `zpid`, `url`, `address`, `price`, `bedrooms`, `bathrooms`, `homeStatus`, `yearBuilt`: 140 fields in total, use field discovery | | `indeedJobs` | `jobid`, `url`, `job_title`, `company_name`, `location`, `salary_formatted`, `job_type`, `date_posted_parsed`, `description_text` | | `googleMaps` | `place_id`, `url`, `name`, `address`, `category`, `reviews_count`, `open_hours`, `business_details` | ## Two Modes: Instant Lookup vs Live Scrape Enrichment runs one of two ways. Instant lookup queries Bright Data's pre-collected index and is the default for people and company enrichment; live scrape fetches fresh data on demand for exact URLs or datasets the index doesn't serve. | | Instant Lookup | Live Scrape | | --- | --- | --- | | API | Bright Data Search API | Web Scraper API (`/scrape`; reviews use async `/trigger`) | | Speed | Sub-second | Often 10–30s; review jobs can take several minutes | | Cost | Free up to the monthly allowance, then 0.25 credits / returned record | Free up to the monthly allowance, then 0.15 credits / successful record | | Datasets | The 3 LinkedIn datasets only | Any scraper-backed dataset (Amazon, Zillow, Indeed, Google Maps, Crunchbase, Instagram) | | How to call | `{ dataset, filter, fields }` | `{ dataset, scrapeUrls, fields }` | | Best for | Bulk lookups by field (e.g. profile `id`) | Exact URLs, non-LinkedIn data, or lookup misses | | Limits | Pass all keys in one `in` filter: batching is server-side | Max 20 inputs per call: chunk larger lists with `rtrvr.mapLimit` | ### Slow Scrapes: Pending Jobs Bright Data serves a scrape inline only while it fits their one-minute window. A heavier job (20 Zillow listings, say) hands back a job handle instead, and the call returns `{ pending: true, snapshotId }` having billed nothing. Do other work, then collect the records later in the same plan: ```js let { records, pending, snapshotId } = await rtrvr.enrich({ dataset: rtrvr.datasets.zillowProperties, scrapeUrls: listingUrls, // max 20 per call fields: ['zpid', 'address', 'price', 'bedrooms'], }); // ...do other free work here while Bright Data finishes... if (pending) { ({ records, pending } = await rtrvr.enrich({ collect: snapshotId, fields: ['zpid', 'address', 'price', 'bedrooms'] })); } // Never re-scrape a pending job — collecting it is how you avoid paying twice. ``` ## Google Maps Reviews Use `googleMaps` for business details and a small `top_reviews` sample. Use `googleMapsReviews` (`gd_luzfs1dn2oa0teb81`) for fresh review records. Both use Bright Data's Web Scraper API. An explicit request to use the Maps UI takes priority: the agent should use that rendered page and ask before switching to a dataset or API if blocked. A running job is not a confirmed failure based on age alone. The reviews route starts an asynchronous job and returns its snapshot without keeping the agent waiting; provider collection can take several minutes. ```js const job = await rtrvr.enrich({ dataset: 'googleMapsReviews', scrapeUrls: [placeUrl], // a resolved https://www.google.com/maps/place/... URL limitPerInput: 120, sortBy: 'Newest', // daysLimit: 90, // optional age filter, in days }); // Save job.snapshotId. If pending, end this run and collect later. // Reuse the SAME account and billing scope. Do not dispatch the scrape again. const result = await rtrvr.enrich({ collect: savedSnapshotId }); ``` - `limitPerInput` is required for an intentional count: default 20, maximum 500 per place and 1,000 across a job. Larger requests fail validation rather than silently reducing the count. Split businesses into smaller jobs. Numeric strings and camelCase/snake_case control aliases are normalized; conflicting or misplaced count controls require correction before a paid request. This is a maximum, not a promise that the provider can access that many reviews. - `sortBy` accepts Newest (also latest), Most relevant, Highest rating, or Lowest rating. Per-row `sort_by` and `days_limit` are supported with `scrape: [{url, sort_by, days_limit}]`. Omit `daysLimit` to avoid a requested age restriction. - Default fields retain full `review` text, `review_id`, `place_id`, rating, date, owner response and the displayed review total. `review: null` means no written text was returned. It may be rating-only, but is not proof that no written text exists. Deduplicate locally by place and review ID. A limit, no-growth scroll, or displayed review count alone does not prove end-of-feed completion. - Billing counts successful review records, including rating-only records, at the configured scrape rate (currently 0.15 credits per record beyond the shared free allowance). Failed inputs and pending collections are unbilled. Collecting an already billed snapshot costs zero additional enrichment credits and returns the same snapshot; it does not fetch the next review page. Agent/model/browser costs are separate. - A terminal provider failure returns `success: false`, `snapshotId`, `failures`, and `creditsUsed`. Preserve this result. A `no_peers` error comes from the provider scraper, not an empty successful collection. Do not redispatch an unknown or pending job. Any retry after a confirmed failure creates a new collection; there is no automatic provider retry or switch to another source. - Review results include `collection` counts and `completeness: unverified`. Set the count, sort and date window from your actual task. For all-review requests, use the displayed total to plan a bounded collection and report any gap; request limits and the displayed total alone do not establish completion. - Snapshots retain original dataset, projection and record limit. Collection checks ownership and billing scope. If billing is awaiting reconciliation, retain the snapshot and contact support; no automatic second debit is attempted. Older, unregistered snapshots also require support reconciliation. ### Connected Chrome Controls For MCP `act_on_tab`, pass `settings: {llmIntegration: {model: 'gpt-6-luna', reasoningEffort: 'low'}}`, `disable_fallbacks: true` (only that model at that reasoning level, or a `MODEL_UNAVAILABLE` error; see /docs/mcp#disable-fallbacks) and `max_steps: 10` to control this invocation. Request overrides do not change saved extension preferences. For GMI inference only, set settings.llmIntegration.inferencePolicy to gmi. This uses managed GLM Flash, keeps normal billing, and refuses alternate-provider fallback. Cloud works through the existing service; connected Chrome requires an extension advertising MCP protocol 4 or later. An unavailable model fails before inference. `max_steps` limits actions; it is not a hard credit limit. Extension `maxCredits` is unsupported and rejected. Use planner/code-plan for `createTool` and `enrich`. For direct `take_page_action`, inspect `actionResults`, `verified`, updated trees and any network `output`/`outputRef`; a dispatched click or unchanged feed is not evidence of successful collection. Generated webpage tools receive `deadlineEpochMs`, a host-owned deadline that includes navigation. Collect bounded batches and return progress before it. On timeout or cancellation, the runtime closes the tabs it created and preserves completed URLs in `error.details.partialResults`; use those results when resuming the remaining work. To report blocked or partial work, return `rtrvr.done(result, {status: 'partial', reason: 'Feed stopped before completion'})`; use `failed` when the requested work failed. These options set completion status without interpreting fields inside your records. ## Cost & Credits - Free allowance: your first 1,000 records each month are free. Enrich records and web searches draw from one shared allowance, which resets on your account's renewal date. - Instant lookup: 0.25 credits per returned record beyond the allowance; zero matches cost nothing. - Live scrape: 0.15 credits per successful record beyond the allowance; failed inputs are free. - Discovery: listing datasets and inspecting fields is always free and never counts against the allowance. - Pending jobs: a scrape that exceeds the sync window bills nothing until you collect it. - Credits are billed at cost (1 credit = $0.01). Overflow beyond the free allowance bills automatically: there are no approval prompts. ## Free Allowance & Billing Enrichment runs without approval prompts. Every account gets 1,000 free records per month, shared between enrich calls and web searches, resetting on the account's renewal date. When a run exceeds what's left of the allowance, the overflow bills automatically at the per-record rates above. Each response reports `creditsUsed` and how many records the free allowance covered, so a plan can always tell you exactly what a run cost. ## Example: Enrich LinkedIn Profiles You do not have to write this yourself: ask in plain English (e.g. "enrich these LinkedIn profile URLs with name, title, and company") and the agent generates and runs the plan. The code below is what it runs under the hood. ```js // Build lookup keys from your sheet rows: match on the lowercase LinkedIn // profile slug (the segment after /in/), NOT the full URL. const ids = rows .map(r => r.linkedinUrl?.split('/in/')[1]?.split(/[/?#]/)[0].toLowerCase()) .filter(Boolean); // Instant lookup — no approval step needed: the first 1,000 records/month are // free and overflow bills automatically (the response reports creditsUsed). // Pass ALL ids in ONE `in` filter (batching is server-side). const { records } = await rtrvr.enrich({ dataset: rtrvr.datasets.linkedinPeople, filter: { name: 'id', operator: 'in', value: ids }, fields: ['id', 'name', 'position', 'current_company_name', 'city'], }); // records → join back onto your rows on `id`, then write the enriched columns. ``` > **warning**: Match on the lowercase `id` slug, not the full profile URL: stored URLs vary by country subdomain and trailing slash, so URL equality matches nothing. Always pass `fields` to keep records small (full records are tens of KB each); the join keys `id`, `url`, and `input_url` are always returned so you can match records back to your rows. ## Enriching LinkedIn URLs with Emails To add emails and phone numbers, use the `linkedinPeopleContact` dataset: same instant lookup by `id` slug, but request the `email` and `cellphone_number` fields explicitly (they are dropped unless named). Coverage is partial: this is partner-sourced B2B contact data, and most profiles return null for both, so treat any email you get as a bonus rather than a guarantee. It is lookup-only: there is no scraper behind it, so `scrapeUrls` on `linkedinPeopleContact` is served by the `linkedinPeople` profiles scraper and returns profile fields but never `email`/`cellphone_number`: a person missing from the instant lookup cannot be recovered by a live scrape; report the miss. ```js const { records } = await rtrvr.enrich({ dataset: rtrvr.datasets.linkedinPeopleContact, filter: { name: 'id', operator: 'in', value: slugs }, fields: ['id', 'name', 'position', 'current_company_name', 'email', 'cellphone_number'], }); const filled = records.filter(r => r.email).length; // e.g. "12 of 60 profiles had an email" — a blank email on a matched row is // normal, not a failed lookup. ``` > **info**: For rows the contact dataset leaves blank, the free supplement is fetching the person's company website contact/about page: the same technique the lead-generation recipe uses. There is no field named `headline`: `position` is the role/title and `about` is the bio. ## Example: Enrich Companies by Domain The `linkedinCompanies` dataset is instant-searchable and carries a `website` field, so a column of company domains can be enriched with firmographics in a sub-second lookup, no scraping required. ```js const { records } = await rtrvr.enrich({ dataset: rtrvr.datasets.linkedinCompanies, filter: { name: 'website', operator: 'in', value: domains }, fields: ['name', 'website', 'industries', 'company_size', 'headquarters'], }); // Domains are stored as full URLs, so `in` can miss on scheme or a leading // "www.". If a domain returns nothing, retry it with the `includes` operator. ``` ## Example: Enrich Amazon Products by URL Non-LinkedIn datasets are live-scrape only: you supply each product's URL and get a fresh record back. Chunk lists larger than 20 with `rtrvr.mapLimit`. ```js const chunks = []; for (let i = 0; i < productUrls.length; i += 20) chunks.push(productUrls.slice(i, i + 20)); const results = await rtrvr.mapLimit(chunks, 2, async chunk => rtrvr.enrich({ dataset: rtrvr.datasets.amazonProducts, scrapeUrls: chunk, fields: ['asin', 'title', 'brand', 'initial_price', 'availability'], }), ); // Each result may come back `pending` — collect it with { collect: snapshotId }. // Join back onto your rows on `url` (or `input_url`, the URL you passed in). ``` ## Web Search Plans can also search the web programmatically with `rtrvr.webSearch({ query, count?, gl?, hl?, recency?, since?, until?, news?, sortByDate? })`: one Google query per call, returning parsed organic results (`{ title, url, snippet, source?, date?, dateText? }`) and, for place-flavored queries, `localResults` (Google's local pack: name, address, rating, reviews, category, and a canonical maps link). Phone numbers and websites are not in the pack: they come from each business's own site or listing. Bound a search to a time window with `recency` (`hour`, `day`, `week`, `month`, `year`) or with explicit `since`/`until` dates (`YYYY-MM-DD`), and add `sortByDate` to order newest first. A time-bounded search returns each result's publication date as an absolute, already-normalized `date`, so a plan never has to parse a phrase like `5 hours ago` itself; `appliedFilters` states the window that was applied and `notice` states anything that could not be. A result with no `date` is undated, which never means recent. Date filtering runs on Google's news vertical, the only one that carries publication dates, so any date filter turns `news` on unless you explicitly pass `news: false`. Queries draw from the same 1,000-record monthly free allowance as enrichment, then cost a flat 0.15 credits per query with no approval prompt, and it replaces navigating a browser tab to Google. Localize with `gl` (country) and `hl` (language). ## Recipe: Local-Business Lead Generation The pieces compose into a lead-generation pipeline: ask in plain English (e.g. "find 100 businesses in Casablanca and Rabat that likely need a website") and the agent runs this shape: - Fan `rtrvr.webSearch` over each industry × city (localized, e.g. `gl: 'ma', hl: 'fr'`) and harvest the local pack: business name, phone, website (or its absence), rating, maps link. - Construct a Google Maps link per business: `https://www.google.com/maps/search/?api=1&query=Name+City` resolves to the real place page. - Enrich businesses that have a website with a free fetch of their contact/about page (email, socials), or instantly via the `linkedinCompanies` dataset filtered on `website`. - Qualify with one LLM pass (`rtrvr.inferSheetData`): e.g. a "why they need a website" column and a priority score. - Rows append to a Google Sheet as they are found, so partial progress always survives; export the sheet as CSV when done. > **info**: Expect partial email coverage on local-business runs: many small businesses publish no email anywhere, and the strongest leads (no website at all) usually have none. Phone numbers and maps links fill far more reliably. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Run from anywhere. RUN # Run from anywhere. Start browser jobs from your terminal, CI, or another agent. Choose Cloud, the Chrome browser on your device, or let rtrvr route the job. [Install from npm](https://www.npmjs.com/package/@rtrvr-ai/cli)[Open on GitHub](https://github.com/rtrvr-ai/rtrvr-cli) 01 ## Cloud Run away from your laptop in a managed browser. 02 ## Chrome Use the signed-in browser already on your device. 03 ## Auto Use Chrome when it is available and Cloud when it is not. API, CLI, and MCP runs need a paid plan: Cloud API calls with an API key, the MCP Cloud tools (cloud\_agent, cloud\_scrape, and agent or scrape in Cloud), and rtrvr's agent in your Chrome. On a paid plan they use credits for the resources they consume. Browser tools your own AI drives over MCP are free on every plan. On the free plan, try Free Mode in the extension or Cloud dashboard. [Compare plans →](/pricing#free-mode) Free usage, ads, and data terms Free Mode includes supported AI models and Cloud browser time for tasks you start in the extension or Cloud dashboard. No AI API key or paid AI subscription is required. Sponsored cards and a daily fair-use allowance apply. Your account shows the current allowance and reset time. When you reach it, wait for the reset, use your own AI provider, or choose a paid plan. Your provider may charge for its usage. One schedule that runs once a day or less often, in the Cloud or in your Chrome, is included, paid from the daily allowance. More schedules, faster schedules, triggers, cookie sync, API runs, rtrvr's agent over MCP, and WhatsApp tasks require a paid plan. Browser tools that let your own AI drive your Chrome over MCP are free on every plan. Data enrichment and managed proxies can use credits separately. On the free plan, Cloud API calls made with an API key, the MCP Cloud tools (cloud\_agent, cloud\_scrape, and agent or scrape when they run in Cloud), and WhatsApp tasks need a paid plan, as does running rtrvr's agent in your Chrome through API or MCP. Free Mode covers the tasks you start in the extension or Cloud dashboard. On a paid plan, API, MCP, and WhatsApp runs use credits for the resources they consume. Free Mode involves sponsored content in both the Chrome extension and Cloud, as described in the Terms and Privacy Notice. Using your own AI provider avoids model-credit charges and the Free Mode allowance. Cloud resources and managed services may still use credits. Sponsored cards still appear on the free plan. Paid plans offer ad-free runs. [Free Mode terms](/terms#free-mode) · [Privacy notice](/privacy) CLI (global) bash ``` npm install -g @rtrvr-ai/cli ``` Programmatic API bash ``` curl https://api.rtrvr.ai/agent ``` The CLI provides the `rtrvr` command. Programmatic callers can use the HTTP API directly. 1**Authenticate** bash ``` rtrvr auth login ``` 2**Run your first task** CLI ``` rtrvr run "Extract the top 10 products and prices" --url https://example.com ``` 3**Explore** bash ``` # Scrape a page rtrvr scrape --url https://example.com # Check your capabilities rtrvr capabilities # Run diagnostics rtrvr doctor ``` Pick where the browser should run. Use `--target`, or keep Auto when the same job should work across environments. 01`--cloud` ### Cloud Run in a managed browser away from your device. Best for public pages, scheduled jobs, and unattended work. 02`--extension` ### Chrome Use the signed-in Chrome browser on your device. Best for private apps, SSO, and internal tools. 03`--target auto` ### Auto (default) Use Chrome when it is available; fall back to Cloud when it is not. Best for portable jobs. Auto routing `rtrvr run "task"` Chrome online**Run in Chrome** No device**Run in Cloud** The response includes routing metadata showing which mode was selected and whether fallback was applied: json ``` { "metadata": { "selectedMode": "cloud", "fallbackApplied": true, "fallbackReason": "no extension devices online" } } ``` bash ``` # Positional input rtrvr run "Find the latest pricing for each plan" --url https://example.com # From file rtrvr run --input-file ./task.txt --url https://example.com --target cloud # From stdin echo "Summarize this page" | rtrvr run --url https://example.com ``` `` Task description (positional argument) `--input ` Task description (flag alternative) `--input-file ` Read task description from a file `--url ` Target URL(s) for the agent `--target `default: `auto` Routing mode: auto, cloud, or extension `--cloud` Shortcut for --target cloud `--extension` Shortcut for --target extension `--device-id ` Target a specific browser extension device `--schema-file ` JSON schema file for structured output `--json` Machine-readable JSON output `--no-stream` Disable real-time progress streaming Use the authenticated HTTP API directly for programmatic cloud runs. ### Create a Run cURL ``` curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer $RTRVR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Find latest headline and author", "urls": ["https://example.com"], "target": "auto" }' ``` ### Client Options `apiKey` Your rtrvr API key (rtrvr\_...) `defaultTarget`default: `auto` Default routing mode `baseUrl`default: `https://api.rtrvr.ai` Override the API base URL `mcpUrl`default: `https://mcp.rtrvr.ai` Override the MCP base URL ### Unified Run JSON body ``` { "input": "Find latest headline and author", "urls": ["https://example.com"], "target": "auto" } ``` ### Direct Tool Calls CLI ``` rtrvr raw extract_from_tab --user_input "Extract all product names and prices" --tab_urls '["https://example.com/products"]' rtrvr raw act_on_tab --user_input "Click the Sign Up button" --tab_urls '["https://example.com"]' rtrvr raw crawl_and_extract_from_tab --user_input "Find all blog post titles" --tab_urls '["https://example.com/blog"]' ``` ### Scrape CLI ``` rtrvr scrape https://example.com ``` ### Utilities CLI ``` rtrvr devices rtrvr credits rtrvr profile ``` Keep building ## Use the same job from another surface. Move between the CLI, APIs, and MCP without relearning the task contract. [API overview Endpoints and authentication](/docs/api)[Agent API Run complete browser jobs](/docs/agent)[Scrape API Return page content and structure](/docs/scrape)[Browser API and MCP Give another agent a browser](/docs/mcp) YOUR NEXT RUN ## Run from anywhere. Install the CLI to start jobs from your terminal, CI, or another agent. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # API Overview High-level overview of the Agent API plus recommended client patterns. For the full schema and Playground, see /docs/agent. # API Overview API runs need a paid plan and use credits for the resources they consume. On the free plan, a Cloud API call made with an API key is refused with 403 PLAN_REQUIRED, because Free Mode applies to tasks you start in the extension or Cloud dashboard, not to API calls. Running rtrvr's agent in your Chrome through API or MCP requires a subscription too; the browser tools your own AI drives are free on every plan. [Compare plans](/pricing#free-mode). [Video: API Overview](https://www.youtube.com/watch?v=jmVgTLezDT8) The rtrvr.ai HTTP API exposes the same planner + tools engine that powers the web agent UI. Use it to run web automations or sheets-style workflows directly from your backend or serverless functions. > **info**: For the full request/response schema, live Playground, and language-specific examples, open the API Reference at /docs/agent. ## Agent Endpoint Almost all integrations use a single endpoint: POST /agent. Send a natural-language input, optional URLs, optional dataInputs (CSV/JSON), and an optional response config. The planner chooses the right tools and returns a structured AgentApiResponse. ```bash curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Summarize this page in 5 bullet points.", "urls": ["https://example.com"], "response": { "verbosity": "final" } }' ``` Every endpoint (/agent, /scrape and the MCP endpoint) takes the same API key: `Authorization: Bearer rtrvr_…`, the bare key (`Authorization: rtrvr_…`), or an `x-api-key` header. For n8n, Make or Zapier "Header Auth", set Name to `Authorization` and Value to your key, or set Name to `x-api-key`. ## Request: Mental Model - input: required natural-language instruction the planner reasons over - urls: optional array of pages to open before the agent runs - dataInputs: optional tabular inputs (CSV/TSV/JSON) converted into in-memory sheets - variables: optional exact values by name (a signed file URL, the text to post, a time); name them in input and the agent reads each as data instead of copying it out of the task text. From n8n, send `variables` as `{{ JSON.stringify({ ... }) }}`. See /docs/agent#variables - settings.browser: optional clock for the cloud browser, `timezone` (IANA, e.g. "Asia/Singapore") and `locale` (e.g. "en-US"). Pages and date/time pickers use it; without it the clock is set where the browser started (a proxy location's own clock; America/Chicago, en-US when unknown), so set it when times matter. The agent is told the zone and converts requested times into it. See /docs/agent#browser-clock - tools.enableAdditionalTools: opt-in for heavier tool families (generate_docs, generate_sheets, generate_pdfs, generate_websites, ask_questions) - settings.proxyConfig.location: optional exit location for the managed proxy: `country` (ISO, e.g. "IT"), optional `region` (ISO 3166-2 part, e.g. "NY") and `city` (English name). The run never exits in another country, the browser's time zone and language follow the exit, and the response's `egress` says where it exited. MCP also takes the shorthand `proxy_location`. Countries with an exit: GET /proxy-locations (dated, from the last sweep); a region or city right now: POST /proxy-location/check. See /docs/agent#proxy-location and /docs/agent#proxy-locations - disable_fallbacks: optional `true` to run only the selected model at the reasoning level asked for (`disableFallbacks`, "true"/"false" and 1/0 are accepted too). A step that model cannot finish ends the run with code `MODEL_UNAVAILABLE` (details in `modelUnavailable`; status "error", or "partial" when it had already produced output) instead of switching to another model or a lower reasoning level. `false` allows fallbacks for one request; either way your saved Disable fallbacks setting is unchanged. See /docs/agent#parameters - response.verbosity: the detail level, one of "final" (default), "steps", or "debug" > **warning**: For production, keep response.verbosity = "final" unless you need per-step telemetry. Debug mode returns much more data and costs more bandwidth. ## Response: Mental Model - result.text: human-readable summary of what happened - result.json: structured machine-readable result, shaped by your optional schema - output: all blocks (text, json, and in debug mode, per-step tool_result blocks) - usage: creditsUsed, creditsLeft, and other billing fields - metadata: trajectoryId, toolsUsed, optional references to full snapshots ## Cancelling a Run Cancel a running run from the dashboard (Executions → Cancel, whatever started it: the chat, this API, MCP, a schedule or a webhook) or with POST /agent/cancel and the run's trajectoryId. It stops within seconds, the request still waiting on it returns status "cancelled", and the credits for steps already taken are charged. Stopping an n8n execution does not close the requests it already sent; send your own trajectoryId with each request to cancel them from a workflow. See /docs/agent#cancel ## SDK & Client Patterns You don't need a heavy SDK. The recommended pattern is a thin server-side wrapper around POST /agent, plus optional batching for fan-out. This keeps your API key on the backend, centralizes rate limiting, and minimizes per-request latency. ### Node / Next.js ```typescript // /app/api/rtrvr/agent/route.ts (Next.js App Router) import "server-only" const RTRVR_BASE = "https://api.rtrvr.ai" const RTRVR_KEY = process.env.RTRVR_API_KEY! type Payload = { input: string; urls?: string[]; dataInputs?: any[]; tools?: any; response?: any } export async function POST(req: Request) { const body = (await req.json()) as Payload | Payload[] const tasks = Array.isArray(body) ? body : [body] const results = await Promise.all( tasks.map((task) => fetch(RTRVR_BASE + "/agent", { method: "POST", headers: { Authorization: "Bearer " + RTRVR_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ response: { verbosity: "final", inlineOutputMaxBytes: 200_000 }, ...task, }), }).then((r) => r.json()) ) ) return Response.json(Array.isArray(body) ? results : results[0]) } ``` ### Python ```python import os, requests from typing import List, Dict, Any BASE = "https://api.rtrvr.ai" KEY = os.environ["RTRVR_API_KEY"] def execute_tasks(tasks: List[Dict[str, Any]]) -> List[Dict[str, Any]]: session = requests.Session() results = [] for task in tasks: resp = session.post( f"{BASE}/agent", headers={"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"}, json={"response": {"verbosity": "final", "inlineOutputMaxBytes": 200_000}, **task}, timeout=60, ) results.append(resp.json()) return results ``` > **success**: For the complete schema, error codes, and many more code samples, open the API Reference at /docs/agent. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Send one job./agent RUN # Send one job.`/agent` Give rtrvr a goal, starting pages, and the response shape. It plans the route, uses the browser and tools, and returns the result. [Try a request](#playground)[Create API key](/cloud?view=api-keys) API, CLI, and MCP runs need a paid plan: Cloud API calls with an API key, the MCP Cloud tools (cloud\_agent, cloud\_scrape, and agent or scrape in Cloud), and rtrvr's agent in your Chrome. On a paid plan they use credits for the resources they consume. Browser tools your own AI drives over MCP are free on every plan. On the free plan, try Free Mode in the extension or Cloud dashboard. [Compare plans →](/pricing#free-mode) Free usage, ads, and data terms Free Mode includes supported AI models and Cloud browser time for tasks you start in the extension or Cloud dashboard. No AI API key or paid AI subscription is required. Sponsored cards and a daily fair-use allowance apply. Your account shows the current allowance and reset time. When you reach it, wait for the reset, use your own AI provider, or choose a paid plan. Your provider may charge for its usage. One schedule that runs once a day or less often, in the Cloud or in your Chrome, is included, paid from the daily allowance. More schedules, faster schedules, triggers, cookie sync, API runs, rtrvr's agent over MCP, and WhatsApp tasks require a paid plan. Browser tools that let your own AI drive your Chrome over MCP are free on every plan. Data enrichment and managed proxies can use credits separately. On the free plan, Cloud API calls made with an API key, the MCP Cloud tools (cloud\_agent, cloud\_scrape, and agent or scrape when they run in Cloud), and WhatsApp tasks need a paid plan, as does running rtrvr's agent in your Chrome through API or MCP. Free Mode covers the tasks you start in the extension or Cloud dashboard. On a paid plan, API, MCP, and WhatsApp runs use credits for the resources they consume. Free Mode involves sponsored content in both the Chrome extension and Cloud, as described in the Terms and Privacy Notice. Using your own AI provider avoids model-credit charges and the Free Mode allowance. Cloud resources and managed services may still use credits. Sponsored cards still appear on the free plan. Paid plans offer ad-free runs. [Free Mode terms](/terms#free-mode) · [Privacy notice](/privacy) ### Agent API Playground POST`/agent` Planner + tools engine in API mode. Try an example API Key Get from [rtrvr.ai/cloud](/cloud?view=api-keys) Task Description \* URLs (one per line) Recording (optional) Sent as `recordingContext`: the agent follows the recorded walkthrough as its guide. Record one in the extension, then find its id under [Recordings](/cloud?view=recordings). Sign in to pick from your library. curl -X POST https://api.rtrvr.ai/agent \\ -H "Authorization: Bearer YOUR\_API\_KEY" \\ -H "Content-Type: application/json" \\ -d '{ "input": "Retrieve the top 5 article titles and authors.", "urls": \[ "https://news.ycombinator.com/" \], "response": { "verbosity": "final" } }' CLI Run the same job from your terminal with [rtrvr CLI](/docs/cli). `rtrvr run "Extract products"` Watch the walkthrough video Agent API Walkthrough Base URL`https://api.rtrvr.ai` Primary endpoints: `/agent` (planner + tools) and `/scrape` (raw page data). Use your API key in the `Authorization` header: Header ``` Authorization: Bearer rtrvr_your_api_key ``` The `Bearer` prefix is optional (`Authorization: rtrvr_your_api_key` works), and `x-api-key: rtrvr_your_api_key` is accepted too. In n8n, Make or Zapier **Header Auth**, set Name to `Authorization` and Value to your key, or Name to `x-api-key`. **Security:** Always keep your key on the server side (e.g. backend, serverless). Never embed it in browser code or ship it to clients. POST`https://api.rtrvr.ai/agent` Send a single JSON payload describing what you want. The planner orchestrates browser tabs, tools, and in-memory sheets to get the job done. cURL ``` curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Summarize the main points of this page in 5 bullet points.", "urls": ["https://example.com/blog/ai-trends-2025"], "response": { "verbosity": "final" } }' ``` Internally, this maps to an execution trajectory. New requests get a new `trajectoryId`; continuations reuse it. For low-level raw page data, see the [Scrape API docs](/docs/scrape) (`/scrape`). Both endpoints share the same browser + proxy infra but are optimized for different jobs. Dimension /agent /scrape What it does Full agent run: planner + tools + browser + optional Sheets/Docs/etc. Loads pages and returns extracted text + accessibility tree. Typical latency Higher – dominated by LLM calls and multi-step tools. Lower – usually just browser + proxy round-trips. Credits Infra credits + model/tool credits. Infra-only credits (browser + proxy); no model/tool usage. Best for End-to-end automations, multi-step workflows, writing back to external systems. Feeding your own LLM/RAG stack, ad-hoc scraping, prefetching page data. Capabilities Planner, tools, Sheets workflows, Docs/PDF generation, `ask_user`, etc. Extracted text, accessibility tree, `elementLinkRecord`, usage metrics. Start with an API key. For native Google operations, connect Google Drive in the same Cloud account. Attach files only when the task reads them. 01 ### Create an API key Create it in Cloud and keep it on your server. [Open API keys](https://rtrvr.ai/cloud?view=api-keys) 02 ### Connect Google Drive Google tools use your API key owner’s saved connection and refresh it automatically. 1. 01 Open Cloud → Sheets and connect Google Drive 2. 02 Select existing files through the Google picker 3. 03 Enable the Google tools your API request needs 03 ### Attach files when needed Upload PDFs, images, or documents, then pass their Storage URLs in files. [Open files](https://rtrvr.ai/cloud?view=files) ### Trajectory & Phase A **trajectory** is a stable ID for a workflow. Use it to group related phases (e.g. discovery → enrichment → reporting) and continuations. - Omit `trajectoryId` to start fresh. - Reuse the same `trajectoryId` with `continuePlanning = true` and the returned `history` to continue. - `phase` (default `1`) lets you structure long-running projects into multiple stages. ### Planner + Tools You don't call tools directly. Instead, you describe the task and optionally configure which `enableAdditionalTools` to allow. Support for `tools.enableAdditionalTools` in the public API will come soon. Under the hood, the planner can call tools like `act_on_tab`, `crawl_and_extract_from_tab`, `sheets_workflow`, `create_sheet_from_data`, and more. Only a subset (Docs, Slides, PDFs, persistent Sheets, ask\_user, etc.) is gated behind `enableAdditionalTools` to control cost and latency. ### Tabular Inputs & In-Memory Sheets Use `dataInputs` to attach CSV/TSV/JSON, text, markdown, or binary formats (XLSX/Parquet via URL or storage). The system: - Infers the format from extension or content type when omitted. - Parses header and row schema. - Creates an in-memory sheet (no Google Drive write) exposed to tools like `sheets_workflow`. The `files` parameter lets you attach PDFs, images, and documents for the agent to analyze or use. This is different from `dataInputs`which is specifically for tabular/structured data. **What the agent can do with files:** - Read and analyze PDF documents - Process and describe images (screenshots, diagrams, photos) - Fill out PDF forms with extracted or provided data - Upload files to web forms during browser automation - Compare multiple documents and find differences ### ApiExecuteRequestFile schema `files[].displayName`string**required** Human-readable filename shown to the agent (e.g., 'Q3-Report.pdf', 'screenshot.png') `files[].uri`string**required** File location. Accepts Firebase Storage URL, GCS URI (gs://bucket/path), or public HTTPS URL `files[].mimeType`string**required** MIME type (e.g., 'application/pdf', 'image/png', 'image/jpeg') ### Supported file types PDF(application/pdf) PNG(image/png) JPEG(image/jpeg) GIF(image/gif) WebP(image/webp) Word(docx) Text(text/plain) Markdown(text/markdown) ### Ways to provide file URIs Recommended1\. Firebase Storage URL Upload files via [Cloud → Files](/cloud?view=files) and copy the Storage URL, or programmatically via the [`upload_file` MCP tool](/docs/mcp#file-inputs) (base64, URL import, or signed upload URL for local files). This is the most reliable option. `https://firebasestorage.googleapis.com/v0/b/bucket/o/path%2Ffile.pdf?alt=media&token=...` 2\. GCS URI If you have files in Google Cloud Storage, use the gs:// URI directly. `gs://your-bucket/path/to/file.pdf` 3\. Public HTTPS URL Any publicly accessible URL. Must not require authentication. `https://example.com/documents/report.pdf` ### Example: Analyze a PDF report PDF Analysis ``` curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Extract the key financial metrics from this quarterly report and summarize them.", "files": [ { "displayName": "Q3-2024-Report.pdf", "uri": "https://firebasestorage.googleapis.com/v0/b/bucket/o/reports%2Fq3.pdf?alt=media&token=abc", "mimeType": "application/pdf" } ], "schema": { "type": "object", "properties": { "revenue": { "type": "string" }, "profit": { "type": "string" }, "growth": { "type": "string" }, "highlights": { "type": "array", "items": { "type": "string" } } } } }' ``` ### Example: Analyze an image Image Analysis ``` curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Describe this screenshot and identify any UI/UX issues.", "files": [ { "displayName": "app-screenshot.png", "uri": "gs://my-bucket/screenshots/app-v2.png", "mimeType": "image/png" } ] }' ``` ### Example: Compare multiple documents Multi-file comparison ``` curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Compare these two contracts and list all the differences.", "files": [ { "displayName": "contract-v1.pdf", "uri": "https://firebasestorage.googleapis.com/.../contract-v1.pdf?...", "mimeType": "application/pdf" }, { "displayName": "contract-v2.pdf", "uri": "https://firebasestorage.googleapis.com/.../contract-v2.pdf?...", "mimeType": "application/pdf" } ], "schema": { "type": "object", "properties": { "differences": { "type": "array", "items": { "type": "object", "properties": { "section": { "type": "string" }, "v1_text": { "type": "string" }, "v2_text": { "type": "string" }, "significance": { "type": "string" } } } } } } }' ``` ### Example: Upload file to web form File upload during automation ``` curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Go to the application page, upload my resume, and fill out the form with name: John Doe, email: john@example.com", "urls": ["https://company.com/careers/apply"], "files": [ { "displayName": "resume.pdf", "uri": "https://firebasestorage.googleapis.com/.../resume.pdf?...", "mimeType": "application/pdf" } ] }' ``` **Limits & notes:** - Maximum file size: **128 MB** per file - The LLM reads files up to 20 MB; longer documents may use more credits - Over 20 MB, the LLM sees only the file's name, type and size. The agent can still upload the file to a web form or pass it on to tools and later steps - Binary files are base64-encoded internally for LLM processing - Use `dataInputs` for tabular data (CSV, JSON, Excel) - it's more efficient - Local files: upload first via the [upload\_file MCP tool](/docs/mcp#file-inputs) (base64, URL import, or signed upload URL) or [Cloud → Files](/cloud?view=files), then pass the returned storage URL as the `uri` The full request shape is `AgentApiRequest`: AgentApiRequest (conceptual) ``` interface AgentApiRequest { // ───────────────────────────────────────── // CORE PARAMETERS // ───────────────────────────────────────── /** Stable ID for a workflow. Omit to start new; reuse to continue. */ trajectoryId?: string; /** Phase index within a trajectory (default: 1). Use ≥2 for multi-stage workflows. */ phase?: number; /** The trajectoryId of an earlier run that ended unfinished: this new run starts from the progress it saved. */ retryOf?: string; /** Main user instruction - REQUIRED */ input: string; /** Optional Google OAuth override; otherwise Google work uses the API key owner's Cloud connection. */ authToken?: string; /** URLs to open in browser tabs */ urls?: string[]; /** JSON Schema describing expected result shape */ schema?: Schema; /** * Credit budget for this run: its per-task credit ceiling. Shorthand for * options.limits.creditCeiling.credits (wins when both are sent); * max_credits is accepted too. At the budget the run pauses with a * Continue / Stop question (a schedule stops instead). */ maxCredits?: number; /** * Only the selected model, at the reasoning level asked for, for this run * (default: your Disable fallbacks setting). A provider serving the same * model may still answer; the run never switches to another model, a lower * reasoning level, or credits when your own key fails. A step the model * cannot finish ends the run with code MODEL_UNAVAILABLE (details in * modelUnavailable), status "error", or "partial" when it had already * produced output. disableFallbacks is accepted too, as are "true", * "false", 1, 0, "1" and "0". Never saved. */ disable_fallbacks?: boolean; /** * Exact values for this run, by name: a signed file URL, the text to post, * a schedule time. Refer to them by name in input; the agent reads each one * as data and never copies it out of input or retypes it. Names: a letter * or _, then letters, digits or _ (max 64). Values: string, number or * boolean; at most 32 entries of 20,000 characters each. A JSON string of * the object is accepted too. Anything else is a 400 (INVALID_VARIABLES). * A continuation that omits it keeps the run's values; one that sends it * replaces them. */ variables?: Record; // ───────────────────────────────────────── // FILE INPUTS (PDFs, Images, Documents) // ───────────────────────────────────────── /** * File attachments for the agent to process. * Supports PDFs, images, and documents up to 128 MB each. * The model reads files up to 20 MB; for a larger file it sees only * the name, type and size, and the agent can still upload the file. * * The agent can: * - Read and analyze file contents * - Extract text from PDFs * - Analyze images * - Upload files to web forms */ files?: ApiExecuteRequestFile[]; // ───────────────────────────────────────── // TABULAR DATA INPUTS // ───────────────────────────────────────── /** * Tabular data to load as in-memory sheets. * Supports CSV, TSV, JSON, text, markdown, XLSX, Parquet. */ dataInputs?: ApiTabularInput[]; // ───────────────────────────────────────── // TOOL CONFIGURATION // ───────────────────────────────────────── tools?: ApiToolsConfig; // ───────────────────────────────────────── // SETTINGS & HISTORY // ───────────────────────────────────────── /** * Per-request settings override. The fields most callers use: * llmIntegration: { model, reasoningEffort } // which model, how hard it thinks * llmIntegration.disableCreditsFallback // true: only that model (as disable_fallbacks) * cookieSync: { enabled } // restore stored website sessions * proxyConfig: { mode: 'none' | 'default' | 'custom' } * browser: { timezone, locale } // the cloud browser's clock: IANA zone + language * limits: { creditCeiling: { credits, onExceed } } * proxyConfig.location: { country, region?, city? } // where the managed proxy exits (mode 'default'); one field may list up to 5 */ settings?: Partial; /** * A recording id from rtrvr.ai/cloud → Recordings. The agent follows the * recorded walkthrough as its guide for this task. */ recordingContext?: string; /** Continue the previous workflow state (top-level wins over history.continue). */ continuePlanning?: boolean; /** Continuation state from previous runs */ history?: { continue?: boolean; previousSteps?: PlannerPreviousStep[]; lastToolPreviousSteps?: ToolPreviousSteps; }; // ───────────────────────────────────────── // RESPONSE CONFIGURATION // ───────────────────────────────────────── response?: { /** 'final' (default) | 'steps' | 'debug' */ verbosity?: ApiVerbosity; /** Max bytes for inline output (default: 1MB) */ inlineOutputMaxBytes?: number; }; // ───────────────────────────────────────── // ARTIFACT REUSE (Advanced) // ───────────────────────────────────────── /** * Control how the agent reuses existing Google artifacts. * Useful for appending to existing Sheets/Docs. */ reuseArtifacts?: ReuseArtifacts; // ───────────────────────────────────────── // INTERNAL OPTIONS // ───────────────────────────────────────── options?: { skipToolsStorageLoad?: boolean; pinTools?: boolean; pinSettings?: boolean; /** Execution trigger context */ trigger?: { type: 'schedule' | 'ui' | 'api'; context?: ScheduleContext; }; /** UI and VNC live view settings */ ui?: { /** Enable VNC live browser viewing. Default: false */ enableVnc?: boolean; /** * Which browser sessions to expose: * - "root": Main browser only (default) * - "all": Main + all batch worker browsers */ vncScope?: 'root' | 'all'; /** * Emit progress events to Firestore. * Opt-in only: set true to enable progress event writes. */ emitEvents?: boolean; }; /** Per-task spend guard. Overrides the saved setting for this run. */ limits?: { creditCeiling?: { /** Credits this run may spend before it stops to ask. */ credits?: number; /** * What to do at the ceiling. Defaults to 'stop' for * trigger.type === 'schedule' and 'pause' everywhere else. * 'off' opts this run out of the check entirely. */ onExceed?: 'pause' | 'stop' | 'off'; }; }; /** * Evidence for the data the run returns. screenshots: true makes the agent * screenshot every page it takes data from and tag each record with * evidenceArtifactId; the screenshots come back in response.artifacts. */ evidence?: { screenshots?: boolean; }; }; // ───────────────────────────────────────── // WEBHOOKS (Async notifications) // ───────────────────────────────────────── /** * Webhook subscriptions for async delivery of execution results. * Up to 5 webhooks per request. Delivered via Cloud Tasks (best-effort). */ webhooks?: WebhookSubscription[]; } // Webhook subscription type interface WebhookSubscription { /** Webhook endpoint URL (HTTPS required in production) */ url: string; /** Events to subscribe to. If omitted, all events are delivered. */ events?: ( | "rtrvr.execution.succeeded" | "rtrvr.execution.failed" | "rtrvr.execution.cancelled" | "rtrvr.execution.requires_input" )[]; /** HTTP method (currently only POST supported) */ method?: "POST"; /** Custom headers to include in webhook requests */ headers?: Record; /** Authentication config */ auth?: { type: "bearer"; token: string; } | { type: "basic"; username: string; password: string; }; /** Secret for HMAC signature (X-Rtrvr-Signature header) */ secret?: string; /** Request timeout in ms (1000-30000, default: 8000) */ timeoutMs?: number; /** Retry policy: "default" (with retries) or "none" */ retry?: { mode: "default" | "none" }; } // File input type interface ApiExecuteRequestFile { /** Human-friendly filename, e.g. "Resume-2025.pdf" */ displayName: string; /** * File location. Accepts: * - Firebase Storage URL: https://firebasestorage.googleapis.com/... * - GCS URI: gs://bucket/path/to/file * - Public HTTPS URL: https://example.com/file.pdf */ uri: string; /** MIME type, e.g. "application/pdf", "image/png" */ mimeType: string; } // Tabular input type interface ApiTabularInput { /** Optional client-provided correlation ID */ id?: string; /** Description for the sheet (used as title) */ description?: string; /** Format hint: "csv" | "tsv" | "json" | "text" | "markdown" | "xlsx" | "parquet" */ format?: InputFormat; /** Inline data content */ inline?: string; /** Remote URL to fetch data from */ url?: string; /** Backend storage reference (advanced) */ storageRef?: StorageReference; } // Tools configuration interface ApiToolsConfig { /** * Additional tool families to enable. * Core tools (browser, extraction, in-memory sheets) are always available. */ enableAdditionalTools?: ( | "ask_questions" // Pause for user input | "generate_sheets" // Write to Google Sheets | "generate_docs" // Create Google Docs | "generate_slides" // Create Google Slides | "generate_websites" // Generate web dashboards | "generate_pdfs" // Create new PDFs | "pdf_filling" // Fill PDF forms )[]; /** Names of user-defined tools to make available */ userDefined?: string[]; /** * Tool loading mode: * - "profile": Load user's saved tools (default) * - "allowlist": Only use tools in userDefined * - "none": No user-defined tools */ mode?: "allowlist" | "profile" | "none"; } // Artifact reuse configuration interface ReuseArtifacts { /** 'off' (default) | 'auto' | 'force' */ mode?: 'off' | 'auto' | 'force'; targets?: { sheets?: { sheetId: string; tabTitle?: string; tabId?: number; /** 'SAME_TAB' | 'NEW_TAB' */ tabMode?: 'SAME_TAB' | 'NEW_TAB'; }; docs?: { docId: string; /** 'APPEND' | 'OVERWRITE' */ mode?: 'APPEND' | 'OVERWRITE'; }; slides?: { presentationId: string; mode?: 'APPEND' | 'OVERWRITE'; }; pdfs?: { templateFileId?: string; }; }; } ``` ### Core fields `input`string**required** Natural-language task description; what you want the system to do. `authToken`string Optional Google OAuth override for this request. When omitted, Google work uses and refreshes the API key owner’s saved Cloud connection. Supply and refresh overrides yourself on every request, including continuations; a failed override never switches to the saved account. `urls`string\[\] Optional list of URLs to open. The first real URL loads full content; others default to text-only for efficiency. `schema`Schema Optional OpenAPI-style JSON Schema describing the desired final JSON shape. Planner and tools will try to honor it when producing result.json. `trajectoryId`string Stable ID for a workflow. Omit to start a new trajectory; reuse to continue or add phases. `phase`numberdefault `1` Phase index within a trajectory. Use ≥2 for multi-stage workflows. `retryOf`string The trajectoryId of an earlier run of yours that ended unfinished (stopped, failed, timed out, out of credits, or partial). This request starts a new run, under its own trajectoryId, that begins with the progress that run saved and picks up where it stopped instead of redoing finished items. Not with continuePlanning. A run that finished successfully, ran in Private Mode, or stopped before its first plan script saved no progress; the new run then starts from the beginning. Example schema: bulleted summary ``` { "type": "object", "properties": { "bullets": { "type": "array", "items": { "type": "string" } }, "sourceUrl": { "type": "string" } }, "required": ["bullets"] } ``` ### Exact values (`variables`) A value the agent must use exactly (a signed file URL, the text of a post, a time) goes in `variables`, not in `input`. Name it in the instruction ("attach the video at mediaUrl"). The agent reads the value as data and hands the same characters to the page. A value it has to copy out of the task text, or retype, can lose a character or keep the sentence's final period, and a signed URL then fails with HTTP 403. `variables`Record Names: a letter or \_, then letters, digits or \_ (at most 64). Values: strings, numbers or booleans; at most 32 entries of 20,000 characters each. A JSON string of the object is accepted too. A bad name, an object or array value, or a value over the limit is a 400 (INVALID\_VARIABLES); nothing is dropped silently. `continuations`behavior Every step of a run sees the same values. A continuation (trajectoryId + continuePlanning) that omits variables keeps the run's values; one that sends variables replaces them, e.g. a signed URL that expired while the run waited for an answer. Example: schedule a note with a video ``` { "input": "On Substack, create a Note with the text in noteText, attach the video at mediaUrl, and schedule it for scheduleTime.", "urls": ["https://substack.com/home"], "variables": { "mediaUrl": "https://prod-files-secure.s3.us-west-2.amazonaws.com/…/clip.mp4?X-Amz-Algorithm=…&X-Amz-Signature=…", "noteText": "Day 3 of climate week: the river is back.", "scheduleTime": "2026-10-03T10:00:00-07:00" }, "settings": { "browser": { "timezone": "America/Los_Angeles" } } } ``` **n8n:** in the HTTP Request node, set Body Content Type to JSON. With Specify Body set to _Using JSON_, write each value as an expression with no quotes around it: `JSON.stringify` adds the quotes and escapes any quote or line break in the text, which a quoted `"{{ $json.note_text }}"` does not. n8n HTTP Request: Specify Body = Using JSON ``` { "input": "On Substack, create a Note with the text in noteText, attach the video at mediaUrl, and schedule it for scheduleTime.", "urls": ["https://substack.com/home"], "variables": { "mediaUrl": {{ JSON.stringify($json.media_url) }}, "noteText": {{ JSON.stringify($json.note_text) }}, "scheduleTime": {{ JSON.stringify($json.schedule_time) }} }, "settings": { "browser": { "timezone": "America/Los_Angeles" } } } ``` With _Using Fields Below_, the body is flat (a field named `variables.mediaUrl` is sent as that literal key), so send `variables` as one JSON string. The API reads it as the object. n8n HTTP Request: Specify Body = Using Fields Below ``` Body Content Type JSON Specify Body Using Fields Below Name Value input Create a Note with the text in noteText, attach the video at mediaUrl, and schedule it for scheduleTime. variables {{ JSON.stringify({ mediaUrl: $json.media_url, noteText: $json.note_text, scheduleTime: $json.schedule_time }) }} ``` The examples pin the browser to `America/Los_Angeles`, the zone the `-07:00` time is written in, so Substack's schedule picker shows 10:00 AM as written (see [Browser time zone and language](#browser-clock)). Fields mode sends each value as text and `settings` must be an object, so pin the clock with _Using JSON_. ### Browser time zone and language (`settings.browser`) Pages show dates and times, and date/time pickers take them, in the cloud browser's own clock. Without a pin, that clock is set when the browser starts, from where its traffic exits at that moment, so it can differ from where a later request exits; a run with a proxy location uses that place's clock. Set a pin whenever times matter (scheduling, bookings). When the location can't be looked up, the browser runs on `America/Chicago` in English (`en-US`), never a random zone. Either way the agent is told the browser's zone, its UTC offset (and the next daylight-saving change) and its local time. It converts a requested time into that clock before typing it into a picker, and says the converted value in the result. `settings.browser.timezone`string IANA time zone for this run, e.g. "Asia/Singapore" or "America/New\_York". An offset ("+08:00") or an abbreviation ("PST", "BST") is a 400 (INVALID\_BROWSER\_TIMEZONE). The agent sees the zone under the name the browser itself uses, so an alias can appear under its canonical name (Asia/Kolkata as Asia/Calcutta). `settings.browser.locale`string Browser language tag, e.g. "en-US" or "pt-BR": navigator.language, Accept-Language and how pages format dates. An unknown language is a 400 (INVALID\_BROWSER\_LOCALE). `precedence`behavior A pin wins over the proxy's location: a mismatch is logged, not refused. Pin one of the two and the other still follows the browser's location. A pinned run can take a few more seconds to start, because the browser is launched on the pinned clock. `continuations & schedules`behavior A continuation keeps the clock its run started with while the run is still paused; one that starts on a fresh browser gets a fresh clock, so pin it if it matters. A schedule created from a run keeps the run's pin. Cloud runs only: in your own Chrome the agent uses your computer's clock. Example: pin the clock to the zone the task's times are in ``` { "input": "Book the 9:30 AM slot on 2026-10-14 (Singapore time) for the dentist.", "urls": ["https://booking.example.com/dentist"], "settings": { "browser": { "timezone": "Asia/Singapore", "locale": "en-SG" } } } ``` ### Tabular inputs (`dataInputs`) `dataInputs`ApiTabularInput\[\] Optional list of tabular inputs to materialize as in-memory sheets. All dataInputs of one request together may hold up to 1,000,000 rows and 5,000,000 cells (rows x columns); a request past that fails with an error naming the input. `dataInputs[].description`string Human-readable description. Used as sheet title in the UI. `dataInputs[].format`"text" | "markdown" | "csv" | "tsv" | "json" | "xlsx" | "parquet" Optional explicit format. If omitted, inferred from file extension or content type. `dataInputs[].inline`string Raw content (CSV/TSV/JSON/text/markdown) embedded directly in the request. For XLSX/Parquet prefer URL or storageRef. `dataInputs[].url`string HTTP(S) URL to fetch as a tabular source (CSV/XLSX/Parquet files up to 16 MB). `dataInputs[].storageRef`StorageReference Advanced: backend-managed GCS object reference when clients upload to storage directly. Up to 16 MB. dataInputs example: CSV (inline) ``` # CSV inline curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Enrich each company with website and description.", "dataInputs": [ { "description": "Companies", "format": "csv", "inline": "company\\nOpenAI\\nDeepMind\\nAnthropic\\n" } ], "response": { "verbosity": "steps" } }' ``` dataInputs example: JSON (inline) ``` # JSON inline (array of objects) curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Infer seniority and return an updated JSON array.", "dataInputs": [ { "description": "Contacts", "format": "json", "inline": "[{\"name\":\"Alice\",\"title\":\"VP Engineering\"},{\"name\":\"Bob\",\"title\":\"Software Engineer\"}]" } ], "response": { "verbosity": "steps" } }' ``` dataInputs example: XLSX (via URL) ``` # XLSX via URL curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Summarize opportunity pipeline from this Excel file.", "dataInputs": [ { "description": "Sales pipeline", "format": "xlsx", "url": "https://example.com/sales-pipeline.xlsx" } ], "response": { "verbosity": "steps" } }' ``` dataInputs example: Parquet (via URL) ``` # Parquet via URL curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Compute daily active users per region from this Parquet dataset.", "dataInputs": [ { "description": "Events parquet", "format": "parquet", "url": "https://example.com/events.parquet" } ], "response": { "verbosity": "steps" } }' ``` ### Tools configuration (`tools`) `tools.enableAdditionalTools`string\[\] Higher-power tool families to enable for this request. `ask_questions``generate_docs``generate_slides``generate_websites``generate_pdfs``pdf_filling``generate_sheets` `tools.userDefined`string\[\] Names of the tools you built under rtrvr.ai/cloud → Tools that this run may call. A tool switched off in the Tools list stays off, even when named here. `tools.mode`stringdefault `profile` Which saved tools load: every saved tool (profile), only tools.userDefined (allowlist), or none. `profile``allowlist``none` Core tools (browser actions, extraction, sheets\_workflow on in-memory sheets, etc.) are always enabled. Additional tools control Docs, Slides, PDFs, persistent Sheets, and explicit ask\_user behavior. **Google Integration Required** To use `generate_sheets`, `generate_docs`, or `generate_slides`: 1. Connect Google Drive in the Cloud account that owns your API key. 2. Enable the Google tools in your API request. The Authorization header contains your rtrvr API key; Google tokens are resolved and refreshed on the server. 3. Select existing files through the Google picker and use a Google account with the required file permissions. To use a different Google authorization, send an explicit authToken in the JSON body on every request, including continuations. Refresh that override yourself. Its failure never falls back to the saved account. Public/site keys cannot use an owner’s saved connection. ### Response configuration (`response`) `response.verbosity`"final" | "steps" | "debug"default `"final"` Controls how much detail you get back. `final``steps``debug` `response.inlineOutputMaxBytes`number Hard cap (in bytes) for inline output blocks. Larger payloads are snapshot to storage and previewed. ### History & continuation (`history`) `continuePlanning`boolean Canonical flag that this call should continue the previous workflow state. Top-level value wins over legacy history.continue. `history.continue`boolean Legacy alias for continuePlanning, accepted for backward compatibility. `history.previousSteps`PlannerPreviousStep\[\] Planner-internal state from previous runs. Returned in response.history for advanced clients. `history.lastToolPreviousSteps`ToolPreviousSteps Tool execution state for the last tool. Used for precise continuations. ### Advanced options `recordingContext`string Id of a recording from rtrvr.ai/cloud → Recordings. The agent follows the recorded walkthrough as its guide for this task. `settings`Partial Per-request overrides of your account settings. Common ones: llmIntegration.model and .reasoningEffort. Set llmIntegration.inferencePolicy to gmi for managed GLM Flash served only through GMI, including supported helper calls, with no alternate-provider fallback. Normal authentication, plan limits and credit billing apply. Other settings include cookieSync.enabled (restore stored sessions from Chrome sync, imports, or earlier cloud sign-ins), proxyConfig.mode, browser.timezone and .locale (the cloud browser's clock, see Browser time zone and language), limits.creditCeiling. Other omitted settings keep the account value; proxy omission uses your profile default, or the managed proxy if none is set. Cloud chat-bar choices only override that chat. Select a saved custom proxy with selectedProxyName or selectedProxyId. `disable_fallbacks`booleandefault `your Disable fallbacks setting` true: this run uses only the selected model, at the reasoning level asked for. A provider serving the same model may still answer, but the run never switches to another model or a lower reasoning level, and your own key never falls back to credits. A step the model cannot finish ends the run with code MODEL\_UNAVAILABLE and modelUnavailable (product, effortRequested, blockedFallback, reason), status "error", or "partial" when it had already produced output; it is not retried. false allows fallbacks for this run while the setting is on. disableFallbacks is accepted too, as are "true", "false", 1, 0, "1" and "0"; any other value is a 400. Shorthand for settings.llmIntegration.disableCreditsFallback; never saved. `options.skipToolsStorageLoad`boolean Internal optimization flag when all tools are provided directly. Most clients should omit. `options.evidence.screenshots`booleandefault `false` true: the agent screenshots every page it takes data from, before leaving it, and tags each record from that page with evidenceArtifactId (the screenshot's artifacts\[\].id). The screenshots come back in artifacts with their page URL, capture time and SHA-256. Records whose shape a schema fixes keep it; match them to screenshots by pageUrl. Any other shape for options.evidence is a 400 (INVALID\_EVIDENCE\_OPTION). See Artifacts below. `settings.proxyConfig.location`{ country, region?, city? } Where Retriever's managed proxy exits for this run: a two-letter ISO country code, plus an optional ISO 3166-2 region part ("NY", "25") and English city name. The run never exits in another country, and the browser's time zone and language follow the exit. The response's egress says where it exited. See Choose where the managed proxy exits below. ### Use a saved proxy from MCP or the API Save your proxy in [Cloud Settings → Proxy Config](/cloud?view=settings). Choose it as your default and save settings to use it across Cloud, API, and MCP. To override for one call, pass its exact name or ID. Credentials stay in your account. ``` { "settings": { "proxyConfig": { "mode": "custom", "selectedProxyName": "My Taiwan proxy" } } } ``` For `cloud_agent` and `cloud_scrape`, put `settings` inside the MCP tool's `arguments` or the tool API's `params`. For `POST /agent` and `POST /scrape`, put it in the request body. A saved `selectedProxyId` can replace `selectedProxyName`. - Omit `proxyConfig` to use your profile default, falling back to Retriever's managed proxy when none is set. Use `{"mode":"default"}` to explicitly choose the managed proxy. - The Cloud chat-bar selection overrides routing for that chat without changing your profile default. Choose “Use my default route” to reset it. MCP `list` with `kind: "proxies"` shows saved proxies and marks the default; managed proxy connection details remain private. - Use `{"mode":"none"}` for a direct cloud connection. - Saved names are case-sensitive. Unknown names and IDs fail; duplicate names require an ID. If both selectors are supplied, they must identify the same proxy. - Schedules created from a run retain its routing choice. Permission to use another route belongs to the schedule, so a one-run fallback does not enable it. You can also provide a proxy for just one request. Use an HTTP or HTTPS proxy that supports CONNECT; keep credentials out of shared snippets and client-side code. ``` { "settings": { "proxyConfig": { "mode": "custom", "selectedProxyId": "request-proxy", "customProxies": [ { "id": "request-proxy", "host": "proxy.example.net", "port": 8080, "scheme": "http", "username": "YOUR_USERNAME", "password": "YOUR_PASSWORD" } ] } } } ``` ### Go out through your own computer with Tailscale A Tailscale tunnel sends a cloud run's traffic out through a computer you own, so sites see your home connection. It uses no proxy credits. Once saved, choose it like any saved proxy: as your default, in the chat bar, or by its exact name or ID with `{"mode":"custom"}`. Tailscale connection failures retry once, then stop before the task starts. To allow managed fallback for an API request, send `settings.proxyConfig.tailscaleFallback: "managed"`. Omit it or use `"stop"` to stay on Tailscale. Fallback uses a different IP and normal proxy charges apply. [Set up a Tailscale tunnel](/docs/tailscale): the steps, the limits, and parallel runs. ### Choose where the managed proxy exits Add `location` to Retriever's managed proxy to run from a country, and optionally a region or city in it. The cloud browser's time zone and language follow the exit, so sites show dates, prices and pages the way a local visitor sees them. ``` { "settings": { "proxyConfig": { "mode": "default", "location": { "country": "IT", "city": "Milan" } } } } ``` - One field may list up to 5 places for an exit in any of them: countries (`{"country": ["IT", "FR", "DE"]}`, with no region or city), regions of one country (`{"country": "US", "region": ["CA", "WA"]}`, with no city) or cities of one country (`{"country": "IT", "city": ["Milan", "Rome"]}`). A comma-separated string such as `"IT,FR,DE"` works too. `egress` names the country the run used. - The result's `egress` says where the run exited, for example `{"country":"IT","city":"Milan","timezone":"Europe/Rome"}`. `relaxed: true` means the city or region had no exit and the run used more of the country. - A location goes only with the managed proxy (`mode: "default"`, which it implies when you leave `mode` out). Next to a saved proxy or `"none"` the call is refused. - Same field everywhere: `settings.proxyConfig.location` on `POST /agent` and `POST /scrape`, and on the MCP tools `cloud_agent` and `cloud_scrape`. MCP and the tool API also take the shorthand `proxy_location`, such as `"proxy_location": "IT"`, `"proxy_location": "IT,FR,DE"` or `"proxy_location": {"country": "US", "region": "NY"}`; with `agent` or `scrape` it runs the task in the cloud browser. - Save a location under [Cloud Settings → Proxy Config](/cloud?view=settings) next to the managed default to use it for every run that names no route, schedules included. In the Cloud chat bar, pick Retriever managed proxy and set Location for that chat only. - A few hosts that always connect directly from the cloud, such as some government sites and file storage, do not use the location. ### Supported locations A location names a country, and optionally a region or city in it. Each field takes one value, or a list of up to 5 for an exit in any of them. Field Format Examples `country` Two-letter ISO 3166-1 code (`UK` is read as `GB`). A list of countries takes no region or city. `IT`, `US`, `["IT", "FR", "DE"]` `region` Optional. The part after the dash of an ISO 3166-2 code in that country. A list of regions takes no city. `NY` for US-NY, `25` for IT-25 (Lombardy) `city` Optional. The city's English name, in that country. `Milan`, `New York`, `["Milan", "Rome"]` If the city has no exit, the run tries its region, then the whole country. It never moves to another country. If none of the countries you asked for has an exit, the run does not start and the call returns `503 PROXY_LOCATION_UNAVAILABLE` with a message that says so. Availability is live: exits come and go with the residential pool, and every run checks its own location before it starts. `GET https://api.rtrvr.ai/proxy-locations` with your API key returns the country list below, with the date each country was checked, the format and the fallback rule. To check a region, a city or a list right now, send `POST https://api.rtrvr.ai/proxy-location/check` with `{"location": {"country": "IT", "city": "Milan"}}`. It answers `{"available": true, "egress": {...}}` with where a run would exit, or `{"available": false, "message": "..."}`. Cloud Settings and the chat bar run the same check and only take places that have an exit. 120 countries had an exit when checked on 11 November 2026 - Åland Islands `AX` - Albania `AL` - American Samoa `AS` - Andorra `AD` - Anguilla `AI` - Antigua & Barbuda `AG` - Argentina `AR` - Armenia `AM` - Aruba `AW` - Australia `AU` - Austria `AT` - Azerbaijan `AZ` - Bahamas `BS` - Bahrain `BH` - Barbados `BB` - Belarus `BY` - Belgium `BE` - Belize `BZ` - Bermuda `BM` - Bosnia & Herzegovina `BA` - Brazil `BR` - British Virgin Islands `VG` - Bulgaria `BG` - Canada `CA` - Caribbean Netherlands `BQ` - Cayman Islands `KY` - Chile `CL` - China `CN` - Colombia `CO` - Costa Rica `CR` - Côte d’Ivoire `CI` - Croatia `HR` - Curaçao `CW` - Cyprus `CY` - Czechia `CZ` - Denmark `DK` - Dominica `DM` - Dominican Republic `DO` - Egypt `EG` - Equatorial Guinea `GQ` - Estonia `EE` - Falkland Islands `FK` - Faroe Islands `FO` - Finland `FI` - France `FR` - French Guiana `GF` - French Polynesia `PF` - Gabon `GA` - Georgia `GE` - Germany `DE` - Gibraltar `GI` - Greece `GR` - Greenland `GL` - Grenada `GD` - Guadeloupe `GP` - Guam `GU` - Guernsey `GG` - Hungary `HU` - Iceland `IS` - India `IN` - Iran `IR` - Ireland `IE` - Isle of Man `IM` - Israel `IL` - Italy `IT` - Jamaica `JM` - Japan `JP` - Jersey `JE` - Kazakhstan `KZ` - Kuwait `KW` - Latvia `LV` - Lithuania `LT` - Luxembourg `LU` - Malta `MT` - Martinique `MQ` - Mexico `MX` - Moldova `MD` - Monaco `MC` - Montenegro `ME` - Montserrat `MS` - Namibia `NA` - Netherlands `NL` - New Zealand `NZ` - North Macedonia `MK` - Norway `NO` - Oman `OM` - Palestinian Territories `PS` - Panama `PA` - Peru `PE` - Philippines `PH` - Poland `PL` - Portugal `PT` - Puerto Rico `PR` - Qatar `QA` - Romania `RO` - San Marino `SM` - Saudi Arabia `SA` - Serbia `RS` - Seychelles `SC` - Sint Maarten `SX` - Slovakia `SK` - Slovenia `SI` - South Korea `KR` - Spain `ES` - St. Kitts & Nevis `KN` - St. Lucia `LC` - St. Martin `MF` - St. Vincent & Grenadines `VC` - Sweden `SE` - Switzerland `CH` - Taiwan `TW` - Trinidad & Tobago `TT` - Türkiye `TR` - Turks & Caicos Islands `TC` - U.S. Virgin Islands `VI` - Ukraine `UA` - United Arab Emirates `AE` - United Kingdom `GB` - United States `US` - Uruguay `UY` 129 countries had no exit on 11 November 2026 These codes are accepted, but a run that asks only for them is refused until an exit appears. Check one before you rely on it, or list it with a country that has an exit. - Afghanistan `AF` - Algeria `DZ` - Angola `AO` - Antarctica `AQ` - Bangladesh `BD` - Benin `BJ` - Bhutan `BT` - Bolivia `BO` - Botswana `BW` - Bouvet Island `BV` - British Indian Ocean Territory `IO` - Brunei `BN` - Burkina Faso `BF` - Burundi `BI` - Cambodia `KH` - Cameroon `CM` - Cape Verde `CV` - Central African Republic `CF` - Chad `TD` - Christmas Island `CX` - Cocos (Keeling) Islands `CC` - Comoros `KM` - Congo - Brazzaville `CG` - Congo - Kinshasa `CD` - Cook Islands `CK` - Cuba `CU` - Djibouti `DJ` - Ecuador `EC` - El Salvador `SV` - Eritrea `ER` - Eswatini `SZ` - Ethiopia `ET` - Fiji `FJ` - French Southern Territories `TF` - Gambia `GM` - Ghana `GH` - Guatemala `GT` - Guinea `GN` - Guinea-Bissau `GW` - Guyana `GY` - Haiti `HT` - Heard & McDonald Islands `HM` - Honduras `HN` - Hong Kong SAR China `HK` - Indonesia `ID` - Iraq `IQ` - Jordan `JO` - Kenya `KE` - Kiribati `KI` - Kyrgyzstan `KG` - Laos `LA` - Lebanon `LB` - Lesotho `LS` - Liberia `LR` - Libya `LY` - Liechtenstein `LI` - Macao SAR China `MO` - Madagascar `MG` - Malawi `MW` - Malaysia `MY` - Maldives `MV` - Mali `ML` - Marshall Islands `MH` - Mauritania `MR` - Mauritius `MU` - Mayotte `YT` - Micronesia `FM` - Mongolia `MN` - Morocco `MA` - Mozambique `MZ` - Myanmar (Burma) `MM` - Nauru `NR` - Nepal `NP` - New Caledonia `NC` - Nicaragua `NI` - Niger `NE` - Nigeria `NG` - Niue `NU` - Norfolk Island `NF` - North Korea `KP` - Northern Mariana Islands `MP` - Pakistan `PK` - Palau `PW` - Papua New Guinea `PG` - Paraguay `PY` - Pitcairn Islands `PN` - Réunion `RE` - Russia `RU` - Rwanda `RW` - Samoa `WS` - São Tomé & Príncipe `ST` - Senegal `SN` - Sierra Leone `SL` - Singapore `SG` - Solomon Islands `SB` - Somalia `SO` - South Africa `ZA` - South Georgia & South Sandwich Islands `GS` - South Sudan `SS` - Sri Lanka `LK` - St. Barthélemy `BL` - St. Helena `SH` - St. Pierre & Miquelon `PM` - Sudan `SD` - Suriname `SR` - Svalbard & Jan Mayen `SJ` - Syria `SY` - Tajikistan `TJ` - Tanzania `TZ` - Thailand `TH` - Timor-Leste `TL` - Togo `TG` - Tokelau `TK` - Tonga `TO` - Tunisia `TN` - Turkmenistan `TM` - Tuvalu `TV` - U.S. Outlying Islands `UM` - Uganda `UG` - Uzbekistan `UZ` - Vanuatu `VU` - Vatican City `VA` - Venezuela `VE` - Vietnam `VN` - Wallis & Futuna `WF` - Western Sahara `EH` - Yemen `YE` - Zambia `ZM` - Zimbabwe `ZW` A location costs nothing extra. Managed proxy traffic is billed per GB, about 500 credits per GB ([pricing](/pricing)), the same with or without a location. ### Page-read timing Both `/agent` and `/scrape` open supplied URLs immediately and return page data as soon as it is ready. Configure timing under `settings.extractionConfig`. Request values override your saved profile. The defaults below apply when neither sets a value. - `totalBudgetMs`: one deadline for initial navigation, readiness, extraction, and fallback. Default: **15000**. Values are bounded to **1500–30000** milliseconds. This is a maximum, not a mandatory wait. - `pageLoadDelay`: an optional minimum wait before capture for pages that render content late. Default: **0**. A positive value deliberately waits even if the page becomes ready sooner. It consumes the total budget and is shortened if needed to leave time for extraction and fallback. - `maxParallelTabs`: up to **8** cloud tabs load together (default and maximum: **8**). Set a lower value to load fewer at once, or **1** for sequential reads. Each active batch gets a fresh page-read budget, so a large batch of URLs can take longer than one budget. Return when ready, with up to 15 seconds for the initial read ``` { "settings": { "extractionConfig": { "totalBudgetMs": 15000, "pageLoadDelay": 0 } } } ``` For a page that needs a known 10-second rendering wait, set `pageLoadDelay: 10000`and `totalBudgetMs: 20000`. That leaves roughly 10 seconds for the remaining read work. The delay is not added on top of the deadline. Set `pageLoadDelay: 0` explicitly to override a saved profile delay. At the deadline, a read returns the available tree or a text fallback. If neither is readable, it reports an unreadable page rather than successful empty extraction. Text-only scrapes return text without a tree. An agent with no URLs starts with an empty page immediately; `/scrape` requires at least one URL. This deadline covers page reads, not browser provisioning, model execution, or the whole API request. Later agent captures keep their normal 8-second default unless you set a budget. Cancellation can interrupt a running job. Keep the caller timeout long enough for all batches and agent work; after a lost response, recover by trajectory ID before retrying. ### Spend guard (`maxCredits`, `options.limits`) Every run carries a credit ceiling so a task that loops or crawls further than expected can't burn credits unattended — 100 credits unless you saved another value in Settings. Set `maxCredits` on a call to give that run its own budget: higher for a big job you launch knowingly, lower to cap a small one. `maxCredits`numberdefault `user setting, else 100 (25 on Free)` Credit budget for this run. Shorthand for options.limits.creditCeiling.credits, and it wins when both are sent. max\_credits (the MCP spelling) is accepted too. A value that is not a positive number is a 400 (INVALID\_MAX\_CREDITS). `options.limits.creditCeiling.credits`numberdefault `user setting, else 100 (25 on Free)` Credits this run may spend before it stops to check in. `options.limits.creditCeiling.onExceed`"pause" | "stop" | "off"default `"stop" for trigger.type "schedule", else "pause"` pause finalizes requires\_input with a Continue/Stop question and a resume descriptor, so a caller can decide programmatically; stop finalizes with the work done so far; off disables the check for this run. `pause``stop``off` A paused run fires the `rtrvr.execution.requires_input` webhook and returns the usual resume descriptor, with the question keyed `credit_ceiling_continue`. Answering `"Continue"` grants a fresh budget and continues from the stored trajectory — no work is repeated; `"Stop here"` ends the run with what it produced. ### UI & VNC options (`options.ui`) Enable live browser viewing via VNC. Perfect for debugging, demos, or embedding real-time browser sessions in your app. `options.ui.enableVnc`booleandefault `false` Enable VNC live view for this execution. When true, you can retrieve an embeddable URL to watch the browser in real-time. `options.ui.vncScope`"root" | "all"default `"root"` Controls which browser sessions are visible. 'root' shows only the main browser. 'all' includes batch worker browsers when using parallel execution. `root``all` `options.ui.emitEvents`booleandefault `false` Opt-in only. When true, execution progress events are written to Firestore for SSE/polling clients. If omitted/false, no execution event stream is written. **emitEvents policy:** API and extension/MCP executions only emit events when`options.ui.emitEvents: true`. CLI streaming defaults on for `run`, `agent`, and `scrape` (use `--no-stream` to disable). Streamed payloads at or under 1MB stay inline; larger payloads include inline preview markers and storage references (\`outputRef\` / \`resultRef\` / \`responseRef\`) for full downloads. **Quick Start:** To embed a live browser view, set `options.ui.enableVnc: true`, then call `POST /vnc/share` to get an iframe-ready URL. See the [VNC Live View section](#vnc-live-view) for full details. ### Webhooks (`webhooks`) Get notified when your workflow completes via HTTP webhooks. Up to 5 webhooks per request. Webhooks are delivered asynchronously via Google Cloud Tasks with best-effort delivery and automatic retries. `webhooks[].url`string**required** Webhook endpoint URL. HTTPS required in production. HTTP allowed for localhost development. `webhooks[].events`string\[\] Events to subscribe to. If omitted, all events are delivered. `rtrvr.execution.succeeded``rtrvr.execution.failed``rtrvr.execution.cancelled``rtrvr.execution.requires_input` `webhooks[].secret`string HMAC secret for request signing. If set, requests include X-Rtrvr-Signature header with format: t=timestamp,v1=hmac\_sha256 `webhooks[].auth`object Authentication config. Supports Bearer token ({ type: 'bearer', token: '...' }) or Basic auth ({ type: 'basic', username: '...', password: '...' }) `webhooks[].headers`Record Custom headers to include in webhook requests `webhooks[].timeoutMs`numberdefault `8000` Request timeout in milliseconds (1000-30000) `webhooks[].retry`objectdefault `{ mode: "default" }` Retry policy. 'default' retries on failure, 'none' disables retries Webhook subscription example ``` // Webhook request example curl -X POST "https://api.rtrvr.ai/agent" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Scrape the homepage and summarize it", "urls": ["https://example.com"], "webhooks": [ { "url": "https://your-server.com/webhook", "events": ["rtrvr.execution.succeeded", "rtrvr.execution.failed"], "secret": "your-signing-secret", "headers": { "X-Custom-Header": "my-value" } } ] }' ``` #### Webhook Payload When an event triggers, rtrvr sends a POST request with this envelope: Webhook payload envelope ``` { "id": "whd_abc123", // Unique delivery ID "event": "rtrvr.execution.succeeded", "createdAt": "2025-01-15T10:30:00.000Z", "data": { "trajectoryId": "exec_xyz789", "status": "success", "taskRef": "gs://bucket/user-tasks/uid/exec_xyz789/workflow.json", "responseRef": { ... }, // Full response snapshot when > 1MB "output": { ... }, // Inline preview payload "outputRef": { ... }, // Optional large output download reference "resultRef": { ... }, // Optional large result download reference "artifacts": { // The run's files, by kind (absent when none) "images": [{ "id": "…", "name": "…", "url": "…", "mimeType": "image/png", "kind": "screenshot" }], "pdfs": [{ "id": "…", "name": "…", "url": "…" }], "files": [{ "id": "…", "name": "…", "url": "…" }] }, "usage": { "creditsUsed": 0.15, "creditsLeft": 99.85 } } } ``` #### Signature Verification If you provide a `secret`, verify the signature: Verify X-Rtrvr-Signature ``` // Node.js signature verification const crypto = require('crypto'); function verifyWebhook(payload, signature, secret) { const [tPart, v1Part] = signature.split(','); const timestamp = tPart.split('=')[1]; const receivedSig = v1Part.split('=')[1]; const signedPayload = timestamp + '.' + JSON.stringify(payload); const expectedSig = crypto .createHmac('sha256', secret) .update(signedPayload) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(receivedSig), Buffer.from(expectedSig) ); } ``` **Response metadata:** The API response includes `metadata.webhooks: { requested: number, attempted: number }` showing how many webhooks were configured and enqueued. **Store & reuse webhooks** Save your webhook endpoints in [Cloud → Webhooks](/cloud?view=webhooks) to quickly attach them to any execution without re-entering the URL, secret, and events each time. Provide `urls` to open the starting pages before planning. Without URLs, the agent starts with empty page data and chooses where to go. Save a unique `trajectoryId` before dispatch. If the response is lost, use `GET /executions/TRAJECTORY_ID` with the same API key to read its status and saved result. Use `GET /executions` for history and `POST /agent/cancel` with `{"trajectoryId":"YOUR_TRAJECTORY_ID"}` to cancel. MCP `list_executions`, `check_results`, and `cancel_execution` use the same ID without requiring an extension device. Read the [recovery and cancellation contract](/docs/scrape#recovery) before retrying an unknown run. ### Cancelling a run In the dashboard, open [Executions](/cloud?view=executions) and choose **Cancel** on the run. Every running cloud run offers it, whether the chat, this API, MCP, a schedule or a webhook started it. From code, post the run's `trajectoryId` to `/agent/cancel` with the same API key. The run stops within seconds, and the request still waiting on it returns `status: "cancelled"` (HTTP 200, or 499 `REQUEST_ABORTED` if the run had not started planning). Steps it already took stay done, and the credits they used are charged. A run that already finished is left as it was, and the reply carries its status. Cancel a run ``` curl -X POST https://api.rtrvr.ai/agent/cancel \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"trajectoryId":"YOUR_TRAJECTORY_ID"}' ``` **n8n:** stopping an n8n execution does not close the requests it already sent, so their runs keep going until you cancel them. To cancel from a workflow, send your own `trajectoryId` with each request (8 to 160 letters, digits, `_`, `:` or `-`, new for every request), for example `"trajectoryId": "n8n-{{ $execution.id }}-{{ $itemIndex }}"`, and post it to `/agent/cancel` from an HTTP Request node. Every call returns an `AgentApiResponse`: AgentApiResponse (conceptual) ``` interface AgentApiResponse { protocol: { name: 'rtrvr.agent'; version: string; compatibleWith: Array<'a2w.run' | 'a2a.task'>; }; run: { id: string; trajectoryId: string; executionId?: string; status: 'success' | 'partial' | 'error' | 'cancelled' | 'requires_input' | 'executing' | 'requires_tool'; phase: number; }; success: boolean; status: 'success' | 'partial' | 'error' | 'cancelled' | 'requires_input' | 'executing'; trajectoryId: string; phase: number; // Rich output blocks output: ApiOutputBlock[]; // Note: in debug mode, tool_result blocks may include outputRef/resultRef // when large per-step payloads are stored out-of-line. // Convenience view of final output result?: { text?: string; json?: any; }; // Present when verbosity !== 'final' steps?: ApiStepSummary[]; // Every file the run made: screenshots, generated images, PDFs and other // files, each with a signed download URL. Always an array; [] when none. artifacts: Array<{ id: string; // what evidenceArtifactId in your data refers to kind: 'screenshot' | 'image' | 'pdf' | 'file'; name: string; title?: string; mimeType: string; sizeBytes?: number; url: string; // signed; works until expiresAt expiresAt?: string; // 7 days; renew with GET /artifacts/:trajectoryId stepId?: string; // the run step that made it pageUrl?: string; // the page a screenshot shows capturedAt?: string; // ISO time it was captured sha256?: string; // hex SHA-256 of the file's bytes }>; usage: { creditsUsed: number; creditsLeft?: number; currentCreditsUsed?: number; expiryReason?: string; }; metadata: { taskRef: string; inlineOutputMaxBytes: number; toolsUsed: string[]; outputTooLarge?: boolean; responseRef?: StorageReference; }; warnings?: string[]; error?: string; // Where the managed proxy exited (absent without it). requested/relaxed // appear when settings.proxyConfig.location pinned a place. egress?: { country: string; // ISO 3166-1 alpha-2 countries?: string[]; // every exit country, when more than one region?: string; city?: string; timezone?: string; // the browser ran on this time zone requested?: { country: string; region?: string; city?: string }; relaxed?: boolean; // the city or region had no exit }; // Continuation payload for advanced clients inputRequest?: { reason: string; questions?: PlannerQuestion[]; expiresAt?: string; resume: { executionId: string; continuePlanning: true; phase: number; method?: 'POST'; path?: string; expiresAt?: string; }; browser?: { parkStatus?: 'parked' | 'reused' | 'restored' | 'expired' | 'unavailable'; ttlMs?: number; expiresAt?: string; liveReuseAvailable?: boolean; }; }; history?: { previousSteps?: PlannerPreviousStep[]; lastToolPreviousSteps?: ToolPreviousSteps; }; browser?: { parkStatus?: string; expiresAt?: string; resumedFromPark?: boolean; restoredFromVault?: boolean; activeOrigin?: string; tabCount?: number; }; } ``` ### Output blocks & result The low-level `output` is an array of blocks: `output[].type`"text" | "json" | "tool\_result" Block type: final text, JSON payload, or detailed tool result (debug mode). `output[].text`string Present when type = 'text'. `output[].data`any Present when type = 'json'. `output[].tool_result`… When type = 'tool\_result', includes stepId, toolName, args, inline output preview, optional outputRef/resultRef, thought, etc. Only present when verbosity = 'debug'. `result.text` is the concatenation of all text blocks. `result.json` is either the single JSON block, or an array of JSON blocks if the workflow produced multiple. ### Steps & usage When `response.verbosity` is `"steps"` or `"debug"`, you also get `steps: ApiStepSummary[]`: `steps[].toolName`string Which tool ran in this step (e.g. 'sheets\_workflow', 'act\_on\_tab'). `steps[].status`ExecutionStatus success, error, executing, etc. per step. `steps[].duration`number Execution time in ms for this step (when available). `steps[].creditsUsed`number Credits consumed by this step, useful for analytics. `steps[].hasOutput`boolean Whether this step produced output or an outputRef. `steps[].hasSheets`boolean Whether this step produced or touched tabular data. `steps[].hasGeneratedContent`boolean Whether this step generated external content (docs, slides, etc.). `usage` mirrors your credit accumulator and is ideal for per-customer dashboards and server-side cost control. ### Artifacts (screenshots, PDFs, files) `artifacts` lists every file the run made, at any verbosity: screenshots, generated images, PDFs and other files. Each entry has a signed `url` that works for 7 days, until `expiresAt`. Download what you need to keep. Google Docs, Slides and Sheets are links, not files, so they are not listed here. `artifacts[].id`string Stable id of the file. With options.evidence.screenshots, records carry it as evidenceArtifactId. `artifacts[].kind`"screenshot" | "image" | "pdf" | "file" screenshot: a capture of a page; image: any other picture the run made. `artifacts[].url`string Signed download URL. Treat it like a password: anyone with it can read the file until it expires. `artifacts[].expiresAt`string (ISO) When url stops working. Get fresh URLs with GET /artifacts/:trajectoryId. `artifacts[].pageUrl`string The page the file came from (a screenshot's tab URL), when known. `artifacts[].capturedAt`string (ISO) When the file was captured or made. `artifacts[].sha256`string Hex SHA-256 of the stored bytes, to check a download or record it as evidence. `artifacts[].stepId`string The run step that made the file. A run with options.evidence.screenshots: true ``` { "success": true, "status": "success", "result": { "json": { "records": [ { "permitId": "B-2291", "status": "Issued", "evidenceArtifactId": "e19b6d1f-b5fb-46f3-b76e-f092b25424ba" } ] } }, "artifacts": [ { "id": "e19b6d1f-b5fb-46f3-b76e-f092b25424ba", "kind": "screenshot", "name": "screenshot_tab1914814576_1794379394825.png", "mimeType": "image/png", "sizeBytes": 81687, "url": "https://storage.googleapis.com/…/screenshot_tab1914814576_1794379394825.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&…", "expiresAt": "2026-11-18T06:43:31.000Z", "stepId": "9d87c9a7-f4a5-4446-a07e-a2874e4098f2", "pageUrl": "https://permits.example.gov/records?id=B-2291", "capturedAt": "2026-11-11T06:43:14.509Z", "sha256": "45babf0eaba0fb3a87216ae6150a56f1d34988a92c6db0a548d07f773e94f33f" } ] } ``` Links expire. Fetch fresh ones for a finished run with the same API key; only the run's owner can read them: Renew artifact URLs ``` curl https://api.rtrvr.ai/artifacts/YOUR_TRAJECTORY_ID \ -H "Authorization: Bearer YOUR_API_KEY" # → { "success": true, "trajectoryId": "…", "artifacts": [ …same entries, fresh url and expiresAt… ] } ``` ### Large output handling When the full response exceeds `inlineOutputMaxBytes`: - • The full response is snapshot to storage under `metadata.responseRef`. - • The inline `output`/`result` fields remain as preview content for UX. - • Debug `tool_result` blocks may include `outputRef` / `resultRef` for full per-step payloads. - • `metadata.outputTooLarge` is set to `true`. Client pattern: render the preview for UX, but fetch `responseRef.downloadUrl` from your backend when you need the full payload. ### status & success `status`"success" | "partial" | "error" | "cancelled" | "requires\_input" | "executing" Execution-level status. success implies success = true; all others imply success = false. - • `"success"` – Final result is available in `result` and `output`. - • `"partial"`: The run retained useful output but did not meet every completion requirement. Read `completion.reasonCode` and `completion.missing`. A forced Sheets destination without a confirmed data write reports `SHEETS_DELIVERY_UNCONFIRMED`. - • `"error"` – Workflow failed. You still get `usage`, `steps` (if enabled), and partial output if any. With Disable fallbacks on (`disable_fallbacks: true` or the setting), a step the selected model could not finish ends the run here (or as `"partial"` when it had already produced output) with `code: "MODEL_UNAVAILABLE"` and `modelUnavailable` (`product`, `effortRequested`, `blockedFallback`, `reason`) instead of switching to another model or a lower reasoning level. Do not retry it as is: try later, or send `disable_fallbacks: false`. - • `"cancelled"` – The run was [cancelled](#cancel) (Executions → Cancel, `POST /agent/cancel`, MCP `cancel_execution`) or the client disconnected. Credits are charged for the work done. - • `"requires_input"` – Planner paused because it needs human answers. Read `inputRequest` for questions, resume ids, and browser park expiry. Responses include an additive `protocol.name = "rtrvr.agent"` envelope so A2W/A2A-style clients can map runs, messages, output, history, and input requests consistently. Legacy fields remain top-level for existing clients. **Continuation pattern:** 1. When you see `status: "requires_input"`, surface your own UI to collect missing info. 2. On the next call, send `inputRequest.resume.executionId` as the same `trajectoryId`, set `continuePlanning = true`, and pass back the returned `history`. 3. If `inputRequest.browser.liveReuseAvailable` is true, resume before `inputRequest.expiresAt` to continue in the same live browser; otherwise the agent restores cookies and the last active URL. Control how the agent interacts with existing Google Sheets, Docs, Slides, and PDF templates. Instead of creating new artifacts each time, you can append to or update existing ones. **Google authorization:** API-key requests use the saved Google connection belonging to the API key owner. Connect Google Drive at [rtrvr.ai/cloud → Sheets](https://rtrvr.ai/cloud). Select existing files through the Google picker and use an account with edit access. A pasted file ID does not grant access. API requests and Cloud schedules refresh saved Google authorization on the server. An explicit API authToken overrides the saved connection for that request. **Use cases:** - Append scraped leads to an existing Google Sheet - Add new sections to a running Google Doc report - Build a presentation incrementally across multiple runs - Fill PDF forms using a template ### Mode options `reuseArtifacts.mode`"off" | "auto" | "force"default `"off"` Controls reuse behavior. 'off' disables configured reuse. 'auto' prefers configured targets while respecting an explicitly requested destination. 'force' requires the configured targets; a configured Sheets target also requires a confirmed data write before completion. `"off"` Disable configured artifact reuse (default) `"auto"` Prefer configured targets `"force"` Require configured targets ### Google Sheets Write results to an existing Google Sheets spreadsheet. Requires `generate_sheets` in `enableAdditionalTools`. `targets.sheets.sheetId`string**required** The Google Sheets ID (from the URL: docs.google.com/spreadsheets/d/{sheetId}/edit) `targets.sheets.tabTitle`string SAME\_TAB: the actual tab name in any language. NEW\_TAB: optional name prefix, up to 70 characters without \[ \] : \* ? / or backslash. `targets.sheets.tabId`number SAME\_TAB: stable numeric gid, including 0. Takes precedence over tabTitle and follows tab renames. A missing ID fails validation. Omit for NEW\_TAB. `targets.sheets.tabMode`"SAME\_TAB" | "NEW\_TAB"default `"SAME_TAB"` SAME\_TAB writes to the selected existing tab. NEW\_TAB creates one tab per run when data is written, with a run-specific suffix. Without a tab ID, the runtime resolves an exact name or a unique case-insensitive match. A missing/default Sheet1 name can resolve to the only tab. Ambiguous choices and missing custom names fail validation. Select an actual tab instead of translating its name or assuming an English default. Forced extracted-data writes use `RAW` values to preserve date strings, decimal strings, leading zeros, and multilingual text. Custom append helpers can select `valueInputOption`; intentional formula updates use `updateRange` with `allowFormulas: true`. See the [Sheets helper reference](/docs/tool-calling#google-sheets) and Google's [value input rules](https://developers.google.com/workspace/sheets/api/reference/rest/v4/ValueInputOption). A forced Sheets target completes only after Google confirms a data write. A local fallback, extracted rows, or a model's success message is insufficient. An unconfirmed write produces `status: "partial"`, `success: false`, and `completion.reasonCode: "SHEETS_DELIVERY_UNCONFIRMED"` while retaining the output. This also applies to zero-row results. Errors and cancelled runs retain their failure status. Identical forced appends are deduplicated within a running request. There is no exactly-once guarantee across process restarts or new runs. After a timeout or lost write response, inspect the destination before rerunning. Cloud schedules additionally check destination access before starting the workflow; see [schedule setup](/docs/schedules#save-scheduled-results-to-google-sheets). Example: Append leads to existing sheet ``` { "input": "Scrape new leads and add them to my tracking sheet", "urls": ["https://linkedin.com/search/results/people?keywords=CTO"], "reuseArtifacts": { "mode": "force", "targets": { "sheets": { "sheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms", "tabTitle": "Leads", "tabMode": "SAME_TAB" } } }, "tools": { "enableAdditionalTools": ["generate_sheets"] } } ``` ### Google Docs Append content to or overwrite an existing Google Doc. Requires `generate_docs` in `enableAdditionalTools`. `targets.docs.docId`string**required** The Google Docs ID (from the URL: docs.google.com/document/d/{docId}/edit) `targets.docs.mode`"APPEND" | "OVERWRITE"default `"APPEND"` APPEND adds new content at the end. OVERWRITE replaces the entire document content. Example: Append research notes to existing doc ``` { "input": "Summarize this article and add it to my research notes", "urls": ["https://example.com/ai-research-paper"], "reuseArtifacts": { "mode": "force", "targets": { "docs": { "docId": "1abc123xyz_your_doc_id_here", "mode": "APPEND" } } }, "tools": { "enableAdditionalTools": ["generate_docs"] } } ``` ### Google Slides Add slides to an existing presentation or overwrite it entirely. Requires `generate_slides` in `enableAdditionalTools`. `targets.slides.presentationId`string**required** The Google Slides presentation ID (from the URL) `targets.slides.mode`"APPEND" | "OVERWRITE"default `"APPEND"` APPEND adds new slides at the end. OVERWRITE replaces all slides. Example: Add slides to existing presentation ``` { "input": "Create 3 slides summarizing the key metrics from this page", "urls": ["https://example.com/quarterly-report"], "reuseArtifacts": { "mode": "force", "targets": { "slides": { "presentationId": "1xyz789_your_presentation_id", "mode": "APPEND" } } }, "tools": { "enableAdditionalTools": ["generate_slides"] } } ``` ### PDF Form Filling Fill a PDF form template with data. Requires `pdf_filling` in `enableAdditionalTools`. `targets.pdfs.templateFileId`string Google Drive file ID of the PDF template to fill. The template should have fillable form fields. Example: Fill a PDF form ``` { "input": "Fill out this job application form with the candidate data", "files": [ { "displayName": "candidate-data.json", "uri": "https://firebasestorage.googleapis.com/.../data.json", "mimeType": "application/json" } ], "reuseArtifacts": { "mode": "force", "targets": { "pdfs": { "templateFileId": "1abc_pdf_template_file_id" } } }, "tools": { "enableAdditionalTools": ["pdf_filling"] } } ``` ### Combined Example: Multi-artifact workflow You can target multiple artifact types in a single request: Example: Update both Sheet and Doc ``` { "input": "Scrape competitor pricing, add to my tracking sheet, and append a summary to my report doc", "urls": ["https://competitor.com/pricing"], "reuseArtifacts": { "mode": "force", "targets": { "sheets": { "sheetId": "1abc_sheets_id", "tabTitle": "Competitor Pricing", "tabMode": "SAME_TAB" }, "docs": { "docId": "1xyz_docs_id", "mode": "APPEND" } } }, "tools": { "enableAdditionalTools": ["generate_sheets", "generate_docs"] } } ``` **Important notes:** - You must have edit access to the target Google artifacts - API-key requests use the key owner’s connected Google account, or the account authorized by an explicit authToken override - For Sheets, new data is typically appended below existing rows - Use `mode: "force"` to guarantee the specified targets are used rtrvr supports **view-only live VNC streaming** for any execution. Watch the browser in real-time, embed it in your app via iframe, or build custom viewers using the VNC websocket URL. **Use Cases** - • **Debugging:** Watch exactly what the browser is doing during automation - • **Demos:** Show clients real-time browser activity - • **Dashboards:** Embed live views in internal tools - • **Quality assurance:** Monitor batch jobs visually ### Key Concepts `trajectoryId = executionId` In VNC endpoints, `executionId` refers to your `trajectoryId`. They are the same identifier. `vncScope` `"root"` = main browser only (default). `"all"` = main + all batch worker browsers. `shareKey` A secret token for public/share endpoints. Anyone with it can view (not control) the session until it expires. `Sessions` `root` = main browser session. `batch` = worker sessions (when vncScope="all"). ### Step 1: Enable VNC on Execution Add `options.ui.enableVnc: true` to your execute request. **Pro tip:** Generate your own `trajectoryId` upfront so you can request the embed URL immediately without waiting for the response. Enable VNC on execution ``` curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "trajectoryId": "0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1", "input": "Go to example.com and summarize the homepage", "urls": ["https://example.com"], "options": { "ui": { "enableVnc": true, "vncScope": "root" } } }' ``` ### Step 2: Get the Embed URL Call `POST /vnc/share` with the `executionId` (same as your trajectoryId). This returns an `embedUrl` ready for iframe embedding. POST`https://api.rtrvr.ai/vnc/share` `executionId`string**required** The trajectoryId from your execute request `rotate`booleandefault `false` Set true to generate a new share key (invalidates previous share URLs) Get embed URL ``` curl -X POST https://api.rtrvr.ai/vnc/share \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "executionId": "0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1", "rotate": false }' ``` #### Response Share response ``` { "ok": true, "executionId": "0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1", "embedUrl": "https://vnc-embed.rtrvr.ai/vnc/embed/0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1#key=", "expiresAt": 1730000000 } ``` ### Step 3: Embed in Your App Use the `embedUrl` directly in an iframe. The hosted page handles everything: loading the VNC viewer, connecting to the relay, and auto-refreshing tokens. Embed in iframe ``` ``` **Why the share key is in the fragment (#key=...)** The share key is placed in the URL fragment so it's **never sent to servers** in HTTP requests by default. The embed page reads it client-side and sends it in an Authorization header when calling VNC endpoints. ### Complete Integration Example Full VNC integration (JavaScript) ``` const API_URL = "https://api.rtrvr.ai"; const API_KEY = "YOUR_API_KEY"; async function startExecutionWithVnc(input, urls) { // 1. Generate your own trajectoryId for immediate embed const trajectoryId = crypto.randomUUID(); // 2. Start execution with VNC enabled const executePromise = fetch(`${API_URL}/agent`, { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ trajectoryId, input, urls, options: { ui: { enableVnc: true, vncScope: "root" // or "all" for batch workers } } }), }); // 3. Immediately request embed URL (don't wait for execute) const shareRes = await fetch(`${API_URL}/vnc/share`, { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ executionId: trajectoryId, rotate: false }), }); const shareData = await shareRes.json(); if (shareData.ok) { // 4. Embed the VNC view const iframe = document.createElement("iframe"); iframe.src = shareData.embedUrl; iframe.style.cssText = "width:100%;height:720px;border:0;border-radius:12px;"; iframe.allow = "clipboard-read; clipboard-write"; document.getElementById("vnc-container").appendChild(iframe); } // 5. Wait for execution to complete const executeRes = await executePromise; const result = await executeRes.json(); return { result, embedUrl: shareData.embedUrl }; } // Usage startExecutionWithVnc( "Scrape the top 5 articles from Hacker News", ["https://news.ycombinator.com"] ).then(({ result, embedUrl }) => { console.log("Execution complete:", result); console.log("VNC embed URL:", embedUrl); }); ``` Full VNC integration (Python) ``` import uuid import requests import threading API_URL = "https://api.rtrvr.ai" API_KEY = "YOUR_API_KEY" def start_execution_with_vnc(input_text: str, urls: list[str]): headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } # 1. Generate your own trajectoryId trajectory_id = str(uuid.uuid4()) # 2. Start execution in background thread def execute(): return requests.post( f"{API_URL}/agent", headers=headers, json={ "trajectoryId": trajectory_id, "input": input_text, "urls": urls, "options": { "ui": { "enableVnc": True, "vncScope": "root" # or "all" for batch workers } } }, timeout=300 ).json() execute_thread = threading.Thread(target=execute) execute_thread.start() # 3. Immediately get embed URL share_res = requests.post( f"{API_URL}/vnc/share", headers=headers, json={ "executionId": trajectory_id, "rotate": False } ).json() if share_res.get("ok"): print(f"VNC Embed URL: {share_res['embedUrl']}") print(f"Share key expires: {share_res['expiresAt']}") # 4. Wait for execution execute_thread.join() return { "trajectory_id": trajectory_id, "embed_url": share_res.get("embedUrl") } # Usage result = start_execution_with_vnc( "Go to example.com and take a screenshot", ["https://example.com"] ) print(f"Embed in iframe: {result['embed_url']}") ``` Full VNC flow (cURL) ``` # 1. Start execution with VNC enabled (use your own trajectoryId) TRAJECTORY_ID="$(uuidgen)" curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"trajectoryId\": \"$TRAJECTORY_ID\", \"input\": \"Go to example.com and summarize\", \"urls\": [\"https://example.com\"], \"options\": { \"ui\": { \"enableVnc\": true, \"vncScope\": \"root\" } } }" & # 2. Immediately get the embed URL (don't wait for execute) curl -X POST https://api.rtrvr.ai/vnc/share \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"executionId\": \"$TRAJECTORY_ID\", \"rotate\": false }" # Response contains embedUrl - use it in an iframe ``` ### Advanced: Build a Custom Viewer For custom UIs, use the public VNC endpoints to list sessions and get websocket URLs. They take a Bearer token that is either the `shareKey` from the embed URL, or a Firebase ID token for the account that owns the execution. #### List Sessions GET`/vnc-public/sessions?executionId={executionId}` List VNC sessions (public endpoint) ``` curl "https://vnc-embed.rtrvr.ai/vnc-public/sessions?executionId=0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1" \ -H "Authorization: Bearer YOUR_SHARE_KEY" # Response: # { # "ok": true, # "executionId": "0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1", # "sessions": [ # { # "sessionId": "0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1", # "kind": "root", # "batchIndex": null, # "state": "running", # "expiresAt": 1730001234 # } # ] # } ``` #### Get Viewer Token & WebSocket URL GET`/vnc-public/token?executionId={id}&sessionId={id}` Get VNC token and websocket URL ``` curl "https://vnc-embed.rtrvr.ai/vnc-public/token?executionId=0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1&sessionId=0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1" \ -H "Authorization: Bearer YOUR_SHARE_KEY" # Response: # { # "ok": true, # "executionId": "0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1", # "sessionId": "0f3f2d33-0f6a-4d79-bb3d-56c2d4d7c2a1", # "wsUrl": "wss://relay.rtrvr.ai/vnc?token=", # "expiresAt": 1730000600 # } ``` **Token refresh:** Viewer tokens expire 3 minutes after they are minted. The relay checks the token only when the websocket connects, so call `/vnc-public/token` again right before each connect attempt rather than holding one. ### Authenticated VNC Endpoints (Owner Access) These endpoints use your API key directly (no share key needed). Useful when you don't want to expose share links. `GET /vnc/sessions`endpoint List sessions for an execution. Add ?withToken=1 to include wsUrl for each session. `GET /vnc/token`endpoint Get viewer token + wsUrl. Add ?createIfMissing=1 to auto-create the session doc. `POST /vnc/share`endpoint Generate/rotate a share key and get embedUrl. Authenticated session list with tokens ``` curl "https://api.rtrvr.ai/vnc/sessions?executionId=YOUR_TRAJECTORY_ID&withToken=1" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ### VNC Endpoint Reference VNC endpoints are split across two services. **Authenticated endpoints** live on the main API (`api.rtrvr.ai`), while **public/share-key endpoints** and the embed page are served by the embed service (`vnc-embed.rtrvr.ai`). The correct embed-service host is returned in the `embedUrl` from `POST /vnc/share`. Endpoint Host Auth Description `POST /vnc/share` api.rtrvr.ai API Key Get embedUrl + shareKey `GET /vnc/sessions` api.rtrvr.ai API Key List sessions (owner access) `GET /vnc/token` api.rtrvr.ai API Key Get wsUrl token (owner access) `GET /vnc-public/sessions` vnc-embed.rtrvr.ai Share Key List sessions (public/share) `GET /vnc-public/token` vnc-embed.rtrvr.ai Share Key Get wsUrl token (public/share) `GET /vnc/embed/:executionId` vnc-embed.rtrvr.ai Share Key (in #fragment) Hosted noVNC viewer page ### Security Best Practices - • **Treat shareKey like a password:** Anyone with it can view your browser session - • **Use fragment URLs:** The `#key=...` format prevents the key from appearing in server logs - • **Rotate when needed:** Call `POST /vnc/share` with `rotate: true` to invalidate old links - • **Use vncScope wisely:** Only use `"all"` if you need to see batch worker browsers - • **View-only:** Share links cannot control the browser, only view it **Google tools:** Connect Google Drive in your API key owner’s account. These examples use the saved connection; `authToken` is an optional override. Open [Cloud → Sheets](https://rtrvr.ai/cloud). cURL ``` # ═══════════════════════════════════════════════════════════════ # BASIC EXAMPLES # ═══════════════════════════════════════════════════════════════ # 1. Simple page summarization curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Summarize the main points of this page in 5 bullet points.", "urls": ["https://example.com/blog/ai-trends-2025"], "response": { "verbosity": "final" } }' # 2. With JSON schema for structured output curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Extract article title, author, and publish date.", "urls": ["https://example.com/blog/article"], "schema": { "type": "object", "properties": { "title": { "type": "string" }, "author": { "type": "string" }, "publishDate": { "type": "string" } }, "required": ["title"] } }' # ═══════════════════════════════════════════════════════════════ # FILE INPUT EXAMPLES # ═══════════════════════════════════════════════════════════════ # 3. Analyze a PDF document curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Extract key financial metrics from this quarterly report.", "files": [ { "displayName": "Q3-Report.pdf", "uri": "https://firebasestorage.googleapis.com/v0/b/bucket/o/files%2Freport.pdf?alt=media&token=abc", "mimeType": "application/pdf" } ], "schema": { "type": "object", "properties": { "revenue": { "type": "string" }, "profit": { "type": "string" }, "growth_rate": { "type": "string" } } } }' # 4. Analyze an image curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Describe this UI screenshot and identify usability issues.", "files": [ { "displayName": "app-screenshot.png", "uri": "gs://my-bucket/screenshots/app.png", "mimeType": "image/png" } ] }' # 5. Compare two documents curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Compare these contracts and list all differences.", "files": [ { "displayName": "contract-v1.pdf", "uri": "https://firebasestorage.googleapis.com/.../v1.pdf?...", "mimeType": "application/pdf" }, { "displayName": "contract-v2.pdf", "uri": "https://firebasestorage.googleapis.com/.../v2.pdf?...", "mimeType": "application/pdf" } ] }' # ═══════════════════════════════════════════════════════════════ # DATA INPUT EXAMPLES # ═══════════════════════════════════════════════════════════════ # 6. CSV enrichment (inline) curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "For each company, find their website and a one-sentence description.", "dataInputs": [ { "description": "Companies to enrich", "format": "csv", "inline": "company\nOpenAI\nAnthropic\nGoogle DeepMind" } ], "response": { "verbosity": "steps" } }' # 7. JSON array processing curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Classify each review as positive, negative, or neutral.", "dataInputs": [ { "description": "Reviews", "format": "json", "inline": "[{\"text\":\"Great product!\"},{\"text\":\"Terrible support.\"},{\"text\":\"It works okay.\"}]" } ] }' # 8. XLSX from URL curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Summarize the sales pipeline metrics.", "dataInputs": [ { "description": "Sales pipeline", "format": "xlsx", "url": "https://example.com/data/pipeline.xlsx" } ] }' # ═══════════════════════════════════════════════════════════════ # COMBINED: FILES + DATA + BROWSING # ═══════════════════════════════════════════════════════════════ # 9. Complex workflow: Analyze resume + scrape job posting + match curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Analyze the resume, scrape the job posting, and score the candidate fit (1-10) with reasoning.", "urls": ["https://company.com/careers/senior-engineer"], "files": [ { "displayName": "candidate-resume.pdf", "uri": "https://firebasestorage.googleapis.com/.../resume.pdf?...", "mimeType": "application/pdf" } ], "schema": { "type": "object", "properties": { "fitScore": { "type": "number" }, "strengths": { "type": "array", "items": { "type": "string" } }, "gaps": { "type": "array", "items": { "type": "string" } }, "recommendation": { "type": "string" } } } }' # ═══════════════════════════════════════════════════════════════ # GOOGLE SHEETS # ═══════════════════════════════════════════════════════════════ # 10. Create new Google Sheet curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Scrape all products and save to Google Sheets.", "urls": ["https://example.com/products"], "tools": { "enableAdditionalTools": ["generate_sheets"] } }' # 11. Append to existing Google Sheet curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Scrape new leads and add to my existing sheet.", "urls": ["https://linkedin.com/search/..."], "reuseArtifacts": { "mode": "force", "targets": { "sheets": { "sheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms", "tabTitle": "Leads", "tabMode": "SAME_TAB" } } }, "tools": { "enableAdditionalTools": ["generate_sheets"] } }' # ═══════════════════════════════════════════════════════════════ # GOOGLE SLIDES # ═══════════════════════════════════════════════════════════════ # 12. Create new presentation curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Create a 5-slide presentation summarizing key points. Include title, 3 content slides, and conclusion.", "urls": ["https://example.com/blog/industry-trends-2025"], "tools": { "enableAdditionalTools": ["generate_slides"] } }' # 13. Append to existing presentation curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Add 3 slides with competitor analysis to the existing presentation.", "urls": ["https://competitor.com/products"], "reuseArtifacts": { "mode": "force", "targets": { "slides": { "presentationId": "1abc123_your_presentation_id", "mode": "APPEND" } } }, "tools": { "enableAdditionalTools": ["generate_slides"] } }' # ═══════════════════════════════════════════════════════════════ # GOOGLE DOCS # ═══════════════════════════════════════════════════════════════ # 14. Create new Google Doc curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Create a detailed research report about this company including products, leadership, and news.", "urls": ["https://example.com/about", "https://example.com/news"], "tools": { "enableAdditionalTools": ["generate_docs"] } }' # 15. Append to existing Google Doc curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Add a new section summarizing this weeks market news.", "urls": ["https://news.example.com/markets"], "reuseArtifacts": { "mode": "force", "targets": { "docs": { "docId": "1abc123_your_doc_id", "mode": "APPEND" } } }, "tools": { "enableAdditionalTools": ["generate_docs"] } }' # ═══════════════════════════════════════════════════════════════ # PDF GENERATION & FILLING # ═══════════════════════════════════════════════════════════════ # 16. Generate new PDF curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Create a PDF invoice: 3x Widget Pro at $99 each, customer: Acme Corp.", "tools": { "enableAdditionalTools": ["generate_pdfs"] } }' # 17. Fill PDF form template curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Fill the W-9 form with: Name: John Smith, Business: Smith Consulting LLC", "reuseArtifacts": { "mode": "force", "targets": { "pdfs": { "templateFileId": "1xyz_w9_template_id" } } }, "tools": { "enableAdditionalTools": ["pdf_filling"] } }' # ═══════════════════════════════════════════════════════════════ # WEB DASHBOARDS # ═══════════════════════════════════════════════════════════════ # 18. Generate interactive dashboard curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Create an interactive dashboard showing sales by region with charts.", "dataInputs": [{ "description": "Sales data", "format": "csv", "inline": "region,sales,month\nNorth,50000,Jan\nSouth,42000,Jan\nEast,38000,Jan" }], "tools": { "enableAdditionalTools": ["generate_websites"] } }' # ═══════════════════════════════════════════════════════════════ # INTERACTIVE WORKFLOWS (ask_questions) # ═══════════════════════════════════════════════════════════════ # 19. Enable follow-up questions curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Help me find the best flight from NYC to London.", "urls": ["https://flights.example.com"], "tools": { "enableAdditionalTools": ["ask_questions"] } }' # 20. Continue after requires_input status curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Direct flights only, economy class, morning departure.", "trajectoryId": "exec_from_inputRequest_resume_executionId", "continuePlanning": true, "history": { "previousSteps": [] } }' # ═══════════════════════════════════════════════════════════════ # MULTI-PHASE WORKFLOWS # ═══════════════════════════════════════════════════════════════ # 21. Phase 1: Discovery curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Find the top 10 AI startups in healthcare.", "urls": ["https://techcrunch.com/tag/ai-healthcare"], "phase": 1 }' # 22. Phase 2: Enrichment (same trajectoryId) curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Get funding details and executives for each startup.", "trajectoryId": "traj_from_phase1", "phase": 2, "tools": { "enableAdditionalTools": ["generate_sheets"] } }' # 23. Phase 3: Report curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Create a presentation with investment recommendations.", "trajectoryId": "traj_from_phase1", "phase": 3, "tools": { "enableAdditionalTools": ["generate_slides"] } }' # ═══════════════════════════════════════════════════════════════ # CUSTOM TOOLS # ═══════════════════════════════════════════════════════════════ # 24. Use custom/user-defined tools curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Find leads and add them to our CRM.", "urls": ["https://linkedin.com/search/..."], "tools": { "mode": "allowlist", "userDefined": ["add_to_crm", "enrich_lead"] } }' # ═══════════════════════════════════════════════════════════════ # VNC LIVE VIEW EXAMPLES # ═══════════════════════════════════════════════════════════════ # 25. Start execution with VNC enabled TRAJECTORY_ID="$(uuidgen)" curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"trajectoryId\": \"$TRAJECTORY_ID\", \"input\": \"Navigate to example.com and fill out the contact form\", \"urls\": [\"https://example.com/contact\"], \"options\": { \"ui\": { \"enableVnc\": true, \"vncScope\": \"root\" } } }" # 26. Get embeddable VNC URL curl -X POST https://api.rtrvr.ai/vnc/share \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"executionId\": \"$TRAJECTORY_ID\", \"rotate\": false }" # 27. List VNC sessions (authenticated) curl "https://api.rtrvr.ai/vnc/sessions?executionId=$TRAJECTORY_ID&withToken=1" \ -H "Authorization: Bearer YOUR_API_KEY" # 28. Get VNC token (authenticated) curl "https://api.rtrvr.ai/vnc/token?executionId=$TRAJECTORY_ID&sessionId=$TRAJECTORY_ID" \ -H "Authorization: Bearer YOUR_API_KEY" # 29. List sessions with share key (public — served by the embed service) curl "https://vnc-embed.rtrvr.ai/vnc-public/sessions?executionId=$TRAJECTORY_ID" \ -H "Authorization: Bearer YOUR_SHARE_KEY" # 30. Get VNC token with share key (public — served by the embed service) curl "https://vnc-embed.rtrvr.ai/vnc-public/token?executionId=$TRAJECTORY_ID&sessionId=$TRAJECTORY_ID" \ -H "Authorization: Bearer YOUR_SHARE_KEY" ``` YOUR NEXT RUN ## Run the example on a real site. Use Chrome for the page in front of you. Use Cloud when the run should continue on a schedule or across many pages. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Get the page data./scrape RUN # Get the page data.`/scrape` Send one or more URLs and get the visible text, page structure, and link records back. Use your own model or pipeline for what comes next. [Try a scrape](#playground)[Create API key](/cloud?view=api-keys) 01 ## Text and structure Return clean page text, accessibility trees, and element links. 02 ## No planner Use the browser and proxy layer without an agent deciding the route. 03 ## Built to compose Pass the response into your own search, RAG, or enrichment system. API, CLI, and MCP runs need a paid plan: Cloud API calls with an API key, the MCP Cloud tools (cloud\_agent, cloud\_scrape, and agent or scrape in Cloud), and rtrvr's agent in your Chrome. On a paid plan they use credits for the resources they consume. Browser tools your own AI drives over MCP are free on every plan. On the free plan, try Free Mode in the extension or Cloud dashboard. [Compare plans →](/pricing#free-mode) Free usage, ads, and data terms Free Mode includes supported AI models and Cloud browser time for tasks you start in the extension or Cloud dashboard. No AI API key or paid AI subscription is required. Sponsored cards and a daily fair-use allowance apply. Your account shows the current allowance and reset time. When you reach it, wait for the reset, use your own AI provider, or choose a paid plan. Your provider may charge for its usage. One schedule that runs once a day or less often, in the Cloud or in your Chrome, is included, paid from the daily allowance. More schedules, faster schedules, triggers, cookie sync, API runs, rtrvr's agent over MCP, and WhatsApp tasks require a paid plan. Browser tools that let your own AI drive your Chrome over MCP are free on every plan. Data enrichment and managed proxies can use credits separately. On the free plan, Cloud API calls made with an API key, the MCP Cloud tools (cloud\_agent, cloud\_scrape, and agent or scrape when they run in Cloud), and WhatsApp tasks need a paid plan, as does running rtrvr's agent in your Chrome through API or MCP. Free Mode covers the tasks you start in the extension or Cloud dashboard. On a paid plan, API, MCP, and WhatsApp runs use credits for the resources they consume. Free Mode involves sponsored content in both the Chrome extension and Cloud, as described in the Terms and Privacy Notice. Using your own AI provider avoids model-credit charges and the Free Mode allowance. Cloud resources and managed services may still use credits. Sponsored cards still appear on the free plan. Paid plans offer ad-free runs. [Free Mode terms](/terms#free-mode) · [Privacy notice](/privacy) CLI Return the same page data from your terminal with [rtrvr CLI](/docs/cli). `rtrvr scrape --url https://example.com` Scrape API Walkthrough ### Try a scrape POST`/scrape` Add URLs. Get readable text, page structure, and links. Try an example API key [Create an API key](/cloud?view=api-keys) Page URLs Add one complete URL per line. curl -X POST https://api.rtrvr.ai/scrape \\ -H "Authorization: Bearer YOUR\_API\_KEY" \\ -H "Content-Type: application/json" \\ -d '{ "urls": \[ "https://news.ycombinator.com/" \], "response": { "inlineOutputMaxBytes": 1048576 } }' Add your API key to run this request. Base URL`https://api.rtrvr.ai` Use `/scrape` for raw page data and `/agent` for full agent runs. Use your API key in the `Authorization` header: Header ``` Authorization: Bearer rtrvr_your_api_key ``` The `Bearer` prefix is optional (`Authorization: rtrvr_your_api_key` works), and `x-api-key: rtrvr_your_api_key` is accepted too. In n8n, Make or Zapier **Header Auth**, set Name to `Authorization` and Value to your key, or Name to `x-api-key`. **Security:** Keep your key server-side (backend or serverless). Don't ship it to the browser. POST`https://api.rtrvr.ai/scrape` Agent vs Scrape Use `/agent` when you want the full planner + tools engine, and `/scrape` when you just need raw page text + structure for your own models. [See comparison](/docs/agent#agent-vs-scrape) Open one or more URLs in our browser cluster and get back each page's accessibility tree with its links, or its plain text. The endpoint is designed to be: - **Cheap** – infra-only credits (browser + proxy), no model usage. - **Predictable** – stable schema for tab content + usage metrics. - **Composable** – plug the result into your own LLM/RAG pipeline. Minimal scrape – single URL ``` curl -X POST https://api.rtrvr.ai/scrape \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "urls": ["https://example.com/blog/ai-trends-2025"] }' ``` Extraction preferences come from your `UserSettings` profile stored in the cloud. Relevant UserSettings fields (conceptual) ``` interface UserSettings { extractionConfig: { maxParallelTabs?: number; /** Minimum wait inside totalBudgetMs; default 0. */ pageLoadDelay?: number; /** Initial read deadline: default 15000, bounded to 1500–30000 ms. */ totalBudgetMs?: number; makeNewTabsActive?: boolean; writeRowProcessingTime?: boolean; disableAutoScroll?: boolean; /** * When true, only text content is returned from scrapes. * The accessibility tree + elementLinkRecord are omitted. * When false (the default), HTML pages return tree + elementLinkRecord * and no content. */ onlyTextContent?: boolean; }; // Proxy Configuration proxyConfig: { mode: 'none' | 'custom' | 'default' | 'device'; customProxies?: ProxySettings[]; selectedProxyId?: string; selectedProxyName?: string; selectedDeviceId?: string; // Managed proxy exit (mode 'default'): ISO country, optional ISO 3166-2 // region part ("NY", "25") and English city name. location?: { country: string; region?: string; city?: string }; }; } ``` Two ways to control behavior: - **1\. Cloud profile:** configure defaults in [Cloud → Settings](/cloud?view=settings). - **2\. Per-request overrides:** send `settings` in your request body. ### Use a saved proxy from MCP or the API Save your proxy in [Cloud Settings → Proxy Config](/cloud?view=settings). Choose it as your default and save settings to use it across Cloud, API, and MCP. To override for one call, pass its exact name or ID. Credentials stay in your account. ``` { "settings": { "proxyConfig": { "mode": "custom", "selectedProxyName": "My Taiwan proxy" } } } ``` For `cloud_agent` and `cloud_scrape`, put `settings` inside the MCP tool's `arguments` or the tool API's `params`. For `POST /agent` and `POST /scrape`, put it in the request body. A saved `selectedProxyId` can replace `selectedProxyName`. - Omit `proxyConfig` to use your profile default, falling back to Retriever's managed proxy when none is set. Use `{"mode":"default"}` to explicitly choose the managed proxy. - The Cloud chat-bar selection overrides routing for that chat without changing your profile default. Choose “Use my default route” to reset it. MCP `list` with `kind: "proxies"` shows saved proxies and marks the default; managed proxy connection details remain private. - Use `{"mode":"none"}` for a direct cloud connection. - Saved names are case-sensitive. Unknown names and IDs fail; duplicate names require an ID. If both selectors are supplied, they must identify the same proxy. - Schedules created from a run retain its routing choice. Permission to use another route belongs to the schedule, so a one-run fallback does not enable it. You can also provide a proxy for just one request. Use an HTTP or HTTPS proxy that supports CONNECT; keep credentials out of shared snippets and client-side code. ``` { "settings": { "proxyConfig": { "mode": "custom", "selectedProxyId": "request-proxy", "customProxies": [ { "id": "request-proxy", "host": "proxy.example.net", "port": 8080, "scheme": "http", "username": "YOUR_USERNAME", "password": "YOUR_PASSWORD" } ] } } } ``` ### Go out through your own computer with Tailscale A Tailscale tunnel sends a cloud run's traffic out through a computer you own, so sites see your home connection. It uses no proxy credits. Once saved, choose it like any saved proxy: as your default, in the chat bar, or by its exact name or ID with `{"mode":"custom"}`. Tailscale connection failures retry once, then stop before the task starts. To allow managed fallback for an API request, send `settings.proxyConfig.tailscaleFallback: "managed"`. Omit it or use `"stop"` to stay on Tailscale. Fallback uses a different IP and normal proxy charges apply. [Set up a Tailscale tunnel](/docs/tailscale): the steps, the limits, and parallel runs. ### Choose where the managed proxy exits Add `location` to Retriever's managed proxy to run from a country, and optionally a region or city in it. The cloud browser's time zone and language follow the exit, so sites show dates, prices and pages the way a local visitor sees them. ``` { "settings": { "proxyConfig": { "mode": "default", "location": { "country": "IT", "city": "Milan" } } } } ``` - One field may list up to 5 places for an exit in any of them: countries (`{"country": ["IT", "FR", "DE"]}`, with no region or city), regions of one country (`{"country": "US", "region": ["CA", "WA"]}`, with no city) or cities of one country (`{"country": "IT", "city": ["Milan", "Rome"]}`). A comma-separated string such as `"IT,FR,DE"` works too. `egress` names the country the run used. - The result's `egress` says where the run exited, for example `{"country":"IT","city":"Milan","timezone":"Europe/Rome"}`. `relaxed: true` means the city or region had no exit and the run used more of the country. - A location goes only with the managed proxy (`mode: "default"`, which it implies when you leave `mode` out). Next to a saved proxy or `"none"` the call is refused. - Same field everywhere: `settings.proxyConfig.location` on `POST /agent` and `POST /scrape`, and on the MCP tools `cloud_agent` and `cloud_scrape`. MCP and the tool API also take the shorthand `proxy_location`, such as `"proxy_location": "IT"`, `"proxy_location": "IT,FR,DE"` or `"proxy_location": {"country": "US", "region": "NY"}`; with `agent` or `scrape` it runs the task in the cloud browser. - Save a location under [Cloud Settings → Proxy Config](/cloud?view=settings) next to the managed default to use it for every run that names no route, schedules included. In the Cloud chat bar, pick Retriever managed proxy and set Location for that chat only. - A few hosts that always connect directly from the cloud, such as some government sites and file storage, do not use the location. ### Supported locations A location names a country, and optionally a region or city in it. Each field takes one value, or a list of up to 5 for an exit in any of them. Field Format Examples `country` Two-letter ISO 3166-1 code (`UK` is read as `GB`). A list of countries takes no region or city. `IT`, `US`, `["IT", "FR", "DE"]` `region` Optional. The part after the dash of an ISO 3166-2 code in that country. A list of regions takes no city. `NY` for US-NY, `25` for IT-25 (Lombardy) `city` Optional. The city's English name, in that country. `Milan`, `New York`, `["Milan", "Rome"]` If the city has no exit, the run tries its region, then the whole country. It never moves to another country. If none of the countries you asked for has an exit, the run does not start and the call returns `503 PROXY_LOCATION_UNAVAILABLE` with a message that says so. Availability is live: exits come and go with the residential pool, and every run checks its own location before it starts. `GET https://api.rtrvr.ai/proxy-locations` with your API key returns the country list below, with the date each country was checked, the format and the fallback rule. To check a region, a city or a list right now, send `POST https://api.rtrvr.ai/proxy-location/check` with `{"location": {"country": "IT", "city": "Milan"}}`. It answers `{"available": true, "egress": {...}}` with where a run would exit, or `{"available": false, "message": "..."}`. Cloud Settings and the chat bar run the same check and only take places that have an exit. 120 countries had an exit when checked on 11 November 2026 - Åland Islands `AX` - Albania `AL` - American Samoa `AS` - Andorra `AD` - Anguilla `AI` - Antigua & Barbuda `AG` - Argentina `AR` - Armenia `AM` - Aruba `AW` - Australia `AU` - Austria `AT` - Azerbaijan `AZ` - Bahamas `BS` - Bahrain `BH` - Barbados `BB` - Belarus `BY` - Belgium `BE` - Belize `BZ` - Bermuda `BM` - Bosnia & Herzegovina `BA` - Brazil `BR` - British Virgin Islands `VG` - Bulgaria `BG` - Canada `CA` - Caribbean Netherlands `BQ` - Cayman Islands `KY` - Chile `CL` - China `CN` - Colombia `CO` - Costa Rica `CR` - Côte d’Ivoire `CI` - Croatia `HR` - Curaçao `CW` - Cyprus `CY` - Czechia `CZ` - Denmark `DK` - Dominica `DM` - Dominican Republic `DO` - Egypt `EG` - Equatorial Guinea `GQ` - Estonia `EE` - Falkland Islands `FK` - Faroe Islands `FO` - Finland `FI` - France `FR` - French Guiana `GF` - French Polynesia `PF` - Gabon `GA` - Georgia `GE` - Germany `DE` - Gibraltar `GI` - Greece `GR` - Greenland `GL` - Grenada `GD` - Guadeloupe `GP` - Guam `GU` - Guernsey `GG` - Hungary `HU` - Iceland `IS` - India `IN` - Iran `IR` - Ireland `IE` - Isle of Man `IM` - Israel `IL` - Italy `IT` - Jamaica `JM` - Japan `JP` - Jersey `JE` - Kazakhstan `KZ` - Kuwait `KW` - Latvia `LV` - Lithuania `LT` - Luxembourg `LU` - Malta `MT` - Martinique `MQ` - Mexico `MX` - Moldova `MD` - Monaco `MC` - Montenegro `ME` - Montserrat `MS` - Namibia `NA` - Netherlands `NL` - New Zealand `NZ` - North Macedonia `MK` - Norway `NO` - Oman `OM` - Palestinian Territories `PS` - Panama `PA` - Peru `PE` - Philippines `PH` - Poland `PL` - Portugal `PT` - Puerto Rico `PR` - Qatar `QA` - Romania `RO` - San Marino `SM` - Saudi Arabia `SA` - Serbia `RS` - Seychelles `SC` - Sint Maarten `SX` - Slovakia `SK` - Slovenia `SI` - South Korea `KR` - Spain `ES` - St. Kitts & Nevis `KN` - St. Lucia `LC` - St. Martin `MF` - St. Vincent & Grenadines `VC` - Sweden `SE` - Switzerland `CH` - Taiwan `TW` - Trinidad & Tobago `TT` - Türkiye `TR` - Turks & Caicos Islands `TC` - U.S. Virgin Islands `VI` - Ukraine `UA` - United Arab Emirates `AE` - United Kingdom `GB` - United States `US` - Uruguay `UY` 129 countries had no exit on 11 November 2026 These codes are accepted, but a run that asks only for them is refused until an exit appears. Check one before you rely on it, or list it with a country that has an exit. - Afghanistan `AF` - Algeria `DZ` - Angola `AO` - Antarctica `AQ` - Bangladesh `BD` - Benin `BJ` - Bhutan `BT` - Bolivia `BO` - Botswana `BW` - Bouvet Island `BV` - British Indian Ocean Territory `IO` - Brunei `BN` - Burkina Faso `BF` - Burundi `BI` - Cambodia `KH` - Cameroon `CM` - Cape Verde `CV` - Central African Republic `CF` - Chad `TD` - Christmas Island `CX` - Cocos (Keeling) Islands `CC` - Comoros `KM` - Congo - Brazzaville `CG` - Congo - Kinshasa `CD` - Cook Islands `CK` - Cuba `CU` - Djibouti `DJ` - Ecuador `EC` - El Salvador `SV` - Eritrea `ER` - Eswatini `SZ` - Ethiopia `ET` - Fiji `FJ` - French Southern Territories `TF` - Gambia `GM` - Ghana `GH` - Guatemala `GT` - Guinea `GN` - Guinea-Bissau `GW` - Guyana `GY` - Haiti `HT` - Heard & McDonald Islands `HM` - Honduras `HN` - Hong Kong SAR China `HK` - Indonesia `ID` - Iraq `IQ` - Jordan `JO` - Kenya `KE` - Kiribati `KI` - Kyrgyzstan `KG` - Laos `LA` - Lebanon `LB` - Lesotho `LS` - Liberia `LR` - Libya `LY` - Liechtenstein `LI` - Macao SAR China `MO` - Madagascar `MG` - Malawi `MW` - Malaysia `MY` - Maldives `MV` - Mali `ML` - Marshall Islands `MH` - Mauritania `MR` - Mauritius `MU` - Mayotte `YT` - Micronesia `FM` - Mongolia `MN` - Morocco `MA` - Mozambique `MZ` - Myanmar (Burma) `MM` - Nauru `NR` - Nepal `NP` - New Caledonia `NC` - Nicaragua `NI` - Niger `NE` - Nigeria `NG` - Niue `NU` - Norfolk Island `NF` - North Korea `KP` - Northern Mariana Islands `MP` - Pakistan `PK` - Palau `PW` - Papua New Guinea `PG` - Paraguay `PY` - Pitcairn Islands `PN` - Réunion `RE` - Russia `RU` - Rwanda `RW` - Samoa `WS` - São Tomé & Príncipe `ST` - Senegal `SN` - Sierra Leone `SL` - Singapore `SG` - Solomon Islands `SB` - Somalia `SO` - South Africa `ZA` - South Georgia & South Sandwich Islands `GS` - South Sudan `SS` - Sri Lanka `LK` - St. Barthélemy `BL` - St. Helena `SH` - St. Pierre & Miquelon `PM` - Sudan `SD` - Suriname `SR` - Svalbard & Jan Mayen `SJ` - Syria `SY` - Tajikistan `TJ` - Tanzania `TZ` - Thailand `TH` - Timor-Leste `TL` - Togo `TG` - Tokelau `TK` - Tonga `TO` - Tunisia `TN` - Turkmenistan `TM` - Tuvalu `TV` - U.S. Outlying Islands `UM` - Uganda `UG` - Uzbekistan `UZ` - Vanuatu `VU` - Vatican City `VA` - Venezuela `VE` - Vietnam `VN` - Wallis & Futuna `WF` - Western Sahara `EH` - Yemen `YE` - Zambia `ZM` - Zimbabwe `ZW` A location costs nothing extra. Managed proxy traffic is billed per GB, about 500 credits per GB ([pricing](/pricing)), the same with or without a location. ### Page-read timing Both `/agent` and `/scrape` open supplied URLs immediately and return page data as soon as it is ready. Configure timing under `settings.extractionConfig`. Request values override your saved profile. The defaults below apply when neither sets a value. - `totalBudgetMs`: one deadline for initial navigation, readiness, extraction, and fallback. Default: **15000**. Values are bounded to **1500–30000** milliseconds. This is a maximum, not a mandatory wait. - `pageLoadDelay`: an optional minimum wait before capture for pages that render content late. Default: **0**. A positive value deliberately waits even if the page becomes ready sooner. It consumes the total budget and is shortened if needed to leave time for extraction and fallback. - `maxParallelTabs`: up to **8** cloud tabs load together (default and maximum: **8**). Set a lower value to load fewer at once, or **1** for sequential reads. Each active batch gets a fresh page-read budget, so a large batch of URLs can take longer than one budget. Return when ready, with up to 15 seconds for the initial read ``` { "settings": { "extractionConfig": { "totalBudgetMs": 15000, "pageLoadDelay": 0 } } } ``` For a page that needs a known 10-second rendering wait, set `pageLoadDelay: 10000`and `totalBudgetMs: 20000`. That leaves roughly 10 seconds for the remaining read work. The delay is not added on top of the deadline. Set `pageLoadDelay: 0` explicitly to override a saved profile delay. At the deadline, a read returns the available tree or a text fallback. If neither is readable, it reports an unreadable page rather than successful empty extraction. Text-only scrapes return text without a tree. An agent with no URLs starts with an empty page immediately; `/scrape` requires at least one URL. This deadline covers page reads, not browser provisioning, model execution, or the whole API request. Later agent captures keep their normal 8-second default unless you set a budget. Cancellation can interrupt a running job. Keep the caller timeout long enough for all batches and agent work; after a lost response, recover by trajectory ID before retrying. The request body is an `ScrapeApiRequest`: ScrapeApiRequest (conceptual) ``` interface ScrapeApiRequest { /** * Unique caller id for this scrape. Save it before dispatch to recover * results or cancel after a lost response. Reusing it returns HTTP 409. */ trajectoryId?: string; /** * One or more absolute URLs to load in the browser. * Must be a non-empty array of non-empty strings. */ urls: string[]; /** * Optional per-request settings override. * Other settings merge with your profile; omitted proxyConfig uses the profile default, or the managed proxy if none is set. * * Use extraction-related settings if you only want text content and don't need * the accessibility tree + elementLinkRecord. */ settings?: Partial; /** * Response size control for API callers. */ response?: { /** * Max bytes allowed for the inline JSON response. * If the full response exceeds this, tabs remain inline as preview content, * and a StorageReference is returned under metadata.responseRef for full payload download. * Default: 1MB (1048576 bytes) */ inlineOutputMaxBytes?: number; }; /** * Optional execution options. * Set options.ui.emitEvents=true to write progress events for SSE/polling clients. * If omitted/false, no execution event stream is written. */ options?: { ui?: { emitEvents?: boolean; }; }; /** * Webhooks to call when the scrape completes, fails, or is cancelled. */ webhooks?: WebhookSubscription[]; } interface WebhookSubscription { /** The URL to POST to */ url: string; /** Events to subscribe to. Defaults to all scrape events. */ events?: WebhookEvent[]; /** Optional custom headers */ headers?: Record; /** Optional auth (bearer or basic) */ auth?: { type: "bearer"; token: string } | { type: "basic"; username: string; password: string }; /** Optional secret for HMAC signing (X-Rtrvr-Signature header) */ secret?: string; /** Timeout for webhook delivery (default: 8000ms) */ timeoutMs?: number; /** Retry policy (default: { mode: "default" }) */ retry?: { mode: "default" | "none" }; } type WebhookEvent = | "rtrvr.scrape.succeeded" | "rtrvr.scrape.failed" | "rtrvr.scrape.cancelled"; ``` ### Parameters `urls`string\[\]**required** One or more absolute URLs to scrape. Must be a non-empty array. `trajectoryId`string Optional stable id for grouping scrapes together (analytics, observability). `settings`Partial Per-request settings. Proxy omission uses the managed default; other omitted settings use your profile. `response.inlineOutputMaxBytes`numberdefault `1048576` Maximum inline response size in bytes (default 1MB). `options.ui.emitEvents`booleandefault `false` Opt-in execution progress events for SSE/polling consumers. `webhooks`WebhookSubscription\[\] Optional array of webhook endpoints to notify when the scrape completes, fails, or is cancelled. Receive HTTP callbacks when your scrape completes, fails, or is cancelled. Webhooks are delivered asynchronously after the scrape finishes. ### Webhook Subscription `url`string**required** The HTTPS endpoint to POST the webhook payload to. `events`WebhookEvent\[\] Which events to subscribe to. Defaults to all scrape events. `rtrvr.scrape.succeeded``rtrvr.scrape.failed``rtrvr.scrape.cancelled` `headers`Record Custom headers to include with each webhook request. `auth`object Authentication for the webhook endpoint. Supports bearer token or basic auth. `auth.type`"bearer" | "basic" The authentication type. `auth.token`string Bearer token (when type is "bearer"). `auth.username`string Username (when type is "basic"). `auth.password`string Password (when type is "basic"). `secret`string HMAC secret for signing. When provided, requests include X-Rtrvr-Signature header. `timeoutMs`numberdefault `8000` Timeout for webhook delivery in milliseconds. `retry`object Retry policy. { mode: "default" } retries with backoff; { mode: "none" } delivers once. ### Example with Webhook Scrape with webhook notification ``` curl -X POST https://api.rtrvr.ai/scrape \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "urls": ["https://example.com/page1", "https://example.com/page2"], "webhooks": [ { "url": "https://your-server.com/webhooks/scrape", "events": ["rtrvr.scrape.succeeded", "rtrvr.scrape.failed"], "secret": "whsec_your_signing_secret", "headers": { "X-Custom-Header": "my-value" } } ] }' ``` ### Webhook Payload Each webhook delivery is a POST request with a JSON envelope: Webhook envelope ``` { "id": "whd_abc123...", // unique delivery id "event": "rtrvr.scrape.succeeded", "createdAt": "2025-01-15T10:30:00.000Z", "data": { "trajectoryId": "traj_xyz...", "success": true, "tabs": [...], "usageData": {...} } } ``` ### Signature Verification When you provide a `secret`, each request includes an `X-Rtrvr-Signature` header: text ``` X-Rtrvr-Signature: t=1705312200,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd ``` Verify signature (Node.js) ``` import crypto from 'crypto'; function verifyWebhookSignature(payload, signature, secret) { const [tPart, vPart] = signature.split(','); const timestamp = tPart.split('=')[1]; const receivedSig = vPart.split('=')[1]; // Recreate the signed payload const signedPayload = `${timestamp}.${JSON.stringify(payload)}`; const expectedSig = crypto .createHmac('sha256', secret) .update(signedPayload) .digest('hex'); // Timing-safe comparison return crypto.timingSafeEqual( Buffer.from(receivedSig), Buffer.from(expectedSig) ); } ``` **Store & reuse webhooks** Save your webhook endpoints in [Cloud → Webhooks](/cloud?view=webhooks) to quickly attach them to any execution without re-entering the URL, secret, and events each time. The API response is an `ScrapeApiResponse`: ScrapeApiResponse (conceptual) ``` interface ScrapedTab { tabId: number; url: string; title: string; contentType: string; status: "success" | "error"; error?: string; /** * The page's visible text. HTML pages fill it when * extractionConfig.onlyTextContent is true, or with a text fallback when * the tree could not be read. PDFs and other documents return their text here. */ content?: string; /** * The accessibility tree as a plain-text outline, not JSON. Do not JSON.parse it. * One element per line, indented by depth: "[role] text", then markers such * as [id=N]. Lines of plain page text start with "[]". Link lines carry their * URL inline: * [link] Learn more [id=8 href="https://iana.org/help/example-domains"] * Omitted when onlyTextContent is true. */ tree?: string; /** * Element id -> href for the link elements in 'tree', e.g. { "8": "https://..." }. * The same URLs already appear inline in 'tree'. * Only present when 'tree' is present. */ elementLinkRecord?: Record; } interface ScrapeUsageData { totalCredits: number; browserCredits: number; proxyCredits: number; totalUsd: number; requestDurationMs: number; proxyPageLoads: number; proxyTabsDataFetches: number; usingBillableProxy: boolean; } interface ScrapeApiResponse { success: boolean; status: "success" | "error"; trajectoryId: string; tabs?: ScrapedTab[]; usageData: ScrapeUsageData; // Where the managed proxy exited, e.g. { country: "IT", city: "Milan", timezone: "Europe/Rome" } egress?: { country: string; countries?: string[]; region?: string; city?: string; timezone?: string; requested?: { country: string; region?: string; city?: string }; relaxed?: boolean }; metadata?: { taskRef?: string; inlineOutputMaxBytes: number; durationMs: number; outputTooLarge?: boolean; responseRef?: StorageReference; }; error?: string; } ``` ### Tabs & content `tabs`ScrapedTab\[\] One tab per URL, in the same order as the input urls. `tabs[].content`string Visible page text. HTML pages return it when onlyTextContent=true, or as a fallback when the tree could not be read. PDFs and other documents return their text here. `tabs[].tree`string Accessibility tree as an indented plain-text outline, not JSON: one element per line, such as \[link\] Learn more \[id=8 href="https://…"\]. Plain text lines start with \[\]. Omitted when onlyTextContent=true. `tabs[].elementLinkRecord`Record Element id → href for the links in tree, such as {"8": "https://…"}. The same URLs appear inline in tree. Omitted when onlyTextContent=true. tabs\[0\].tree for https://example.com/ (default settings) ``` [] This domain is for use in documentation examples without needing permission. ... [link] Learn more [id=8 href="https://iana.org/help/example-domains"] [title] Example Domain ``` The same tab returns `elementLinkRecord` `{"8": "https://iana.org/help/example-domains"}` and no `content`. With `onlyTextContent: true` it returns the page text in `content` and no `tree` or `elementLinkRecord`. ### Infra usage `usageData.totalCredits`number Total infra credits consumed by this scrape. `usageData.browserCredits`number Credits attributable to browser usage. `usageData.proxyCredits`number Credits attributable to proxy usage. `usageData.requestDurationMs`number End-to-end latency for the scrape request in ms. Save a unique `trajectoryId` before each dispatch. The same ID identifies the execution in REST and MCP. If the connection closes or returns HTTP 504, read the existing run before sending another scrape. HTTP ``` GET /executions?limit=50 GET /executions/YOUR_TRAJECTORY_ID POST /scrape/cancel Content-Type: application/json {"trajectoryId":"YOUR_TRAJECTORY_ID"} ``` Use your API key for each request. History returns `nextCursor`; pass it as `cursor` for the next page. A run lookup returns its status, credits used, and saved result or download reference. Check `completed` before treating usage as final. Cancellation keeps results and charges already incurred. Reusing a raw scrape ID returns HTTP 409 instead of starting duplicate work. In MCP, use `list_executions` with `{"source":"cloud","include_completed":true}`, then `check_results` or `cancel_execution` with the `trajectoryId`. Cloud runs and these recovery tools do not require an extension device. Older raw scrapes can be read by ID even if they predate the execution list. The service recycles a failed browser automatically. There is no public browser-reset operation. After reconciling a terminal failure, use a new ID for a deliberate retry. If an older request has no ID, send support its UTC dispatch time and URL. Check each tab's status. A tree read of an HTML page returns a populated `tree` with empty `content`; use `extractionConfig.onlyTextContent=true` when you need page text. A partial capture can retain useful data with an observation warning. Empty startup pages are not successful HTTP-page scrapes. A batch containing failed tabs reports `success: false` and retains readable siblings. cURL ``` # Basic scrape using profile defaults curl -X POST https://api.rtrvr.ai/scrape \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "urls": ["https://example.com/blog/ai-trends-2025"], "response": { "inlineOutputMaxBytes": 1048576 } }' # With per-request settings override curl -X POST https://api.rtrvr.ai/scrape \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "urls": [ "https://example.com/blog/ai-trends-2025", "https://example.com/pricing" ], "settings": { "extractionConfig": { "onlyTextContent": true }, "proxyConfig": { "mode": "default" } }, "response": { "inlineOutputMaxBytes": 1048576 } }' ``` YOUR NEXT RUN ## Run the example on a real site. Use Chrome for the page in front of you. Use Cloud when the run should continue on a schedule or across many pages. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Use your signed-in browser./mcp RUN # Use your signed-in browser.`/mcp` Let an MCP client or backend use your signed-in Chrome session, including sites behind logins, SSO, and internal tools. [Try a tool](#playground)[Add to Chrome](https://chromewebstore.google.com/detail/retriever-ai-web-agent/jldogdgepmcedfdhgnmclgemehfhpomg) 01 ## Your signed-in browser Use the sessions and permissions already available in Chrome. 02 ## MCP or HTTP Connect an MCP client or send JSON from your backend. 03 ## Device and Cloud tools Use browser tools on your device and knowledge tools in Cloud. **Chrome is required for device-backed tools.** Cloud-only tools do not need an extension session. API, CLI, and MCP runs need a paid plan: Cloud API calls with an API key, the MCP Cloud tools (cloud\_agent, cloud\_scrape, and agent or scrape in Cloud), and rtrvr's agent in your Chrome. On a paid plan they use credits for the resources they consume. Browser tools your own AI drives over MCP are free on every plan. On the free plan, try Free Mode in the extension or Cloud dashboard. [Compare plans →](/pricing#free-mode) Free usage, ads, and data terms Free Mode includes supported AI models and Cloud browser time for tasks you start in the extension or Cloud dashboard. No AI API key or paid AI subscription is required. Sponsored cards and a daily fair-use allowance apply. Your account shows the current allowance and reset time. When you reach it, wait for the reset, use your own AI provider, or choose a paid plan. Your provider may charge for its usage. One schedule that runs once a day or less often, in the Cloud or in your Chrome, is included, paid from the daily allowance. More schedules, faster schedules, triggers, cookie sync, API runs, rtrvr's agent over MCP, and WhatsApp tasks require a paid plan. Browser tools that let your own AI drive your Chrome over MCP are free on every plan. Data enrichment and managed proxies can use credits separately. On the free plan, Cloud API calls made with an API key, the MCP Cloud tools (cloud\_agent, cloud\_scrape, and agent or scrape when they run in Cloud), and WhatsApp tasks need a paid plan, as does running rtrvr's agent in your Chrome through API or MCP. Free Mode covers the tasks you start in the extension or Cloud dashboard. On a paid plan, API, MCP, and WhatsApp runs use credits for the resources they consume. Free Mode involves sponsored content in both the Chrome extension and Cloud, as described in the Terms and Privacy Notice. Using your own AI provider avoids model-credit charges and the Free Mode allowance. Cloud resources and managed services may still use credits. Sponsored cards still appear on the free plan. Paid plans offer ad-free runs. [Free Mode terms](/terms#free-mode) · [Privacy notice](/privacy) CLI Connect an MCP client from your terminal with [rtrvr CLI](/docs/cli). `rtrvr mcp init --client claude` ## Video Tutorials Browser as API Introduction Introduction MCP Integration Deep Dive MCP Deep Dive ### Try a browser tool POST`/mcp` Choose a tool, set its inputs, and run the request. Try an example API key [Create an API key](/cloud?view=api-keys) Device ID (optional) Leave blank to let the server pick a browser that answers. Browser tool Describe a task for the browser to complete. Task Description (required) Starting URLs URLs to open before starting Additional Context Max Steps curl -X POST "https://mcp.rtrvr.ai" \\ -H "Authorization: Bearer rtrvr\_xxxxxxxxxxxxxxxxx" \\ -H "Content-Type: application/json" \\ -d '{ "tool": "planner", "params": {} }' Add your API key to run this request. Endpoint URL`https://mcp.rtrvr.ai` Shared by both direct HTTP calls and MCP clients. Extension-generated MCP URLs include your **API key** and **deviceId**; cloud-only knowledge base tools do not require a device. The rtrvr.ai Chrome Extension registers as a remote browser device and exposes a single public entrypoint at `https://mcp.rtrvr.ai`. That same endpoint speaks: - **MCP:** paste the generated MCP URL (includes `apiKey` + `deviceId`) into any MCP-enabled client (e.g. Claude). - **HTTP:** POST JSON describing `tool` + `params`. Extension-backed tools dispatch into your online browser devices, while cloud-only knowledge base tools execute immediately without a device. "Your Chrome browser is now an Agentic API Endpoint." Trigger complex workflows in your own logged-in browser instance from CI/CD, Slack bots, cron jobs, or backend services. OAuth Support (Recommended) MCP clients that support OAuth can authenticate by connecting to `mcp.rtrvr.ai` directly. This triggers a Google Sign-In flow and returns a secure session token. API Key in URL (Fallback) For MCP clients without OAuth support, embed your API key directly in the URL: `https://mcp.rtrvr.ai?apiKey=rtrvr_your_api_key&deviceId=your_device_id` For direct HTTP calls, auth can be provided via: - `Authorization: Bearer YOUR_API_KEY` (recommended) - `Authorization: YOUR_API_KEY` (the `Bearer` prefix is optional) - `X-API-Key: YOUR_API_KEY` - Query param: `?apiKey=YOUR_API_KEY` Header ``` Authorization: Bearer rtrvr_your_api_key ``` In n8n, Make or Zapier **Header Auth**, set Name to `Authorization` and Value to your `rtrvr_…` key (with or without `Bearer`), or set Name to `x-api-key`. **Security:** Prefer OAuth or headers in production. Avoid exposing API keys in URLs/logs when possible. Each Chrome/Chromium profile you install the extension into registers as a separate `deviceId`. This enables powerful multi-device workflows: How deviceId works: - Your `deviceId` is embedded in the MCP URL generated by the extension - Install the extension on multiple browsers/profiles to get multiple deviceIds - Target a specific device by passing `deviceId` in your request - **Leave deviceId blank** to auto-select a connected browser that answers commands ### Device selection rules: - **Explicit deviceId:** Pass `deviceId` or `device_id` in the query or body to target a specific device. - **No deviceId (default):** a browser that answers its commands is auto-selected, the most recently active first. A browser that left its last command unanswered (asleep, closed, or its extension not answering) goes behind every browser that answers, and is still tried when no other is left. One that kept missing commands for 7 days after it last answered is not auto-selected until its extension checks in again, and then it goes last; name it with `deviceId` to try it anyway. `list_devices` reports the current pick as `defaultDeviceId`. - **A browser that does not answer:** if the chosen browser does not pick a command up within 15 seconds, nothing runs and the reply (code `device_not_responding`; HTTP 503 over the API) names that device (id, name, extension version, when it last answered), says whether it was picked automatically, lists your other browsers with their status, and says where to retry. The command is never re-run on another browser for you: tab ids, logins and profiles differ per browser. - **Unified `agent` / `scrape`:** with no deviceId and no `target`, the call runs in your signed-in Chrome on the auto-selected device; if no device can be reached it runs in a cloud browser instead. Pass `target` to override. - **Multi-profile orchestration:** Install the extension on multiple browser profiles and orchestrate them independently by calling `/mcp` with different device IDs. - **Device-independent tools:** Utility tools like `get_current_credits` and `list_devices` work even if no device is online. ### Finding your deviceId: - **From MCP URL:** Open the extension → MCP / Remote Browser → copy the MCP URL. The `deviceId` parameter is embedded in the URL. - **Via API:** Call `list_devices` to see all registered devices: extension version, when each last answered a command (`lastAckAt`, UTC) and its `status` (`responding`, `not responding since …`, `never acked`, or `offline since …`). - **Same names:** two browsers can carry the same default name (“Chrome on Linux x86\_64”); tell them apart by id, version and last answer, or give each its own name in the extension (Browser as API/MCP → Advanced → Device name, in newer extension builds). Discovering devices ``` // List all your devices curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxx" \ -H "Content-Type: application/json" \ -d '{"tool": "list_devices"}' // Response: which browser answers, and where a call without deviceId goes { "success": true, "data": { "online": true, "defaultDeviceId": "dj75mmaTWP0", "devices": [ { "deviceId": "dj75mmaTWP0", "deviceName": "Work laptop", "extensionVersion": "38.1.1", "lastSeen": "2026-10-05T10:30:00.000Z", "lastAckAt": "2026-10-05T10:41:12.000Z", "status": "responding", "reachable": true }, { "deviceId": "abc123XYZ", "deviceName": "Chrome on Linux x86_64", "extensionVersion": "37.9.4", "lastSeen": "2026-10-03T18:00:00.000Z", "lastAckAt": "2026-09-25T21:05:00.000Z", "status": "not responding since 2026-09-25 21:34 UTC", "missedSinceLastAck": 12, "reachable": true } ] } } ``` POST`https://mcp.rtrvr.ai` The same endpoint powers both MCP and HTTP. For HTTP, you send a single JSON object describing which tool to run, which parameters to pass through, and optionally which device to target for extension-backed tools. BrowserAgentApiRequest (conceptual) ``` interface BrowserAgentApiRequest { /** * Canonical tool name, e.g. "planner" or "get_browser_tabs". * Only one of "tool" or "action" is required. */ tool?: string; /** * Optional alias of "tool". Use canonical snake_case tool names. */ action?: string; /** * Parameters for the tool. "params" and "parameters" are equivalent. * Prefer canonical snake_case parameter names. */ params?: Record; parameters?: Record; /** * Optional: route extension-backed tools to a specific Chrome profile / device. * Leaving this blank auto-selects a connected browser that answers commands; * for the unified agent / scrape tools, a cloud browser if none can be reached. * Cloud-only tools ignore this field. */ deviceId?: string; device_id?: string; /** * Accepted but not used — each tool has its own limit (cloud_agent: params.timeoutMs, * 30 s–12 min, default 12 min; cloud_scrape: 5 min; device agent runs: 24 min). */ timeout?: number; /** * Reserved for future async modes. */ async?: boolean; webhookUrl?: string; } ``` ### Top-level fields `tool`string Canonical tool name (snake\_case), e.g. 'planner' or 'get\_browser\_tabs'. Only one of tool/action is required. `action`string Optional alias of tool. Use canonical snake\_case tool names for reliability. `params / parameters`object JSON object of tool-specific parameters. 'params' and 'parameters' are aliases. Prefer snake\_case parameter names. `params.options.ui.emitEvents`booleandefault `false` Opt-in only. Set true to write execution progress events for SSE/polling consumers. If omitted/false, no execution event stream is written. `deviceId / device_id`string Optional device routing for extension-backed tools. If omitted, we pick the most recently active online browser extension device for that user. Cloud-only knowledge base tools ignore this field. `timeout`numberdefault `—` Accepted but not used: each tool has its own limit. cloud\_agent runs up to 12 minutes (set params.timeoutMs, 30 s–12 min), cloud\_scrape up to 5 minutes, and agent runs on your device up to 24 minutes (a device run still going after 5 minutes answers with its execution\_id). `async / webhookUrl`boolean / string Reserved for future async execution modes. Ignored for now. **emitEvents policy:** API and extension/MCP executions only emit events when`options.ui.emitEvents: true`. CLI streaming defaults on for `run`, `agent`, and `scrape` (use `--no-stream` to disable). Streamed payloads at or under 1MB stay inline; larger payloads include inline preview markers and storage references (\`outputRef\` / \`resultRef\` / \`responseRef\`) for full downloads. The Browser as API/MCP exposes extension-backed browser tools, cloud-only tools, scheduling/trigger management, and utility tools. They include browser tools without model credits, credit-based agent tools, cloud tools, utilities, and user-defined functions. Browser tools are free on every plan; agent tools in your Chrome require a subscription. The Cloud tools that start a billed run (`cloud_agent`, `cloud_scrape`, and `agent` or `scrape` when they run in the cloud) need a paid plan too: on the free plan they are not listed, and a call to them is refused with an upgrade message (HTTP 402 on the REST endpoint). ### Unified tools (start here) - `agent` – run an end-to-end task from one prompt. Runs in your own signed-in Chrome whenever the extension is connected (keeps logins, cookies, sessions); falls back to rtrvr's cloud browser, with the logins you saved, only when no device is connected. - `scrape` – read one or more URLs (page content + accessibility tree). Same routing: your Chrome when connected, a cloud browser otherwise. - Both accept `target`: `"auto"` (default, as above), `"extension"` (require your Chrome; errors if no device is connected), or `"cloud"` (force rtrvr's cloud browser, which starts with your [saved logins](#saved-logins)). ### Browser tools without model credits - `get_browser_tabs` – list open tabs (filter by all/active/domain). - `get_page_data` – get accessibility-tree representations for specific tab IDs. - `take_page_action` – run system tools like click, type, scroll, etc. ### Credit-based tools - `planner` – multi-step planning and tool orchestration from natural language. - `act_on_tab` – intelligent page interaction with optional structured schemas. - `extract_from_tab` – structured extraction to JSON or Google Sheets. - `crawl_and_extract_from_tab` – multi-page crawls with schema extraction. - `replay_workflow` – replay a previously executed workflow by task ID or shared URL. - `schedule` – create a scheduled workflow on the browser extension. Without `schedule_id`, every call creates a new schedule. To change a saved one in place, pass its `schedule_id` (from `list`, kind `"schedules"`) with the complete new task text in `user_input`, a new `period_in_minutes`, `enabled` (`false` pauses, `true` resumes) and/or `tab_selection`. Editing an extension schedule needs extension 37.9.5 or later on that device; an unknown ID fails instead of creating anything. A cloud schedule's ID is edited on rtrvr.ai with no device: its `frequency`, `time_zone`, `start_at`, `name`, `notifications` and task text, and pause or resume. A paused schedule stays paused unless `enabled` is `true`, and an edit never starts a run (see [Edit a Cloud Schedule over MCP](/docs/schedules#edit-a-cloud-schedule-over-mcp)). - `trigger_setup` – create or modify a trigger workflow on the browser extension. ### Cloud tools (no extension required) - `cloud_scrape` – scrape web pages in rtrvr's cloud browser, returns accessibility trees. Starts with your [saved logins](#saved-logins). Needs a paid plan. - `cloud_agent` – execute AI agent tasks in rtrvr's cloud browser with structured output. Starts with your [saved logins](#saved-logins). Needs a paid plan. For a long list, send it in batches with your own `trajectoryId`, `dataInputs` and `continue_from` (see [Large jobs in batches](#batches)). - `list_skills` – list your skill files (persistent markdown memory the agent reads and updates). - `get_skill` – read one skill file's full markdown by name. - `check_results` – ask about the stored execution results of your scheduled (`kind: "schedules"`) or trigger (`kind: "triggers"`) workflows. Schedules cover cloud and extension schedules, and cloud schedules come back with their recent runs. Pass an `execution_id` to follow a long-running call (see [Long-running calls](#long-runs)). ### Saved logins in the cloud browser (`logins`, `session_source`) With your account's **Cookies** setting on (the default), cloud runs restore the stored sessions in the selected profile. This applies to `cloud_agent`, `cloud_scrape`, and`agent` or `scrape` when they run in Cloud. - **Save a password:** use [Secure logins](/cloud?view=logins) in Cloud. The agent can sign in when needed. Passwords and authenticator setup keys stay out of model context and tool arguments. - **Sync from Chrome:** add the site in Relay's Secure logins panel to copy its current session to Default. - **Sign in during a cloud task:** use Take control, or let the agent use a saved password. A successful sign-in saves the session for later tasks in the same profile. Scrape calls restore sessions; they do not perform the agent's password sign-in flow. If a session expires or the site needs verification, sign in in a cloud agent task first. For multiple accounts on one site, name the account in the task or use a separate [browser profile](/docs/profiles). See [Secure logins](/docs/cookie-sync) for setup, updates, and removal. Never put a password or cookie value in a prompt. **Check which sessions a run used:** the result lists them as `logins`, as does `check_results` during and after a cloud run. The **Logins** menu below the Cloud prompt lists the selected profile's sites. Cookie names and values are never returned. logins in a cloud\_agent result ``` { "success": true, "status": "success", "logins": { "applied": true, "sites": [ { "site": "google.com", "domains": ["accounts.google.com", "google.com"], "signedIn": true, "source": "Cookie Sync from Chrome on MacIntel (device eJq5Q5BqOfQ)", "deviceId": "eJq5Q5BqOfQ", "syncedAt": "2026-10-05T11:13:04.000Z", "taskSite": true }, { "site": "substack.com", "domains": ["substack.com"], "signedIn": true, "source": "saved in a cloud task", "deviceId": "cloud-browser", "syncedAt": "2026-10-04T09:00:00.000Z" } ] } } ``` `applied`boolean Saved logins were applied to the run. false when Cookies was off for it or nothing was saved; note says which. `sites[].site / domains`string / string\[\] The site and the saved domains it covers. `sites[].signedIn`boolean The saved cookies (or the site's saved sign-in) look signed in. `sites[].source / deviceId`string Where the login came from: "Cookie Sync from Chrome on MacIntel (device …)", or "saved in a cloud task" (deviceId "cloud-browser"). `sites[].syncedAt`string | null When it was last synced or saved (ISO 8601). `sites[].taskSite`true A URL the task named is on this site. `taskSitesWithoutLogin`string\[\] Sites the task named that started without a signed-in saved login. **Run without them:** pass `session_source: "none"` (the same as `settings.cookieSync.enabled: false`). Every site starts signed out, and nothing the run signs in to is saved. To turn them off for every run, switch **Cookies** off in the rtrvr.ai/cloud chat bar. **Use one device's logins:** pass `session_source: {"device_id": "…"}` with a `deviceId` from `logins` (`"cloud-browser"` for sessions saved in cloud tasks), and optionally `domains` to use only those sites. Only that device's saved logins on your account are read. A device with none, or a site it never saved, is refused before the run starts. A sign-in during such a run is saved to that device's copy of the site. Pass the same `session_source` on every call that continues the run. On `agent` and `scrape`, `session_source` runs the task in the cloud browser; with `target: "extension"` it is refused, because your own Chrome always uses its own logins. ### Use a saved proxy from MCP or the API Save your proxy in [Cloud Settings → Proxy Config](/cloud?view=settings). Choose it as your default and save settings to use it across Cloud, API, and MCP. To override for one call, pass its exact name or ID. Credentials stay in your account. ``` { "settings": { "proxyConfig": { "mode": "custom", "selectedProxyName": "My Taiwan proxy" } } } ``` For `cloud_agent` and `cloud_scrape`, put `settings` inside the MCP tool's `arguments` or the tool API's `params`. For `POST /agent` and `POST /scrape`, put it in the request body. A saved `selectedProxyId` can replace `selectedProxyName`. - Omit `proxyConfig` to use your profile default, falling back to Retriever's managed proxy when none is set. Use `{"mode":"default"}` to explicitly choose the managed proxy. - The Cloud chat-bar selection overrides routing for that chat without changing your profile default. Choose “Use my default route” to reset it. MCP `list` with `kind: "proxies"` shows saved proxies and marks the default; managed proxy connection details remain private. - Use `{"mode":"none"}` for a direct cloud connection. - Saved names are case-sensitive. Unknown names and IDs fail; duplicate names require an ID. If both selectors are supplied, they must identify the same proxy. - Schedules created from a run retain its routing choice. Permission to use another route belongs to the schedule, so a one-run fallback does not enable it. You can also provide a proxy for just one request. Use an HTTP or HTTPS proxy that supports CONNECT; keep credentials out of shared snippets and client-side code. ``` { "settings": { "proxyConfig": { "mode": "custom", "selectedProxyId": "request-proxy", "customProxies": [ { "id": "request-proxy", "host": "proxy.example.net", "port": 8080, "scheme": "http", "username": "YOUR_USERNAME", "password": "YOUR_PASSWORD" } ] } } } ``` ### Go out through your own computer with Tailscale A Tailscale tunnel sends a cloud run's traffic out through a computer you own, so sites see your home connection. It uses no proxy credits. Once saved, choose it like any saved proxy: as your default, in the chat bar, or by its exact name or ID with `{"mode":"custom"}`. Tailscale connection failures retry once, then stop before the task starts. To allow managed fallback for an API request, send `settings.proxyConfig.tailscaleFallback: "managed"`. Omit it or use `"stop"` to stay on Tailscale. Fallback uses a different IP and normal proxy charges apply. [Set up a Tailscale tunnel](/docs/tailscale): the steps, the limits, and parallel runs. ### Choose where the managed proxy exits Add `location` to Retriever's managed proxy to run from a country, and optionally a region or city in it. The cloud browser's time zone and language follow the exit, so sites show dates, prices and pages the way a local visitor sees them. ``` { "settings": { "proxyConfig": { "mode": "default", "location": { "country": "IT", "city": "Milan" } } } } ``` - One field may list up to 5 places for an exit in any of them: countries (`{"country": ["IT", "FR", "DE"]}`, with no region or city), regions of one country (`{"country": "US", "region": ["CA", "WA"]}`, with no city) or cities of one country (`{"country": "IT", "city": ["Milan", "Rome"]}`). A comma-separated string such as `"IT,FR,DE"` works too. `egress` names the country the run used. - The result's `egress` says where the run exited, for example `{"country":"IT","city":"Milan","timezone":"Europe/Rome"}`. `relaxed: true` means the city or region had no exit and the run used more of the country. - A location goes only with the managed proxy (`mode: "default"`, which it implies when you leave `mode` out). Next to a saved proxy or `"none"` the call is refused. - Same field everywhere: `settings.proxyConfig.location` on `POST /agent` and `POST /scrape`, and on the MCP tools `cloud_agent` and `cloud_scrape`. MCP and the tool API also take the shorthand `proxy_location`, such as `"proxy_location": "IT"`, `"proxy_location": "IT,FR,DE"` or `"proxy_location": {"country": "US", "region": "NY"}`; with `agent` or `scrape` it runs the task in the cloud browser. - Save a location under [Cloud Settings → Proxy Config](/cloud?view=settings) next to the managed default to use it for every run that names no route, schedules included. In the Cloud chat bar, pick Retriever managed proxy and set Location for that chat only. - A few hosts that always connect directly from the cloud, such as some government sites and file storage, do not use the location. ### Supported locations A location names a country, and optionally a region or city in it. Each field takes one value, or a list of up to 5 for an exit in any of them. Field Format Examples `country` Two-letter ISO 3166-1 code (`UK` is read as `GB`). A list of countries takes no region or city. `IT`, `US`, `["IT", "FR", "DE"]` `region` Optional. The part after the dash of an ISO 3166-2 code in that country. A list of regions takes no city. `NY` for US-NY, `25` for IT-25 (Lombardy) `city` Optional. The city's English name, in that country. `Milan`, `New York`, `["Milan", "Rome"]` If the city has no exit, the run tries its region, then the whole country. It never moves to another country. If none of the countries you asked for has an exit, the run does not start and the call returns `503 PROXY_LOCATION_UNAVAILABLE` with a message that says so. Availability is live: exits come and go with the residential pool, and every run checks its own location before it starts. `GET https://api.rtrvr.ai/proxy-locations` with your API key returns the country list below, with the date each country was checked, the format and the fallback rule. To check a region, a city or a list right now, send `POST https://api.rtrvr.ai/proxy-location/check` with `{"location": {"country": "IT", "city": "Milan"}}`. It answers `{"available": true, "egress": {...}}` with where a run would exit, or `{"available": false, "message": "..."}`. Cloud Settings and the chat bar run the same check and only take places that have an exit. 120 countries had an exit when checked on 11 November 2026 - Åland Islands `AX` - Albania `AL` - American Samoa `AS` - Andorra `AD` - Anguilla `AI` - Antigua & Barbuda `AG` - Argentina `AR` - Armenia `AM` - Aruba `AW` - Australia `AU` - Austria `AT` - Azerbaijan `AZ` - Bahamas `BS` - Bahrain `BH` - Barbados `BB` - Belarus `BY` - Belgium `BE` - Belize `BZ` - Bermuda `BM` - Bosnia & Herzegovina `BA` - Brazil `BR` - British Virgin Islands `VG` - Bulgaria `BG` - Canada `CA` - Caribbean Netherlands `BQ` - Cayman Islands `KY` - Chile `CL` - China `CN` - Colombia `CO` - Costa Rica `CR` - Côte d’Ivoire `CI` - Croatia `HR` - Curaçao `CW` - Cyprus `CY` - Czechia `CZ` - Denmark `DK` - Dominica `DM` - Dominican Republic `DO` - Egypt `EG` - Equatorial Guinea `GQ` - Estonia `EE` - Falkland Islands `FK` - Faroe Islands `FO` - Finland `FI` - France `FR` - French Guiana `GF` - French Polynesia `PF` - Gabon `GA` - Georgia `GE` - Germany `DE` - Gibraltar `GI` - Greece `GR` - Greenland `GL` - Grenada `GD` - Guadeloupe `GP` - Guam `GU` - Guernsey `GG` - Hungary `HU` - Iceland `IS` - India `IN` - Iran `IR` - Ireland `IE` - Isle of Man `IM` - Israel `IL` - Italy `IT` - Jamaica `JM` - Japan `JP` - Jersey `JE` - Kazakhstan `KZ` - Kuwait `KW` - Latvia `LV` - Lithuania `LT` - Luxembourg `LU` - Malta `MT` - Martinique `MQ` - Mexico `MX` - Moldova `MD` - Monaco `MC` - Montenegro `ME` - Montserrat `MS` - Namibia `NA` - Netherlands `NL` - New Zealand `NZ` - North Macedonia `MK` - Norway `NO` - Oman `OM` - Palestinian Territories `PS` - Panama `PA` - Peru `PE` - Philippines `PH` - Poland `PL` - Portugal `PT` - Puerto Rico `PR` - Qatar `QA` - Romania `RO` - San Marino `SM` - Saudi Arabia `SA` - Serbia `RS` - Seychelles `SC` - Sint Maarten `SX` - Slovakia `SK` - Slovenia `SI` - South Korea `KR` - Spain `ES` - St. Kitts & Nevis `KN` - St. Lucia `LC` - St. Martin `MF` - St. Vincent & Grenadines `VC` - Sweden `SE` - Switzerland `CH` - Taiwan `TW` - Trinidad & Tobago `TT` - Türkiye `TR` - Turks & Caicos Islands `TC` - U.S. Virgin Islands `VI` - Ukraine `UA` - United Arab Emirates `AE` - United Kingdom `GB` - United States `US` - Uruguay `UY` 129 countries had no exit on 11 November 2026 These codes are accepted, but a run that asks only for them is refused until an exit appears. Check one before you rely on it, or list it with a country that has an exit. - Afghanistan `AF` - Algeria `DZ` - Angola `AO` - Antarctica `AQ` - Bangladesh `BD` - Benin `BJ` - Bhutan `BT` - Bolivia `BO` - Botswana `BW` - Bouvet Island `BV` - British Indian Ocean Territory `IO` - Brunei `BN` - Burkina Faso `BF` - Burundi `BI` - Cambodia `KH` - Cameroon `CM` - Cape Verde `CV` - Central African Republic `CF` - Chad `TD` - Christmas Island `CX` - Cocos (Keeling) Islands `CC` - Comoros `KM` - Congo - Brazzaville `CG` - Congo - Kinshasa `CD` - Cook Islands `CK` - Cuba `CU` - Djibouti `DJ` - Ecuador `EC` - El Salvador `SV` - Eritrea `ER` - Eswatini `SZ` - Ethiopia `ET` - Fiji `FJ` - French Southern Territories `TF` - Gambia `GM` - Ghana `GH` - Guatemala `GT` - Guinea `GN` - Guinea-Bissau `GW` - Guyana `GY` - Haiti `HT` - Heard & McDonald Islands `HM` - Honduras `HN` - Hong Kong SAR China `HK` - Indonesia `ID` - Iraq `IQ` - Jordan `JO` - Kenya `KE` - Kiribati `KI` - Kyrgyzstan `KG` - Laos `LA` - Lebanon `LB` - Lesotho `LS` - Liberia `LR` - Libya `LY` - Liechtenstein `LI` - Macao SAR China `MO` - Madagascar `MG` - Malawi `MW` - Malaysia `MY` - Maldives `MV` - Mali `ML` - Marshall Islands `MH` - Mauritania `MR` - Mauritius `MU` - Mayotte `YT` - Micronesia `FM` - Mongolia `MN` - Morocco `MA` - Mozambique `MZ` - Myanmar (Burma) `MM` - Nauru `NR` - Nepal `NP` - New Caledonia `NC` - Nicaragua `NI` - Niger `NE` - Nigeria `NG` - Niue `NU` - Norfolk Island `NF` - North Korea `KP` - Northern Mariana Islands `MP` - Pakistan `PK` - Palau `PW` - Papua New Guinea `PG` - Paraguay `PY` - Pitcairn Islands `PN` - Réunion `RE` - Russia `RU` - Rwanda `RW` - Samoa `WS` - São Tomé & Príncipe `ST` - Senegal `SN` - Sierra Leone `SL` - Singapore `SG` - Solomon Islands `SB` - Somalia `SO` - South Africa `ZA` - South Georgia & South Sandwich Islands `GS` - South Sudan `SS` - Sri Lanka `LK` - St. Barthélemy `BL` - St. Helena `SH` - St. Pierre & Miquelon `PM` - Sudan `SD` - Suriname `SR` - Svalbard & Jan Mayen `SJ` - Syria `SY` - Tajikistan `TJ` - Tanzania `TZ` - Thailand `TH` - Timor-Leste `TL` - Togo `TG` - Tokelau `TK` - Tonga `TO` - Tunisia `TN` - Turkmenistan `TM` - Tuvalu `TV` - U.S. Outlying Islands `UM` - Uganda `UG` - Uzbekistan `UZ` - Vanuatu `VU` - Vatican City `VA` - Venezuela `VE` - Vietnam `VN` - Wallis & Futuna `WF` - Western Sahara `EH` - Yemen `YE` - Zambia `ZM` - Zimbabwe `ZW` A location costs nothing extra. Managed proxy traffic is billed per GB, about 500 credits per GB ([pricing](/pricing)), the same with or without a location. ### Utility & user-defined tools - `list_devices` – list all registered extension devices and online/offline status. - `get_current_credits` – fetch current plan, credits used, and credits remaining. - `upload_file` – upload a file (base64, URL import, or signed upload URL) to rtrvr storage and get back a `storageUrl` to attach to agent tools. Free, no device required. - `list_executions` – list the commands running on your devices, each with its `executionId` and the tabs it is using. Free, no device required. - `cancel_execution` – stop a running command by its `execution_id` and get back what it had produced so far. It does not undo actions already taken on a page. Free, no device required. - `list` – list your saved items by `kind`: `"recordings"` (ID, name, timestamp), `"custom_functions"` (metadata only, not code), `"schedules"` (cloud and extension schedules, each with a `source`) or `"triggers"` (trigger configs). Works offline. - `user_function` – user-defined tools created in Cloud and executed in the extension sandbox. ### Credit budget (`max_credits`) `agent`, `planner` and `cloud_agent` take `max_credits`: the credit ceiling for that one run. Omit it to use the Credit Ceiling / Task setting (100 credits unless changed). When the run has spent that much it returns `status: "requires_input"` with a question keyed `credit_ceiling_continue`: answer `"Continue"` to go on with a fresh budget of the same size, or `"Stop here"` to end with what it produced. A value that is not a positive number is refused before the run starts. ### Live view (`live_view`) `cloud_agent`, and `agent` when it runs in the cloud, take `live_view: true` to let you watch the run's cloud browser while it works: open the run in [Executions](/cloud?view=executions) and choose **Watch live**. It is off by default, and it must be set when the run starts: a run started without it cannot be watched. A run in your own Chrome needs no live view. ### Browser time zone and language (`settings.browser`) `cloud_agent`, and `agent` when it runs in the cloud, take `settings.browser.timezone` (an IANA name such as `"Asia/Singapore"`, not an offset or an abbreviation) and `settings.browser.locale` (a language tag such as `"en-US"`): the clock and language the cloud browser runs on, which is how pages show times and how date/time pickers read them. Omit them and the clock is set where the cloud browser started (`America/Chicago`, `en-US` when that can't be looked up), so set them when times matter. The agent is told the browser's zone and offset either way, converts requested times into it before typing them, and says the converted value in the result. An invalid value is refused before the run starts. A run in your own Chrome uses your computer's clock. See [Agent API: Browser time zone and language](/docs/agent#browser-clock). ### Keep tabs open (`keep_tabs_open`) `planner`, `act_on_tab`, `extract_from_tab` and `crawl_and_extract_from_tab` (and `agent` when it runs in your Chrome) work in background tabs they open, and close those tabs when the run ends. Pass `keep_tabs_open: true` to leave them open, whether the run finishes, fails or is cancelled: the result lists them as `keptTabs` (`tabId`, `url`, `title`; `data.keptTabs` over HTTP). Read one with `get_page_data`, continue in it by passing it as `tab_id`, and close it with `take_page_action` and `close_tab` when you are done. A tab you pass as `tab_id` is never closed either way. Kept tabs count toward your **Max parallel tabs** setting for tabs that connected apps leave open in your browser, with the ones `take_page_action` opens. Past it, a run that would keep its tabs is refused before it starts, with the open tabs listed. An extension too old for `keep_tabs_open` closes the tabs as before, and `warnings` says so. ### Only the selected model (`disable_fallbacks`) `planner`, `agent`, `cloud_agent`, `act_on_tab`, `extract_from_tab`, `crawl_and_extract_from_tab` and `schedule` take `disable_fallbacks: true`: the call uses only the selected model, at the reasoning level you asked for. Another provider that serves the same model may still answer (GPT-6 Luna on AWS Bedrock or OpenAI), and a managed model bills credits as usual. The call never switches to another model or a lower reasoning level, and an API key of your own that fails never falls back to credits. When the selected model cannot finish a step, the run stops there with `MODEL_UNAVAILABLE` (keeping what it already produced) and these details in `modelUnavailable`. It is final: the step is not retried. `modelUnavailable.product`string The selected model. `modelUnavailable.effortRequested`string The reasoning level asked for; "auto" when none was set. `modelUnavailable.blockedFallback`string What the run would have switched to: "rescue" (another model answers the step), "gemini\_last\_resort" (Gemini as a last resort), "credits" (a managed model on credits after your own key failed), "sibling\_model" (another model on the same connection), "effort\_step\_down" (a lower reasoning level), "web\_search\_model" (web search through another model) or "caption" (another model reads an image). `modelUnavailable.reason`string Why the selected model could not do the step. It takes `true` or `false`, also spelled `"true"`, `"false"`, `1`, `0`, `"1"` or `"0"`. Any other value is refused before the run starts. It applies to that call only and never changes your saved settings: omit it to use the **Disable fallbacks** setting in Settings, or pass `false` to allow fallbacks for one call while that setting is on (a run in your Chrome on an older extension build keeps the saved setting). On `schedule` it covers the call that sets the schedule up; the scheduled runs follow your saved setting. The nested form, `settings.llmIntegration.disableCreditsFallback`, still works. ChatGPT's hosted MCP connector can keep an old tools list, so a client that does not see `disable_fallbacks` can send the nested form instead. When the result carries the run's `model` receipt, `model.fallbacks` is `"disabled"` for a run with fallbacks off, and `model.fallbacksBlocked` lists each fallback it refused (`blockedFallback`, `reason` and, when known, `at`, the step it happened in), including ones the run finished without. ### Tool name aliases Use canonical snake\_case tool names. For direct HTTP, `action` can mirror `tool`: - `tool: "agent"` – routes to `planner` in your signed-in Chrome when a device is connected (or `target: "extension"` is set), otherwise to `cloud_agent`. `target: "cloud"` forces the cloud browser. On the extension side a request with a `schema` routes to `act_on_tab`. - `tool: "scrape"` – routes to the extension scrape in your signed-in Chrome when a device is connected (or `target: "extension"` is set), otherwise to `cloud_scrape`. - Retired names still work as aliases: `list_recordings`, `list_custom_functions`, `list_schedules`, `list_triggers` → `list`; `check_schedule_results`, `check_trigger_results` → `check_results`. They return the same response shape as before but no longer appear in `tools/list`. - `tool: "planner"` is equivalent to `action: "planner"`. - `tool: "act_on_tab"` is equivalent to `action: "act_on_tab"`. - For MCP protocol calls, use tool names exactly as returned by `tools/list`. ### Parameter aliases Prefer snake\_case parameters. Common compatibility aliases include: - `user_input` ⇔ `userInput` - `tab_urls` ⇔ `tabUrls` - `device_id` ⇔ `deviceId` - `max_steps` ⇔ `maxSteps` - `max_credits` ⇔ `maxCredits` - `live_view` ⇔ `liveView` - `keep_tabs_open` ⇔ `keepTabsOpen` - `task_id` ⇔ `taskId` - `recording_id` ⇔ `recordingId` - `file_urls` ⇔ `fileUrls` - `image_urls` ⇔ `imageUrls` - `shared_workflow_url` ⇔ `sharedWorkflowUrl` - `store_id` ⇔ `storeId` - `conversation_context` ⇔ `conversationContext` - `tab_ids` ⇔ `tabIds` - `web_page_map` ⇔ `webPageMap` - `auth_token` ⇔ `authToken` All credit tools support file and image inputs via publicly fetchable URLs. Files are automatically uploaded to Firebase Storage and passed to the agent as context. For local files that aren't hosted anywhere, use the `upload_file` tool first (see below) and pass the returned `storageUrl`. Each file can be up to 128 MB. The model reads files up to 20 MB; for a larger file it sees only the name, type and size, and the agent can still upload the file into a page or pass it on to tools and later steps. Supported input parameters: - `file_urls` – array of publicly fetchable file URLs (CSV, PDF, etc.) - `image_urls` – array of publicly fetchable image URLs (JPG, PNG, etc.) - `recording_id` – ID of a recorded workflow to use as context `file_urls` CSV, PDF, text files to use as input data `image_urls` JPG, PNG images for visual context `recording_id` Recorded workflow to use as context Example with file inputs ``` { "tool": "planner", "params": { "user_input": "Upload this CSV and submit the form", "tab_urls": ["https://example.com/upload"], "file_urls": ["https://example.com/data.csv"], "image_urls": ["https://example.com/screenshot.png"], "recording_id": "rec_abc123" } } ``` ### Uploading local files: `upload_file` The `upload_file` tool stores a file under your account and returns a `storageUrl` + `gcsUri`. It is free, needs no device, and supports three modes (files up to 128 MB; send large files by URL or signed upload, not base64): - **Base64:** pass `name`, `mimeType`, and base64 `data` — best for small files. - **URL import:** pass `url` — the file is copied into rtrvr storage. - **Signed upload URL:** pass only `name` and `mimeType` — you get back a signed `uploadUrl` valid for 15 minutes. PUT the raw bytes to it (no base64 inflation), then use the returned `storageUrl`. Local file → signed upload → agent attachment ``` # 1. Request a signed upload URL (no bytes in the request) curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxx" \ -H "Content-Type: application/json" \ -d '{"tool": "upload_file", "params": {"name": "resume.pdf", "mimeType": "application/pdf"}}' # → { "mode": "signed_url", "uploadUrl": "https://storage.googleapis.com/…", "storageUrl": "…", "gcsUri": "gs://…" } # 2. Upload the raw bytes curl -X PUT -H "Content-Type: application/pdf" --upload-file ./resume.pdf "" # 3. Attach it to any agent tool curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxx" \ -H "Content-Type: application/json" \ -d '{ "tool": "planner", "params": { "user_input": "Apply to this job with my resume", "tab_urls": ["https://example.com/careers/apply"], "file_urls": [""] } }' ``` For `agent` / `cloud_agent`, attach files via the `files` parameter instead of `file_urls`: cloud\_agent / agent files parameter ``` { "tool": "agent", "params": { "user_input": "Summarize the attached report", "files": [ { "displayName": "report.pdf", "uri": "", "mimeType": "application/pdf" } ] } } ``` The `replay_workflow` tool allows you to re-execute a previously completed workflow. You can replay your own workflows by task ID, or replay workflows shared by other users via a shared URL. Two ways to replay: - `task_id` – replay your own workflow by execution ID - `shared_workflow_url` – replay a workflow shared by another user At least one of these must be provided. ### Parameters `task_id`string The task ID from a previous workflow execution in your history. `shared_workflow_url`string A shared workflow URL (e.g., https://rtrvr.ai/shared/Tasks/userId/taskId/token). Use this to replay workflows shared by other users. `tab_execution_mode`stringdefault `new_tabs` How to handle tabs during replay. `new_tabs``reuse_tabs``current_context` `recording_id`string Optional recording ID to use as additional context. `file_urls`string\[\] Optional file URLs to include as input. `image_urls`string\[\] Optional image URLs to include as input. Replay workflow examples ``` // By task ID (your own workflow) { "tool": "replay_workflow", "params": { "task_id": "abc123xyz", "tab_execution_mode": "new_tabs" } } // By shared URL (another user's workflow) { "tool": "replay_workflow", "params": { "shared_workflow_url": "https://rtrvr.ai/shared/Tasks/userId/taskId/token" } } ``` Below is a conceptual TypeScript view of each tool's parameters. Agentic tool parameters ``` // Unified tools — your signed-in Chrome when connected, else a cloud browser agent({ user_input: string; target?: "auto" | "extension" | "cloud"; // default "auto" urls?: string[]; schema?: object; files?: { displayName: string; uri: string; mimeType: string }[]; device_id?: string; // pin a specific Chrome profile max_credits?: number; // credit budget for this run (default: your Credit Ceiling / Task) disable_fallbacks?: boolean; // only the selected model and reasoning level, else MODEL_UNAVAILABLE (default: your setting) keep_tabs_open?: boolean; // your Chrome only: keep the tabs the run opens (default: false) live_view?: boolean; // cloud runs: watch the run live in Executions (default: false) session_source?: "none" | { device_id: string; domains?: string[] }; // cloud runs: which saved logins (default: all) }); scrape({ urls: string[]; target?: "auto" | "extension" | "cloud"; // default "auto" device_id?: string; session_source?: "none" | { device_id: string; domains?: string[] }; // cloud runs: which saved logins (default: all) }); // Free tools get_browser_tabs({ filter?: "all" | "active" | "domain"; domain?: string; device_id?: string; }); get_page_data({ tabIds: number[]; device_id?: string; }); take_page_action({ actions: { tab_id?: number; tool_name: SystemToolName; args: Record; }[]; device_id?: string; }); // Credit tools planner({ user_input: string; context?: string; tab_urls?: string[]; tab_id?: number; // run in this tab (yours, or one a call left open); never closed keep_tabs_open?: boolean; // keep the tabs this run opens open; listed as keptTabs (default: false) max_steps?: number; device_id?: string; recording_id?: string; // Recording ID to use as workflow context file_urls?: string[]; // Publicly fetchable file URLs image_urls?: string[]; // Publicly fetchable image URLs max_credits?: number; // Credit budget for this run (default: your Credit Ceiling / Task) disable_fallbacks?: boolean; // Only the selected model and reasoning level, else MODEL_UNAVAILABLE (default: your setting) }); act_on_tab({ user_input: string; tab_urls?: string[]; schema?: { fields: { name: string; description: string; type: string; required?: boolean; }[]; }; tab_id?: number; keep_tabs_open?: boolean; // keep the tabs this run opens open; listed as keptTabs (default: false) disable_fallbacks?: boolean; // only the selected model and reasoning level, else MODEL_UNAVAILABLE (default: your setting) device_id?: string; recording_id?: string; file_urls?: string[]; image_urls?: string[]; }); extract_from_tab({ user_input: string; tab_urls?: string[]; schema?: { fields: { name: string; description: string; type: string; required?: boolean; }[]; }; output_destination?: { // omit it for the rows only (extractedData): no sheet is written type?: "json" | "google_sheet"; // "json" (default): rows only. "google_sheet": also written to a Google Sheet new_sheet_title?: string; new_tab_title?: string; existing_sheet_id?: string; // append to this sheet instead of making a new one existing_tab_title?: string; }; tab_id?: number; keep_tabs_open?: boolean; // keep the tabs this run opens open; listed as keptTabs (default: false) disable_fallbacks?: boolean; // only the selected model and reasoning level, else MODEL_UNAVAILABLE (default: your setting) device_id?: string; recording_id?: string; file_urls?: string[]; image_urls?: string[]; }); crawl_and_extract_from_tab({ user_input: string; tab_urls?: string[]; schema?: { fields: { name: string; description: string; type: string; required?: boolean; }[]; }; max_pages?: number; follow_links?: boolean; link_pattern?: string; output_destination?: { type?: "json" | "google_sheet"; new_sheet_title?: string; }; // as extract: omit it for the rows only tab_id?: number; keep_tabs_open?: boolean; // keep the tabs this run opens open; listed as keptTabs (default: false) disable_fallbacks?: boolean; // only the selected model and reasoning level, else MODEL_UNAVAILABLE (default: your setting) device_id?: string; recording_id?: string; file_urls?: string[]; image_urls?: string[]; }); replay_workflow({ task_id?: string; // Task ID from previous execution shared_workflow_url?: string; // Shared workflow URL from another user tab_execution_mode?: "new_tabs" | "reuse_tabs" | "current_context"; recording_id?: string; file_urls?: string[]; image_urls?: string[]; }); // Cloud-only skill tools (no device_id required) list_skills({}); get_skill({ name: string; }}); // Cloud-only inventory tools (no device_id required) list({ kind: "recordings" | "custom_functions" | "schedules" | "triggers"; source?: "cloud" | "extension" | "all"; // schedules only, default "all" device_id?: string; // extension schedules / triggers: filter by device }); check_results({ kind?: "schedules" | "triggers" | "executions"; // required unless execution_id is given user_input?: string; // question about the stored results id?: string; // schedule / trigger name or ID execution_id?: string; // follow a long-running call that answered status "running" wait_seconds?: number; // with execution_id: default 25, max 45, 0 = answer now source?: "cloud" | "extension" | "all"; // schedules only, default "all" device_id?: string; // extension workflows only limit?: number; // recent runs per schedule / trigger, default 10 }); // Schedules: creates extension schedules (on a connected device); edits extension // schedules on their device and cloud schedules on rtrvr.ai (no device needed) schedule({ user_input?: string; // creating: what to run and how often; editing: the complete new task text schedule_id?: string; // edit this schedule in place (from list kind "schedules"); omit to create a NEW one source?: "cloud" | "extension"; // with schedule_id: edit only that kind (default: a cloud schedule's id edits it in the cloud) period_in_minutes?: number; // with schedule_id: new cadence (cloud: 5+, 60 = hourly, 1440 = daily) frequency?: { unit: "minutes" | "hours" | "days" | "once"; every?: number }; // cloud only, instead of period_in_minutes time_zone?: string; // cloud only: IANA zone, e.g. "Europe/London" start_at?: string; // cloud only: the dashboard's Run at, ISO 8601 name?: string; // cloud only: new name notifications?: Record; // cloud only: e.g. { email: true, slack: false }; channels not named are kept enabled?: boolean; // with schedule_id: false pauses, true resumes; omitted, the status is left as it is step?: number; // with schedule_id, extension only: 0-based step whose task text user_input replaces tab_selection?: "new_tab" | "active_tab"; // extension only: where each run starts, default "new_tab" device_id?: string; // extension only: the device to create it on, or that holds the schedule being edited disable_fallbacks?: boolean; // this call only: only the selected model sets it up (default: your setting) }); // Runs on your devices (free, no device_id required) list_executions({ device_id?: string }); cancel_execution({ execution_id: string; wait_for_partial_results?: boolean; // default true: wait up to 10 s for what the run produced }); // Utility: upload a local file to rtrvr storage (free, no device_id required) upload_file({ name?: string; // filename incl. extension; required unless url given mimeType?: string; // inferred from extension if omitted data?: string; // base64 content (small files) url?: string; // OR: public URL to import // neither data nor url → returns a signed PUT uploadUrl (15 min) // → { storageUrl, gcsUri } to pass via file_urls or files[] }); // User functions (defined in Cloud and executed in the browser sandbox) user_function({ functionName: string; // your custom parameters... }); ``` All tools return a consistent envelope with tool-specific `data` plus metadata: BrowserAgentApiResponse (conceptual) ``` interface BrowserAgentApiResponse { success: boolean; data: TData | null; error: string | null; metadata: { requestId: string; executionTime: number; tool: string; deviceId?: string; creditsUsed?: number; creditsRemaining?: number; inlineOutputMaxBytes?: number; outputTooLarge?: boolean; responseRef?: StorageReference; }; timestamp: string; } ``` Example: get\_browser\_tabs response ``` { "success": true, "data": { "tabs": [{ "id": 1, "url": "https://example.com" }], "activeTab": { "id": 1, "url": "https://example.com" }, "tabCount": 1 }, "error": null, "metadata": { "requestId": "req_abc123", "executionTime": 1234, "tool": "get_browser_tabs", "deviceId": "dj75mmaTWP0", "creditsUsed": 0, "creditsRemaining": 10000 }, "timestamp": "2025-01-01T12:00:00.000Z" } ``` - `metadata.deviceId` shows which device executed the request. - `metadata.requestId` is useful for joining logs with rtrvr.ai's internal state. - HTTP headers like `X-Credits-Used` and `X-Credits-Remaining` are also surfaced. - Large payloads keep inline previews and expose storage refs via `metadata.responseRef` and/or `outputRef`/`resultRef`. An MCP call to a long-running tool (`agent`, `planner`, `cloud_agent`, `act_on_tab`, `extract_from_tab`, `crawl_and_extract_from_tab`, `replay_workflow`) that is still going after about 40 seconds answers with `status: "running"` and an `execution_id` instead of the result. The run keeps going, and its result is kept. - Follow it with `check_results`, passing the `execution_id`. No `kind` is needed; if you pass one, use `"executions"`. - Each call waits up to 25 seconds for new steps or the result (`wait_seconds`, max 45; `0` answers immediately). It returns `state: "pending"` with the latest steps while the run is going, or `state: "done"` with the full result. Call it again until the state is `"done"`. - While a cloud run's planner is writing its plan (the first plan, a continuation, a repair or the final review), the pending reply's `execution.activity` says so: `kind: "planning"`, the `pass`, the `model` and `effort`, how long the current attempt has run against its limit, and how earlier attempts ended (a timeout, a switch to another model). Once steps run, `recentSteps` takes over. - Don't start the task again: the first run is still going. To stop a run on your device, call `cancel_execution` with its `execution_id`. Following a long-running call ``` // 1. The call answers while the run is still going { "success": true, "status": "running", "execution_id": "exec_abc123", "next": { "tool": "check_results", "arguments": { "execution_id": "exec_abc123" } } } // 2. Follow it { "tool": "check_results", "params": { "execution_id": "exec_abc123" } } // While it runs { "success": true, "kind": "executions", "execution_id": "exec_abc123", "state": "pending", "execution": { "status": "running", "recentSteps": [ ... ] } } // While a cloud run's planner writes the plan (shortened) { "success": true, "kind": "executions", "execution_id": "exec_abc123", "state": "pending", "execution": { "status": "running", "steps": 0, "activity": { "kind": "planning", "pass": "first_plan", "forSeconds": 252, "model": "gpt-6-luna", "effort": "max", "attempt": { "number": 1, "forSeconds": 252, "limitSeconds": 360 } } } } // Once it finishes: the full result, as the original call returns it { "success": true, "kind": "executions", "execution_id": "exec_abc123", "state": "done", "execution": { "status": "completed", "result": { ... } } } ``` MCP clients stop waiting on a tool call after their own timeout: Codex, for example, defaults to 60 seconds (`tool_timeout_sec`). Because a long call answers with its `execution_id` first, long tasks keep working whatever that timeout is. Direct HTTP calls (a plain JSON POST, as from n8n or a script) are not cut short at 40 seconds: they wait for the result, and only a run on your device that is still going after 5 minutes answers with its `execution_id`. For a list too long for one run, send `cloud_agent` one batch of rows at a time: - **Name each batch** with your own `trajectoryId` (8–160 characters: letters, digits, `_`, `-` or `:`). If a run with that id already exists, running or ended, nothing new starts: the reply has `status: "already_exists"` and that run's state as `check_results` reads it (its result, once it has finished). A batch you send twice never runs or bills twice. Over REST the same call answers HTTP 409. An id whose call was refused before anything started (every cloud browser busy, say) can be sent again. - **Pass the batch's rows** as `dataInputs`, as for the [/agent API](/docs/agent): each entry has `inline` (CSV, TSV, JSON or text; base64 for xlsx or parquet, with `format`), a `url`, or a `storageRef` (`{ path }` of a file you uploaded with `upload_file`). Each becomes a sheet the agent reads. One call carries about 10 MB, so use a URL or a stored file for a large table. A malformed entry is refused before anything starts. - **Continue a batch that ended short** (stopped, failed, timed out, out of credits, or partial) with `continue_from` set to its `execution_id`, and the task again in `user_input`. A new run starts with the progress the ended run saved and picks up where it stopped instead of redoing finished rows; the reply's `continuedFrom` says what was restored. Nothing starts when that run is still going (follow it with `check_results`), is waiting for an answer, finished successfully, or saved no progress; to run the task from the beginning, call without `continue_from`. Batches with cloud\_agent ``` // One batch: its own id and its rows { "tool": "cloud_agent", "params": { "trajectoryId": "investors-batch-0007", "user_input": "For each row, find the company's official site and its latest funding round. Return one result per row with a status.", "dataInputs": [{ "format": "csv", "inline": "canonicalID,name\n101,Acme Robotics\n102,Globex" }] } } // The same batch sent again: nothing new starts { "success": true, "status": "already_exists", "started": false, "execution_id": "investors-batch-0007", ... } // The batch ended short: continue it in a new run { "tool": "cloud_agent", "params": { "trajectoryId": "investors-batch-0007-b", "continue_from": "investors-batch-0007", "user_input": "For each row, find the company's official site and its latest funding round. Return one result per row with a status.", "dataInputs": [{ "format": "csv", "inline": "canonicalID,name\n101,Acme Robotics\n102,Globex" }] } } ``` Remote tool execution can be configured at a per-user and per-tool level via the extension settings and the Cloud dashboard. - Disable remote browser tools entirely for a given user. - Independently enable/disable free tools and credit tools. - Toggle individual tools inside each family. - All configuration is respected by the MCP handler; disabled tools yield an explanatory error. **Important:** Remote tool execution is enabled by default. Review allowed tools in the Chrome extension MCP / Remote Tools settings to match your security posture. If `/mcp` calls fail with `No online devices found` or other errors: - Open/close the rtrvr.ai Chrome extension popup to refresh its connection. - Rotate your API key from the extension dropdown to re-sync backend state. - Sign out and sign back into the extension to reset device registration. - Call `list_devices` to see which devices are online and which answer commands (`status`, `lastAckAt`). - A `device_not_responding` reply names the browser that did not pick the command up and your other browsers: retry with the `deviceId` of one that is responding, or open that browser (a sleeping or closed computer cannot answer) and retry. - Ensure the deviceId you're targeting matches an online device. Most device issues are resolved by refreshing the extension, rotating the API key, or resetting the sign-in. 1. Install the [rtrvr.ai Chrome Extension](https://chromewebstore.google.com/detail/retriever-ai-web-agent/jldogdgepmcedfdhgnmclgemehfhpomg). 2. Open the MCP / Remote Browser section in the extension. 3. Copy the generated MCP URL — your **API key** and **deviceId** are already embedded. Alternatively, get your API key from [rtrvr.ai/cloud](/cloud?view=api-keys). 4. For MCP clients: paste the URL directly into your MCP-enabled application (e.g. Claude). 5. For direct HTTP: call `https://mcp.rtrvr.ai` with your API key in headers. Optionally pass `deviceId` to target a specific device. 6. **Multi-device setup:** Install the extension on multiple Chrome profiles. Each gets its own deviceId. Target specific devices or leave blank for auto-selection. 7. Configure which tools to enable/disable in extension settings. The MCP URL generated by the extension includes your API key and deviceId. Treat this URL as a secret: store it safely, avoid logging it in plaintext, and rotate as needed. These snippets show the recommended integration pattern: a thin server-side helper that wraps POST `/mcp`, keeps your API key off the frontend, and centralizes rate limiting + logging. cURL ``` # 1) Your browser as an agentic API endpoint curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "tool": "planner", "params": { "user_input": "Go to ChatGPT.com, ask for top Indian restaurants in SF, and extract back citations.", "tab_urls": ["https://chatgpt.com"], "options": { "ui": { "emitEvents": true } } }, "deviceId": "dj75mmaTWP0" }' # 2) Free tool: list all tabs on the auto-selected device (no deviceId = a browser that answers) curl -X POST "https://mcp.rtrvr.ai" \ -H "X-API-Key: rtrvr_xxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "tool": "get_browser_tabs", "params": { "filter": "all" } }' # 3) Replay a workflow with file inputs curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "tool": "replay_workflow", "params": { "task_id": "abc123xyz", "tab_execution_mode": "new_tabs", "file_urls": ["https://example.com/data.csv"] } }' # 4) Planner with image context curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "tool": "planner", "params": { "user_input": "Find similar products to the one in this image", "tab_urls": ["https://amazon.com"], "image_urls": ["https://example.com/product.jpg"] } }' # 5) Cloud-only skills listing (no deviceId required) curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "tool": "list_skills", "params": {} }' # 6) Cloud-only skill read (no deviceId required) curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "tool": "get_skill", "params": { "name": "general" } }' # 7) Unified agent: runs in YOUR signed-in Chrome when the extension is connected, else a cloud browser curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "tool": "agent", "params": { "user_input": "Open my Gmail and list the subjects of unread emails from this week", "target": "auto" } }' # 8) Same routing for scrape; target "cloud" forces rtrvr's cloud browser (with your saved logins; session_source "none" reads signed out) curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "tool": "scrape", "params": { "urls": ["https://example.com/pricing"], "target": "cloud" } }' ``` YOUR NEXT RUN ## Run the example on a real site. Use Chrome for the page in front of you. Use Cloud when the run should continue on a schedule or across many pages. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Separate logins for every client. RUN # Separate logins for every client. A browser profile keeps one set of website accounts and an exit location. Its tasks use only its sessions and saved passwords. Profile management is free; task usage follows your plan. [Create a profile](/cloud)[Create API key](/cloud?view=api-keys) 01 ## Isolated A profile run never sees your other logins, and its sign-ins never leak into Default. 02 ## No extension needed Save a password, sign in inside a cloud task, or import a session file. 03 ## Same place, every run Each profile keeps an exit location, pinned from its first sign-in if you set none. Two kinds ## Profiles and Default Every account has Default. Named profiles are the ones you create. Default ### Your shared set of logins The sites you sync from Chrome, passwords you save to Default, and sessions saved during Default cloud tasks. A run on Default can use these accounts. Named profiles remain separate. Named profile ### Its own logins, nothing else A run on a profile reads only that profile's logins. Select the profile in Secure logins before adding a password. A task can use it to sign in, or you can sign in with Take control. The resulting session is saved to this profile for later tasks. In the Cloud app, the **Logins** menu below the prompt switches profiles: create, rename, delete, and set the account default there. The pick is remembered in that browser. Picking a profile with a location moves the location chip to it. REST ## Profiles API Base URL `https://mcp.rtrvr.ai/v1/profiles`. Use the same API key as `/agent` and `/scrape` (or an MCP OAuth token). Responses list names only: cookie values are never returned, and there is no export. Request Body Returns `POST /v1/profiles` `{ name, location?, proxyId?, makeDefault? }` `201 { profile }` `GET /v1/profiles` `None` `{ profiles, defaultProfileId }` `GET /v1/profiles/{id}` `None` `{ profile, sites } (names only)` `PATCH /v1/profiles/{id}` `{ name?, location?, proxyId?, makeDefault? }` `{ profile }` `DELETE /v1/profiles/{id}` `None` `{ deleted, sitesDeleted }` `PUT /v1/profiles/{id}/state` `a login file (see Import)` `{ imported, sites, skipped, ignored }` `DELETE /v1/profiles/{id}/sites/{site}` `None` `{ site, deleted, domains }` `name`string**required** 1 to 60 characters, unique on the account (case-insensitive). "Default" is reserved. `location`object | null Where runs on this profile exit: {country, region?, city?} in the same shape as settings.proxyConfig.location. null clears it. `proxyId`string | null The id of a proxy saved in Cloud Settings → Proxy Config. Runs on the profile use it instead of the managed proxy, so they keep the same IP. `makeDefault`boolean true makes this the account default: API and MCP runs that name no profile use it. false on the current default goes back to Default. Create a profile ``` curl -X POST https://mcp.rtrvr.ai/v1/profiles \ -H "Authorization: Bearer rtrvr_your_api_key" \ -H "Content-Type: application/json" \ -d '{"name": "Client A", "location": {"country": "US", "region": "NY", "city": "New York"}}' ``` Errors ### { error: { code, message } } 400 for a bad name, location or file, 404 for an unknown profile, 409 for a taken name or the 50-profile limit, 413 for a file over the caps, 429 past 30 imports an hour, 503 when profiles are briefly unavailable. Free ### Every plan Creating, importing and running on profiles costs nothing extra. Runs bill as they always do. Use it ## Run on a profile Pass `profile` (an id or the exact name, or `"default"`) to `POST /agent`, `POST /scrape`, or the MCP `cloud_agent` and `cloud_scrape` tools. Agent API on a profile ``` curl -X POST https://api.rtrvr.ai/agent \ -H "Authorization: Bearer rtrvr_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "input": "Download last month's invoices", "urls": ["https://billing.example.com/invoices"], "profile": "Client A" }' ``` MCP cloud\_agent on a profile ``` { "name": "cloud_agent", "arguments": { "user_input": "Reply to the newest support ticket", "urls": ["https://support.example.com"], "profile": "Client A" } } ``` `profile`string Omit it to use the account default profile (Default when none is set). A run that continues an earlier one stays on that run's profile. `session_source`MCP only Still works for one device's logins or "none". Pass profile or session\_source, not both. `settings.proxyConfig`object A route the request names wins over the profile's location or saved proxy. The MCP result's `logins` names the profile a run used. Schedules run on the profile their saved request names, never on a later account default. Bring your logins ## Import a login file Send the file to `PUT /v1/profiles/{id}/state`, or drop it on the Logins menu's Import box in the Cloud app. Each site in the file replaces that site's stored session in the profile; saved passwords and other sites stay. Add `"replace": true` to clear every other site first. Import ``` # A Playwright storageState file curl -X PUT https://mcp.rtrvr.ai/v1/profiles/PROFILE_ID/state \ -H "Authorization: Bearer rtrvr_your_api_key" \ -H "Content-Type: application/json" \ --data-binary @state.json # A cookies.txt file curl -X PUT https://mcp.rtrvr.ai/v1/profiles/PROFILE_ID/state \ -H "Authorization: Bearer rtrvr_your_api_key" \ -H "Content-Type: text/plain" \ --data-binary @cookies.txt # A Cookie header: say which page it was sent to curl -X PUT https://mcp.rtrvr.ai/v1/profiles/PROFILE_ID/state \ -H "Authorization: Bearer rtrvr_your_api_key" \ -H "Content-Type: application/json" \ -d '{"content": "Cookie: session=...; csrftoken=...", "url": "https://app.example.com/"}' ``` Format How to get it Playwright `storageState` JSON `await context.storageState({ path: "state.json" })` after signing in (snippet below). Its `localStorage` is not imported; the response says how many origins were left out. Cookie-Editor or EditThisCookie JSON Open the extension on the signed-in site and export as JSON. Netscape `cookies.txt` A "Get cookies.txt" style exporter, `curl -c`, or `yt-dlp --cookies`. `#HttpOnly_` lines are kept as HttpOnly. DevTools "Copy as cURL" Chrome DevTools → Network → reload the signed-in page → right-click its first request → Copy → Copy as cURL (bash or cmd). Paste it into "Paste from DevTools". A `Cookie:` header + URL The request's Cookie header from DevTools, with the page URL it was sent to. Save a Playwright storageState ``` // After signing in with Playwright: await context.storageState({ path: "state.json" }) // Or sign in by hand once, then save the state: const browser = await chromium.launch({ headless: false }) const context = await browser.newContext() const page = await context.newPage() await page.goto("https://app.example.com/login") // … sign in in the window that opened … await context.storageState({ path: "state.json" }) ``` cURL and headers ### Saved for 30 days A Cookie header carries no expiry or flags, so each cookie is saved for that host only, path /, secure, not HttpOnly, and expires 30 days after the import. Re-import to refresh it. Watch out ### document.cookie is not enough `document.cookie` leaves out HttpOnly cookies, which is where most sites keep the login. Chrome's cookie file on disk is encrypted, so copying it does not work either. Use one of the formats above. Limits: 2 MB per file, 100 sites, 300 cookies per site, 30 imports per hour per account. Expired cookies are skipped. Each site gets a sign-in check from its cookie names, so you see right away which sites carry a login. Look like the same visitor ## Location pinning Sites notice a login that hops between countries. A profile keeps where its runs exit. Managed proxy ### Same city or region, not the same IP A profile's location sends every run through Retriever's managed proxy in that country, region or city. The address changes from run to run within that place. The browser's time zone and language follow the exit. Saved proxy ### The same IP every time Attach a proxy saved in Cloud Settings → Proxy Config (`proxyId`) and every run on the profile uses it. Automatic ### Pinned from the first sign-in A profile with no location and no proxy is pinned to where its run actually exited the first time a run saves a login into it. A run with no managed proxy pins nothing. Change it any time with PATCH or the location chip. Kept apart ## How profile logins are stored - Cookie values and site sign-in state are encrypted (AES-256-GCM) under a key of the profile's own, which Google Cloud KMS protects. Saved passwords and setup keys are sealed separately and are never shown again. - Names, sites and the sign-in check stay readable, so lists and the Logins chip work without decrypting anything. - Only cloud runs on that profile decrypt them. Lists and the API return names only, and there is no export. [Secure logins](/docs/cookie-sync)[Agent API](/docs/agent)[Browser API and MCP](/docs/mcp) YOUR NEXT RUN ## Run the example on a real site. Use Chrome for the page in front of you. Use Cloud when the run should continue on a schedule or across many pages. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Route Cloud through your own computer Some sites block cloud browsers. A Tailscale tunnel sends a Cloud run's traffic out through a computer you own, so sites see your home connection. It is free and uses no proxy credits. ## What you need - A computer that stays on and awake while runs use it. - [Tailscale](https://tailscale.com/download) installed on that computer and signed in. ## Set it up The easiest way is **Sign in with Tailscale**: no key to copy and no policy to edit. 1. **Turn on Run Exit Node.** On the computer, open Tailscale and turn on **Exit Node → Run Exit Node**. On Linux or a Raspberry Pi, turn on IP forwarding as [Tailscale's exit node guide](https://tailscale.com/kb/1103/exit-nodes) shows, then run `sudo tailscale set --advertise-exit-node`. 2. **Approve it as an exit node.** In the [Tailscale admin console](https://login.tailscale.com/admin/machines), open **Machines** → that computer → **Edit route settings** (or **Edit exit node**) → **Use as exit node**. 3. **Sign in from Cloud.** In [Cloud](/cloud), open **Routing** below the prompt → **Add a proxy or Tailscale tunnel** → **Tailscale**. Press **Sign in with Tailscale** and approve the rtrvr device in the window that opens. 4. **Pick it as your route.** If that computer is your only exit node online, rtrvr picks it and this chat goes out through it right away. Otherwise, pick the computer under **Routing → Tailscale tunnels**. To use it for every run, choose it as **Default proxy** in [Cloud Settings → Proxy Config](/cloud?view=settings) and save settings. You can also start from **Cloud Settings → Proxy Config → Add Proxy → Tailscale**. Added there, the tunnel becomes your default rather than one chat's route. If your tailnet holds new devices for approval, approve the rtrvr device under **Machines** too. ## What sites see - **Your IP and time zone.** Sites see the public IP of that computer's connection, and the cloud browser's time zone and language follow its location. - **Not your home network.** The cloud browser can't open your router, printers or other devices on your network or tailnet. Only public sites go through the tunnel. - **No WebRTC leak.** WebRTC stays in the tunnel, so it can't reveal the cloud server's address. Pair it with [Cookie Sync](/docs/cookie-sync) and the cloud browser arrives signed in to your sites, from your own IP. ## Good to know - **One run at a time.** A signed-in tunnel carries one run. A second run on it is refused until the first ends. For parallel runs, [use an OAuth client](#parallel-runs). - **If it cannot connect.** Retriever retries a temporary connection failure once. If it still cannot connect, your task stops before it starts. In Cloud, choose **Retry Tailscale**, **Use Retriever proxy** for this run, or **Cancel task**. The proxy uses a different IP and normal proxy charges apply. - **Speed follows your upload.** Pages travel through that computer's connection, so a slow upload means slower runs. - **Schedules keep the route.** The default is **Retry, then stop this run**. The next scheduled run still tries Tailscale. To allow fallback, choose **Use Retriever proxy** in the schedule. Allowing it for one task does not change your schedules. - **The sign-in expires with the device key.** The sign-in is kept encrypted and lasts until the rtrvr device's key expires (180 days by default) or you remove the device. To keep it, turn off key expiry for the rtrvr device in the Tailscale admin console. After it expires, edit the tunnel in Routing and sign in again. - **Remove it in both places.** Removing the tunnel in rtrvr does not remove the device from your tailnet. Also remove the `rtrvr-cloud-…` machine in the Tailscale admin console. ## Run several tasks at once (OAuth client) For runs in parallel, choose **OAuth client** instead of Sign in with Tailscale in the same dialog. The dialog walks you through these: - An approved exit node (steps 1 and 2 above). - A policy that lets `tag:rtrvr` reach `autogroup:internet`. The dialog has the entries to copy into Access controls. - An OAuth client with the **Auth Keys (write)** scope and the `tag:rtrvr` tag. Paste the client secret, press **Connect**, pick the exit node, and save. - The secret (or an auth key) goes to an encrypted vault, never to your settings, and is not shown again. - Each run joins your tailnet with a single-use key made from it and leaves when the run ends. ## Use it from the API and MCP A tunnel is a saved proxy. Your default route applies to API and MCP runs too. To pick a tunnel for one call, pass its exact name (case-sensitive) or ID: Pick a tunnel for one call ``` { "settings": { "proxyConfig": { "mode": "custom", "selectedProxyName": "My home computer" } } } ``` See [Use a saved proxy from MCP or the API](/docs/agent#cloud-proxies) for where `settings` goes in each call. ## Troubleshooting - **“Your exit node … is offline”:** Wake the computer, check that Tailscale is running and connected, then run again. - **“…carries one run at a time, and another run is using it now”:** Wait for that run to end, or set the tunnel up with an OAuth client to run several at once. - **“…is not offered as an exit node”:** Turn on Run Exit Node on the computer and approve it under Edit route settings. With an OAuth client, also allow `tag:rtrvr` to use `autogroup:internet`. - **“…is not in your tailnet any more”:** Pick the computer again under Routing → Tailscale tunnels. - **“The Tailscale sign-in for this tunnel has expired”:** Edit the tunnel under Routing and press Sign in with Tailscale again. - **“Tailscale rejected the saved key”:** Check that the OAuth client secret has the Auth Keys (write) scope, or create a new one, then connect again. - **“Tailscale refused the tag”:** Add `tag:rtrvr` to tagOwners in your tailnet policy and to the OAuth client's tags. Read [why we built Tailscale tunnels](/blog/tailscale-tunnels-home-ip). --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Shortcuts Save time by replaying successful automations: rerun, replay, or save as one-command shortcuts. # Workflows & Shortcuts Every successful task in rtrvr.ai can be reused. The system offers three levels of reuse, from quick iteration to permanent one-command shortcuts, so you never have to re-explain a task the agent already knows how to do. ## Quick Rerun Every user message in the chat history has a "Rerun" button. Clicking it opens a new chat thread and re-executes the prompt from scratch: the planner reconsiders the approach, which is useful when you want to iterate on phrasing or try a different strategy. ## Perfect Replay When a workflow works perfectly, click "Replay" on the agent's response. This skips the planning phase and runs the exact same steps instantly. Replay is deterministic: the agent follows the recorded action sequence without re-planning. This is the foundation for Shortcuts, Schedules, and Triggers. > **info**: Rerun = re-plan from scratch (AI may choose different steps). Replay = identical steps, no planning (deterministic). ## Creating Shortcuts Turn any successful task into a shortcut you can trigger with a simple "/" command. Shortcuts bundle the exact steps, recordings, and tab configuration that worked. - Find a successful task in your chat - Click the "/" Create Shortcut button on the agent's response - Give it a memorable name (e.g., "weekly-report", "leads", "price-check") - Type "/weekly-report" anytime to run it instantly ## Smart Tab Handling When creating shortcuts, choose how tabs are managed: | Mode | Behavior | Best For | | --- | --- | --- | | Open in New Tabs | Recreates the exact URLs from the original run | Always scraping the same specific sites | | Use Current Context | Applies the workflow logic to whatever tabs you have open | Repetitive tasks on different pages (e.g., extract data from any product page) | ## Combining Workflows Build powerful automations by chaining multiple shortcuts or merging different successful workflows into a single new shortcut. You can also chain them inline: ```text "First /login then /extract-data and /export-csv" ``` > **success**: Configure a single shortcut from multiple prior workflows for the ultimate one-command automation. ## Platform Availability | Capability | Extension | Cloud | API | | --- | --- | --- | --- | | Quick Rerun | ✅ | No | No | | Perfect Replay | ✅ | ✅ (replay_workflow) | ✅ (replay_workflow) | | "/" Shortcuts | ✅ | No | No | | Share workflow via URL | ✅ | ✅ | ✅ | | Import shared workflows | ✅ | ✅ | ✅ | --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Triggers Monitor tab notifications and fire workflows automatically, no API keys, no server setup, no site webhooks required. # Browser Triggers Browser triggers require a subscription. Try the underlying task in Free Mode before connecting it to a notification. [Compare plans](/pricing#plans). Most websites do not expose webhooks or APIs for real-time events. Browser Triggers solve this by monitoring your open tabs for web push notifications and executing workflows when matching notifications arrive. [Video: Browser Triggers from Tab Notifications](https://www.youtube.com/watch?v=ZRyyI8qffUI) > **success**: If a site can send browser notifications, you can trigger workflows from it. ## How Browser Triggers Work The extension injects an interceptor into monitored tabs that patches Notification and ServiceWorkerRegistration.showNotification. Notification title/body metadata is matched against your trigger filters, and matching events run the linked workflow automatically. - Intercept notifications from page and Service Worker paths - Match by hostname plus optional title/body contains filters - Run linked workflow in a new tab when a match is found - Store execution history with matched payload and status ## Creating a Browser Trigger - Run a workflow successfully in side panel chat - Click the "Trigger" button on the workflow response - Enter the URL to monitor (for example: x.com, app.slack.com) - Add optional title/body filters - Set cooldown to prevent rapid re-firing - Save to activate monitoring ## Notification Matching | Filter | Example | Matches | | --- | --- | --- | | Title contains | "new message" | Notifications with "new message" in title | | Body contains | "price drop" | Notifications with "price drop" in body | | Both | Title: "alert", Body: "urgent" | Only when both match | | None | No filter | All notifications from monitored hostname | > **info**: Matching is case-insensitive and uses simple contains logic. ## Cooldown Recommendations | Site Type | Recommended Cooldown | | --- | --- | | Chat apps (Slack, Discord) | 5-15 minutes | | Social apps (X, LinkedIn) | 15-30 minutes | | Price alerts | 30-60 minutes | | Daily digests | 1440 minutes (24 hours) | ## Monitored Tab Groups - Matching tabs are grouped into a yellow "Monitored" tab group - Closing a tab pauses monitoring for that tab - Reopening the URL resumes monitoring automatically ## Manual Testing Use the "Test" action in the Triggers dropdown to run the workflow immediately without waiting for a live notification. ## Limitations - Monitored tabs must stay open - Pure Service Worker push flows may not always be interceptable - Chrome must be running; for 24/7 inbound signals use /docs/webhooks ## Best Practices - Use specific filters to avoid false positives - Set cooldowns for chatty sources to manage credit burn - Validate every trigger with Test before production usage --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Webhooks Trigger workflows from external systems and receive async completion callbacks with signatures and retries. # Webhooks Webhook-triggered tasks and API runs need a paid plan and use credits for the resources they consume, and so does running rtrvr's agent in your Chrome through API or MCP. Receiving a completion callback does not make an API run part of Free Mode. [See plan and usage details](/pricing#free-mode). Webhooks let external systems trigger rtrvr workflows via HTTP POST and let rtrvr send completion/failure callbacks back to your infrastructure. Use this for Zapier, Make, n8n, backend jobs, and server-to-server pipelines. [Video: n8n + Extension Integration](https://www.youtube.com/watch?v=pcPRZsBs2aQ) [Video: Cloud Browser API from n8n](https://www.youtube.com/watch?v=FOmwVh1tJw0) > **info**: Need browser push-notification based automation instead? See /docs/triggers. ## Platform Compatibility | Platform | HTTP Timeout | Compatibility | Recommended Approach | | --- | --- | --- | --- | | n8n | 100s (Cloud) | Excellent | Direct calls work for most tasks | | Make.com | Up to 300s | Excellent | Set timeout to 120s+ | | Zapier | 30s fixed | Use callbacks | Provide webhookUrl for async results | ## Inbound Webhooks (Zapier, Make, n8n → rtrvr) Any service that can send an HTTP POST can trigger rtrvr.ai workflows. Use the MCP endpoint to control your logged-in browser, or the /agent endpoint for cloud browser execution. For a fixed task, the Cloud dashboard's Triggers panel (Cloud → Triggers) mints a per-trigger URL (`POST https://mcp.rtrvr.ai/v1/webhooks/trigger/{id}`, Bearer API key) whose target is a saved tool, a past cloud run, or a prompt stored on the trigger: a prompt trigger runs that prompt on every POST and appends the body's optional `input` to it. Every endpoint here, trigger URLs included, takes your API key as `Authorization: Bearer rtrvr_…`, as the bare key (`Authorization: rtrvr_…`), or in an `x-api-key` header. In n8n, Make or Zapier "Header Auth" credentials, set Name to `Authorization` and Value to your key (the `Bearer` prefix is optional), or set Name to `x-api-key`. ### MCP Endpoint (Your Browser) ```text POST https://mcp.rtrvr.ai Headers: Authorization: Bearer rtrvr_your_api_key Content-Type: application/json Body: { "tool": "planner" | "extract" | "act" | "crawl" | "replay_workflow" | ..., "params": { ... tool-specific parameters ... }, "deviceId": "optional_device_id", "webhookUrl": "https://your-server.com/callback" // optional: receive results } ``` ### Agent Endpoint (Cloud Browser) ```bash POST https://api.rtrvr.ai/agent Headers: Authorization: Bearer YOUR_API_KEY Content-Type: application/json Body: { "input": "Extract company info and contact details", "urls": ["https://example.com"], "webhookUrl": "https://your-server.com/callback", "response": { "verbosity": "final" } } ``` ### n8n Integration n8n Cloud has a 100-second timeout: comfortably above most rtrvr task durations. Use either endpoint depending on whether you need your logged-in browser or a cloud browser. ```json // n8n → MCP (your logged-in browser) { "method": "POST", "url": "https://mcp.rtrvr.ai", "body": { "tool": "planner", "params": { "user_input": "{{ $json.task_description }}", "tab_urls": ["{{ $json.target_url }}"] }, "webhookUrl": "{{ $node.Webhook.url }}" } } // n8n → /agent (cloud browser) { "method": "POST", "url": "https://api.rtrvr.ai/agent", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Authorization", "value": "Bearer {{ $credentials.rtrvrApiKey }}" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "bodyParameters": { "parameters": [ { "name": "input", "value": "={{ $json.taskDescription }}" }, { "name": "urls", "value": "={{ [$json.targetUrl] }}" } ] } } ``` ### Make (Integromat) Integration > **warning**: Make's default timeout is 30 seconds. Click "Show advanced settings" and set Timeout to 120 seconds for reliable results. - Add an "HTTP > Make a request" module - URL: https://mcp.rtrvr.ai | Method: POST - Headers: Authorization (Bearer token), Content-Type (application/json) - Body type: Raw, Content type: JSON - Request content: Your tool + params JSON ### Zapier Integration Zapier has a fixed 30-second HTTP timeout. Use the webhook pattern: Zap 1 triggers rtrvr with a webhookUrl pointing to a Catch Hook in Zap 2, which receives and processes the results. - Add a "Webhooks by Zapier" action to your Zap - Select "POST" as the method - Set URL to: https://mcp.rtrvr.ai - Add headers: Authorization = Bearer rtrvr_your_api_key, Content-Type = application/json - Set Data to your JSON payload (tool + params) - Set webhookUrl to a Catch Hook URL in a second Zap ```json // Example: Extract data when a new row is added to Google Sheets { "tool": "extract", "params": { "user_input": "Extract the company name, employee count, and funding info", "tab_urls": ["{{Google Sheets Row URL}}"] }, "webhookUrl": "https://hooks.zapier.com/hooks/catch/123/abc/" } ``` ### Available Tools | Tool | Use Case | Execution | | --- | --- | --- | | agent | End-to-end task from one prompt; your signed-in Chrome when connected, else a cloud browser (target overrides) | Local or cloud browser | | scrape | Read pages (text + accessibility tree); same routing as agent | Local or cloud browser | | planner | Complex multi-step tasks from natural language | Local or cloud browser | | extract | Structured data extraction with optional schema | Local or cloud browser | | act | Page interactions (click, type, navigate) | Local or cloud browser | | crawl | Multi-page crawling with extraction | Local or cloud browser | | replay_workflow | Re-run a previous workflow by ID or URL | Local or cloud browser | | get_browser_tabs | List open tabs | Local browser only | | user_ | Run one of your saved tools (subroutines, custom JavaScript tools) with its parameters; your signed-in Chrome when connected, else a cloud browser | Local or cloud browser | Saved tools no longer need your Chrome open. A `user_` call (REST `tool`, or the MCP tool of the same name) runs on your extension when a device is connected and falls back to a cloud browser otherwise; pass `target: "cloud"` to force the cloud browser or `target: "device"` to keep the old behaviour (a 503 when nothing is connected). Cloud runs open the tool's page with its stored website session, bill browser time and inference like an `agent` run (`creditsUsed` is in the response), and answer `202 accepted` with a `trajectoryId` when the tool is still running after ~25 seconds: add a `webhookUrl` to receive the result, or read it from Cloud executions. Cloud execution needs an API key with the cloud agent capability. ## Outbound Webhooks (rtrvr → Your Server) Include a webhookUrl in any API request to receive results when the workflow completes. rtrvr.ai will POST the full response to your endpoint. ### Enabling Outbound Webhooks ```bash curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_xxx" \ -H "Content-Type: application/json" \ -d '{ "tool": "planner", "params": { "user_input": "Find pricing for iPhone 16 Pro on Apple.com", "tab_urls": ["https://apple.com"] }, "webhookUrl": "https://your-server.com/rtrvr-callback", "webhookSecret": "your_hmac_secret" }' ``` ## Webhook Payloads ### Success Payload ```json { "event": "workflow.completed", "timestamp": "2025-01-15T12:00:00.000Z", "requestId": "req_abc123xyz", "success": true, "data": { "taskCompleted": true, "output": { ... }, "extractedData": [ ... ], "creditsUsed": 5 }, "metadata": { "tool": "planner", "deviceId": "dj75mmaTWP0", "executionTime": 15234, "creditsRemaining": 9995 }, "originalRequest": { "tool": "planner", "params": { ... } } } ``` ### Error Payload ```json { "event": "workflow.failed", "timestamp": "2025-01-15T12:00:00.000Z", "requestId": "req_abc123xyz", "success": false, "error": { "message": "Device offline: no available browser extensions", "code": "DEVICE_UNAVAILABLE", "details": { ... } }, "metadata": { "tool": "planner", "executionTime": 1234 } } ``` ## Verifying Webhook Signatures If you provide a webhookSecret, rtrvr.ai signs the payload with HMAC-SHA256. Verify it to ensure authenticity: ```typescript // Express.js import crypto from 'crypto'; app.post('/rtrvr-callback', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.headers['x-rtrvr-signature'] as string; const timestamp = req.headers['x-rtrvr-timestamp'] as string; // Reject stale timestamps (> 5 minutes) if (Date.now() - parseInt(timestamp) > 300000) { return res.status(400).json({ error: 'Timestamp too old' }); } const payload = timestamp + '.' + req.body.toString(); const expected = crypto .createHmac('sha256', process.env.RTRVR_WEBHOOK_SECRET!) .update(payload) .digest('hex'); if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) { return res.status(401).json({ error: 'Invalid signature' }); } const data = JSON.parse(req.body.toString()); // Process asynchronously — respond 200 immediately res.status(200).json({ received: true }); processWebhook(data); }); ``` ```python # Flask import hmac, hashlib, time, os from flask import Flask, request, jsonify WEBHOOK_SECRET = os.environ['RTRVR_WEBHOOK_SECRET'] @app.route('/rtrvr-callback', methods=['POST']) def handle_webhook(): signature = request.headers.get('X-Rtrvr-Signature') timestamp = request.headers.get('X-Rtrvr-Timestamp') if abs(time.time() * 1000 - int(timestamp)) > 300000: return jsonify({'error': 'Timestamp too old'}), 400 payload = f"{timestamp}.{request.data.decode()}" expected = hmac.new(WEBHOOK_SECRET.encode(), payload.encode(), hashlib.sha256).hexdigest() if not hmac.compare_digest(signature, expected): return jsonify({'error': 'Invalid signature'}), 401 data = request.json return jsonify({'received': True}) # Process async ``` ## Retry Behavior Failed deliveries are retried with exponential backoff: - Attempt 1: Immediate - Attempt 2: After 5 seconds - Attempt 3: After 30 seconds - Attempt 4: After 2 minutes - Attempt 5: After 10 minutes (final) > **warning**: Respond with 200 OK immediately. Process webhook payloads asynchronously to avoid timeouts. ## Common Patterns ### Lead Enrichment Pipeline New lead in CRM → rtrvr extracts company data → webhook returns enriched info → update CRM record. ```json // Trigger: New HubSpot contact // Action: POST to https://api.rtrvr.ai/agent { "input": "Visit this company website and extract: company size, industry, tech stack, and key contacts", "urls": ["{{contact.company_website}}"], "webhookUrl": "https://hooks.zapier.com/catch/123/enrich/", "response": { "verbosity": "final" } } // Webhook receives enriched data → Update CRM ``` ### Browser Trigger → Sheet Log (Zero Server) The simplest pattern: monitor a site for notifications and log events to Google Sheets. No server, no API, no webhook endpoint needed. - Create a workflow that extracts data from the site and appends to a Google Sheet - Set up a Browser Trigger on that site with appropriate filters - Configure sheet output to "Append to same sheet on each run" - Every matching notification adds a row: building a running log automatically ### Scheduled Price Monitoring Cron schedule → rtrvr checks competitor prices → compare with previous data → alert if changed. ```json // Schedule: Daily at 9am via n8n Cron node // Action: POST to https://api.rtrvr.ai/scrape { "urls": [ "https://competitor1.com/pricing", "https://competitor2.com/pricing" ] } // Compare extracted prices with yesterday's data // If changed → Send Slack/email notification ``` ### Browser Trigger + Outbound Webhook (Hybrid) ```text Flow: 1. Browser Trigger monitors slack.com for "deployment failed" notifications 2. Trigger fires → workflow extracts error details from the Slack thread 3. Workflow calls your server via rtrvr.ai API with webhookUrl set 4. Server receives error details → creates a Jira ticket automatically Result: Slack notification → browser extraction → server-side ticket creation No Slack API required: the browser does the heavy lifting ``` ### Authenticated Data Sync (MCP) Your app triggers → rtrvr uses your logged-in browser via MCP → data synced to your database. ```json // Trigger: Webhook from your application // Action: POST to https://mcp.rtrvr.ai { "tool": "extract", "params": { "user_input": "Export my order history from the last 30 days", "tab_urls": ["https://vendor-portal.com/orders"] }, "webhookUrl": "https://your-app.com/api/orders/sync" } // Your browser navigates using your login session // Results sent to webhook → stored in database ``` ### Zapier → rtrvr → Zapier (Round-trip) - Zap 1: New Google Form submission → POST to mcp.rtrvr.ai (include webhookUrl pointing to Zap 2) - Zap 2: Catch Hook receives results → Add row to Google Sheets ### Slack Command → rtrvr → Slack Message ```typescript app.post('/slack/commands', async (req, res) => { const { text, response_url } = req.body; res.status(200).json({ text: '🔄 Running extraction...' }); // Ack < 3s await fetch('https://mcp.rtrvr.ai', { method: 'POST', headers: { 'Authorization': 'Bearer rtrvr_xxx', 'Content-Type': 'application/json' }, body: JSON.stringify({ tool: 'extract', params: { user_input: text, tab_urls: [extractUrlFromText(text)] }, webhookUrl: 'https://your-server.com/slack-callback', webhookMetadata: { response_url }, }), }); }); app.post('/slack-callback', async (req, res) => { const { data, originalRequest } = req.body; const { response_url } = originalRequest.webhookMetadata; await fetch(response_url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: `✅ Extracted: ${JSON.stringify(data.extractedData, null, 2)}`, }), }); res.status(200).json({ received: true }); }); ``` ## Choosing the Right Approach | Approach | Trigger Signal | Best For | Availability | | --- | --- | --- | --- | | Browser Triggers | Push notification in a tab | Sites without APIs: social media, chat, SaaS dashboards | While Chrome is open | | Schedules | Cron / interval timer | Periodic collection, monitoring, recurring reports | Chrome or 24/7 cloud | | Inbound Webhooks | HTTP POST from external service | Zapier / Make / n8n, CI/CD, server-to-server | 24/7 cloud | > **success**: All three approaches can output to Google Sheets, call custom tools, chain multi-step workflows, and include recordings for grounding. Mix and match. ## Best Practices - Verify signatures on every callback in production - Implement idempotency to handle retries safely - Use HTTPS-only endpoints - Pass webhookMetadata for correlation IDs and routing context --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Schedules Automated task scheduling: run workflows on a timer from your Chrome browser or 24/7 from the cloud. # Schedules The free plan includes one schedule that runs once a day or less often, in the Cloud or in your Chrome; its runs use your daily Free Mode allowance, and its result shows a sponsored card. More schedules and faster schedules need a subscription. On a paid plan a scheduled run uses the daily Free Mode allowance first (AI, and in the Cloud its browser and proxy time too), then your credits once the allowance is used up. It has no ad break, and its result shows a sponsored card. Free Mode runs the value models, so a schedule set to a premium model uses credits only, with no ads. To run any schedule on credits only, with no ads, say so when you create or edit it ("use my credits for this schedule"), pick Credits only under Billing in the schedule's editor, or pass free_mode false to the MCP schedule tool. First try the task as a one-time interactive run, then schedule the version you have checked. [Compare plans](/pricing#plans). [Video: Schedules Overview](https://www.youtube.com/watch?v=EWnxfLbTm1g) Turn any successful workflow into a scheduled task that runs on autopilot. Schedule from the Chrome Extension for local execution using your logged-in sessions, or export to Cloud for 24/7 headless operation. Perfect for price tracking, inventory monitoring, job board scraping, news aggregation, and competitive analysis. ## Creating a Schedule - Run a task successfully in the chat - Click "Schedule" on the agent's response - Set a title and choose frequency: once, hourly, daily, weekly, or custom cron - Pick your start time and configure advanced options - Save: your schedule is now active > **info**: Click the ⓘ button in the Schedule Settings header for quick inline help anytime. ## Browser Execution (Chrome Extension) Scheduled tasks run in your Chrome browser using your existing logged-in sessions, no re-authentication required. Tasks execute while your browser is open. If a scheduled run is missed (browser closed), it runs automatically when Chrome reopens. ```text Schedule set for 9 AM → Browser closed overnight → Opens at 10 AM → Task runs immediately ``` ### Smart Tab Reuse Configure schedules to reuse matching open tabs instead of opening new ones. This can reduce sign-in churn on authenticated sites where the session is still valid. - In Schedule Config, find "Tab Execution Mode" - Select "Reuse matching open tabs when possible" - Keep your target site open in a tab - The agent uses your existing logged-in session > **success**: Tab reuse is especially powerful for walled gardens like LinkedIn, Zillow, and Discord where fresh tabs often trigger CAPTCHA or login walls. ### Where Runs Start A schedule made from a text request (by the agent, or with the MCP `schedule` tool) has no recorded tabs. Each of its runs starts in its own background tab, so it never takes over the page you're working on. To run on whichever tab is active when the schedule fires instead, open Cloud → Schedules → Extension → Edit schedule and set **Where runs start** to "My active tab when it runs" (over MCP: `tab_selection: "active_tab"`). Schedules with recorded tabs keep each step's Tab Execution Mode. Needs extension 37.9.5 or later. ### Auto-Append to Sheets Build a master tracking sheet that grows over time. Configure your schedule to append new data as rows to the same Google Sheet instead of creating a new sheet each run. - In Schedule Config, expand the workflow step - Find "Sheet Output Configuration" - Select "Append to same sheet on each run" - Each scheduled run adds new rows to your master sheet ```text Daily job scrape → New listings append as rows → One sheet tracks all jobs over time ``` ### Multi-Step Workflows Chain multiple workflows together in a single schedule. Each step can have its own tab handling and sheet configuration. Steps can pass context using "Reuse tabs from previous step." ```text Step 1: Scrape job listings → Step 2: Analyze fit with resume → Step 3: Export to tracking sheet ``` ## Cloud Scheduling (24/7) Cloud schedules run on rtrvr.ai's headless cloud browsers, so they keep going when your laptop is closed. They live in the Cloud dashboard (Cloud → Schedules), repeat every N minutes (5 or more), hours or days (or run once), can write into the same Google Sheet, Doc or Slides deck on every run, and can notify you when a run finishes. ### Save scheduled results to Google Sheets - Connect Google Drive in [Cloud Connectors](/docs/connectors#connect-google-drive), using an account that can edit the spreadsheet. Cloud refreshes its saved Google authorization automatically; Chrome can stay closed. - In the schedule's **Options** tab, open **Update existing files** and choose **Use these files** if writing the results is required, then enable Google Sheets. Click **Choose from Google Drive** and pick the spreadsheet to grant access to the file. Pasting an ID or URL identifies a file but does not grant access. - Choose **Write to an existing tab**, then select the actual tab from the list. The saved tab ID survives a rename, including a tab whose gid is 0. If you want a custom name that does not exist, create it in Google Sheets first. - For separate outputs, choose **Create a new tab for each run**. The optional prefix can contain up to 70 characters, excluding `[ ] : * ? /` and backslash. The tab is created when the run writes data. - The editor checks file access, edit permission, and available tabs without running the workflow or spending workflow credits. The schedule checks its destination again before starting each run. Use **Check again** after correcting access. Use the tab's real name in any language. A missing/default Sheet1 name can resolve to the only tab, and a unique case-insensitive match can resolve to the actual title. Multiple possible tabs or a missing custom name require a selection. rtrvr does not redirect a named destination to an unrelated tab. With **Force**, extracted data alone does not complete delivery. Cloud requires a confirmed Google Sheets data write. If it cannot confirm one, it retains the output and reports partial completion, including when the result has zero rows. Extracted strings use RAW writes to preserve dates, decimal strings, leading zeros, and text in any language. ### When a scheduled Sheet stays empty - Open **Run History** and inspect the run's error and retained output before starting another paid run. A destination preflight failure stops before the workflow starts and uses no workflow credits. - If Drive is connected but the file is inaccessible, select it through the picker and check the connected Google account's edit permission. Reconnect when the error says the Google authorization cannot be refreshed. - If the tab is missing, select an existing tab or create the intended tab in Google Sheets. Do not replace a specific destination with Sheet1 just to bypass the error. - A tool that only writes Sheets should use sandbox mode and the built-in Sheets helpers. Remove or repair a broken tool in the saved **Tools** inventory. Removing it from one workflow does not remove the saved tool from other runs. - If the outcome of an append is uncertain, inspect the Sheet before rerunning. The runtime deduplicates identical forced appends within a running request; a new run or a process restart does not provide an exactly-once guarantee. ### Creating a Cloud Schedule - **From the dashboard:** open Cloud → Schedules, click **New schedule**, then choose a **Task** and its **Timing**. Under **Options**, you can update existing files and send notifications. Switch to **My browsers** to manage tasks that run through the Retriever extension. - **From a cloud chat:** ask the cloud agent to repeat the task, e.g. "check these prices every morning". The agent schedules the run it is working on (its `rtrvr.schedule` step). The schedule is created only if that run succeeds, then replays the run at the frequency you asked for. It appears in Cloud → Schedules under the name the agent gave it. A cloud schedule runs one of three targets, chosen on the **Task** tab of the schedule editor (Cloud → Schedules): a **Saved task** (repeat a completed cloud run, the default), a **New task** (up to 4,000 characters, with up to 20 optional start URLs), or **tools** (1–10 of your saved custom/MCP tools, run in order with the parameters you fill in). The dashboard sends that choice to the createSchedule / updateSchedule callables as a `target` object; a request with only `sourceExecutionId` still means the execution kind. Those callables need a signed-in rtrvr.ai session, not an API key. There is no REST endpoint for creating or changing schedules. ```json // target: prompt { "name": "Daily price check", "target": { "kind": "prompt", "userInput": "Open each competitor's pricing page and summarize what changed since the last run", "urls": ["https://example.com/pricing"] }, "frequency": { "unit": "days", "every": 1 }, "timeZone": "America/New_York" } // target: tools (ordered saved-tool steps) { "name": "Sync leads to Slack", "target": { "kind": "tools", "steps": [ { "toolName": "fetchNewLeads", "parameters": { "since": "24h" } }, { "toolName": "postLeadsToSlack" } ] }, "frequency": { "unit": "hours", "every": 6 } } // target: execution (replay a completed cloud run) { "target": { "kind": "execution", "sourceExecutionId": "exec_123" } } ``` ### Frequency A cloud schedule repeats at a fixed interval from its start time, in the schedule's time zone (an IANA name such as `America/New_York`; UTC by default). Cloud schedules do not take cron expressions: the start time sets the time of day, and the interval sets how often it repeats. The shortest interval is 5 minutes, because each run starts a cloud browser and uses credits: a faster frequency is refused, and the dashboard raises a shorter custom value to 5 minutes. | Dashboard option | Frequency | | --- | --- | | Every 15 minutes | `{ "unit": "minutes", "every": 15 }` | | Every 6 hours | `{ "unit": "hours", "every": 6 }` | | Daily | `{ "unit": "days", "every": 1 }`, at the start time | | Weekly | `{ "unit": "days", "every": 7 }`, on the start day | | One-time | `{ "unit": "once" }`, at the start time (right away if that time has passed) | ### Notifications The Notifications tab sends every finished run, successful or not, to email, Slack, Discord, a WhatsApp number linked to your account, or your own webhook. The webhook gets the same payload as an `/agent` completion callback, signed if you set a secret. See [Webhooks](/docs/webhooks). ### Extension schedule delivery & alerts Extension schedules can deliver each run too. When a run finishes, the extension hands it to rtrvr.ai, which sends it to the schedule's channels (webhook, WhatsApp, email, Slack or Discord), trying each one up to 3 times. Set it up from **Delivery & alerts** (the bell on the schedule in the side panel or in Cloud → Schedules → Extension), or just ask in chat: "check prices every morning and WhatsApp me the results", "send my daily digest to https://… with no notifications". - **Chrome notification on this computer:** *Every run*, *Only if something fails*, or *Never*. Once any channel is on it defaults to *Only if something fails*: the notification appears only when the run fails or a delivery still fails after 3 tries. Either way, new runs show as a count on the Schedules button in the side panel until you open it. - **Webhooks must be public `https://` URLs**, because delivery goes out from rtrvr.ai. For a local n8n or server, expose it with `n8n start --tunnel` or ngrok and use that URL. - **Payload:** the same envelope as a cloud schedule's webhook (`rtrvr.execution.succeeded` / `rtrvr.execution.failed`), plus `data.schedule` (`id`, `title`, `runId`, `deviceId`, `source: "extension"`) and a one-line `data.summary`. With a secret set, requests carry `X-Rtrvr-Signature: t=,v1=`. - **Send test** in the settings posts a sample run to every channel that is on, so you can check your receiver before the next run. - Needs extension 37.9.1 or later. If the computer can't reach rtrvr.ai after a run, it shows the notification instead (unless notifications are set to *Never*). ## Schedule Management Manage extension schedules from the Schedules dropdown in the extension side panel. Manage cloud schedules in Cloud → Schedules: each card can be edited, paused or resumed, run now, or deleted, and its menu can skip the next run, cancel a run in progress, open the last run, or show the Run History. You can also ask the agent in the side panel to change a saved extension schedule, for example "run my price check every 2 hours" or "change its task to also check shipping costs". It edits that schedule in place instead of creating a second one, and it can pause, resume, rename or delete a schedule the same way. > **warning**: Schedules have no endpoint of their own; with an API key they are managed through the MCP tools (over MCP, or the same tools over REST). `schedule` edits, pauses and resumes your cloud schedules and creates or edits extension schedules; `list` and `check_results` list your cloud and extension schedules and read their recent runs; a prompt trigger starts a schedule's prompt (all covered below). Creating, deleting and running a cloud schedule stay in the dashboard; you can also create one from a cloud chat. ### Edit a Cloud Schedule over MCP - Find the schedule with `list` and `kind: "schedules"` (cloud items have `source: "cloud"` and an `id`), then call `schedule` with `schedule_id` set to that `id`. It is edited on rtrvr.ai: no browser or `device_id` is needed, the same schedule is changed in place, and nothing new is created. Add `source: "cloud"` to make sure the call never reaches an extension schedule; an ID that is not one of your cloud schedules is then refused. - An edit can set `frequency` (`{ "unit": "minutes" | "hours" | "days" | "once", "every": n }`, as the dashboard stores it) or `period_in_minutes` (60 is stored as hourly, 1440 as daily), `time_zone` (an IANA name such as `"Europe/London"`), `start_at` (the dashboard's **Run at**, ISO 8601), `name`, `notifications` (only the channels you name change: `email: true` or an address, `whatsapp: true`, a Slack, Discord or webhook URL, or `false` to turn one off), and `user_input` (the complete new task text; prompt schedules only). - `enabled: false` pauses the schedule and `enabled: true` resumes it (resuming needs a paid plan, or on the free plan a daily schedule with no other one active). Without `enabled` the status stays as it is: editing a paused schedule leaves it paused, and no edit starts a run. - The validation is the dashboard's: a cadence under 5 minutes is refused, and a dashboard change that lands while the call is being applied is refused rather than overwritten. Restating a value that has not changed leaves the next run where it was. When the time zone changes, the run keeps its clock time in the new zone. - The reply lists each change (`before` → `after`) with the schedule's `status`, `frequency`, `timeZone` and `nextRunAt`. Over REST a refusal answers 400, 402 (a paid plan is needed to resume), 404 (no such cloud schedule) or 409, and says what was applied before it, if anything. ```json // schedule tool arguments: make a cloud schedule run hourly (a paused one stays paused) { "schedule_id": "YOUR_CLOUD_SCHEDULE_ID", "source": "cloud", "frequency": { "unit": "hours", "every": 1 } } // Resume it (send "enabled": false to pause) { "schedule_id": "YOUR_CLOUD_SCHEDULE_ID", "source": "cloud", "enabled": true } // The reply (shortened) { "success": true, "source": "cloud", "scheduleId": "YOUR_CLOUD_SCHEDULE_ID", "changes": [{ "field": "frequency", "before": "every 5 minutes", "after": "every hour" }], "status": "paused", "frequency": "every hour", "timeZone": "Europe/London", "nextRunAt": null, "runStarted": false } ``` ### Create or Edit an Extension Schedule over MCP - Without `schedule_id`, every call to the MCP `schedule` tool creates a new extension schedule on a connected device, even when the text says "update" or names an existing schedule. - To change a saved schedule, find it with `list` and `kind: "schedules"` (extension items carry `scheduleId` and `deviceId`), then call `schedule` with `schedule_id` and `device_id`. The same schedule is rewritten and nothing new is created; an unknown ID fails. - An edit can set `user_input` (the complete new task text, stored as written), `period_in_minutes` (the new cadence), `enabled` (`false` pauses, `true` resumes), `tab_selection` (`"new_tab"` or `"active_tab"`), and `step` (which step's task text to replace in a multi-step schedule). - Editing needs extension 37.9.5 or later on that device. ```json // schedule tool arguments: new task text and cadence for a saved schedule { "schedule_id": "YOUR_SCHEDULE_ID", "device_id": "YOUR_DEVICE_ID", "user_input": "Open the three competitor pricing pages and list every price that changed since the last run", "period_in_minutes": 120 } // Pause it (send "enabled": true to resume) { "schedule_id": "YOUR_SCHEDULE_ID", "device_id": "YOUR_DEVICE_ID", "enabled": false } ``` ### Run a Cloud Schedule Now **Run Now** in a schedule card's menu starts a one-off run of the schedule's target a few seconds later, without moving the next scheduled time. If a run of that schedule is still going and its Concurrency Policy isn't **Allow overlap**, the manual run is recorded as skipped. **Force Run Now** starts it anyway. Manual runs show in the Run History next to scheduled ones. ## Reading Results - **Cloud schedules:** **Run History** in the schedule card's menu lists each run's status, duration, credits used, summary and error, with a link to the full run. To have results sent to you instead, turn on a notification channel. - **If Tailscale cannot connect:** Under **Timing > Connection & overlapping runs**, the default is **Retry, then skip**. Retriever retries a temporary connection failure once, then ends that occurrence if it is still unavailable. The next scheduled run keeps the same route. On a paid plan, choose **Use Retriever proxy** to allow fallback to a different IP at normal proxy rates. Allowing fallback for a single task does not change this schedule. - **From a cloud chat:** ask the agent, e.g. "what did my price check find this week?". It reads your cloud schedules and their recent runs. - **Over MCP / REST (API key):** `list` with `kind: "schedules"` returns your cloud schedules and the schedules your extension devices have synced to rtrvr.ai. Each item has `source: "cloud"` or `source: "extension"`. Cloud items include `id`, `name`, `status`, `frequency`, `nextRunAt`, `lastRunAt` and `lastRunStatus`. Extension items include `scheduleId`, `deviceId`, `title`, `enabled` and `lastRunAt`. - `check_results` with `kind: "schedules"` answers a question about those schedules' recent runs. It also returns them as `schedules`. Each cloud entry lists its recent `runs`, with `status`, `scheduledFor`, `startedAt`, `finishedAt`, `summary`, `errorMessage`, `creditsUsed` and `executionId`. Both tools work while Chrome is closed. - **Narrowing:** `id` picks one schedule: a cloud schedule's ID or name, or an extension schedule's title (a name only has to contain the text). `limit` sets how many recent runs to read per schedule (default 10, up to 100 for cloud schedules). `source: "cloud"` or `source: "extension"` reads only one kind. `device_id` narrows extension schedules only. ```bash curl -X POST "https://mcp.rtrvr.ai" \ -H "Authorization: Bearer rtrvr_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "tool": "check_results", "params": { "kind": "schedules", "source": "cloud", "id": "Daily price check", "user_input": "Which prices changed since yesterday?", "limit": 5 } }' ``` The response (shortened): ```json { "success": true, "kind": "schedules", "query": "Which prices changed since yesterday?", "answer": "Daily price check (cloud): 2 prices changed since yesterday...", "itemsConsidered": 1, "schedules": [ { "source": "cloud", "id": "8Xk2...", "name": "Daily price check", "status": "active", "frequency": { "unit": "days", "every": 1 }, "nextRunAt": "2026-09-18T15:00:00.000Z", "lastRunStatus": "success", "runs": [ { "runId": "8Xk2..._1789657200000", "status": "success", "scheduledFor": "2026-09-17T15:00:00.000Z", "startedAt": "2026-09-17T15:00:04.000Z", "finishedAt": "2026-09-17T15:02:10.000Z", "summary": "2 of 14 prices changed...", "errorMessage": null, "creditsUsed": 12, "executionId": "8Xk2..._1789657200000" } ] } ] } ``` > **info**: A run's fields are what Run History shows: status, times, credits, summary and error. They don't include the run's full output; for that, open the run from Run History or turn on a webhook notification. When `check_results` finds schedules, a model writes `answer`, which uses credits. The retired `list_schedules` and `check_schedule_results` names still work, but they only read extension schedules. ## Start a Scheduled Prompt from Another System A schedule can't be called over HTTP, but its prompt can. Create a prompt trigger with the same text, and Zapier, Make, n8n, a CRM or your own backend can run that prompt whenever it needs to, separately from the schedule's own timing. - Open Cloud → Triggers and click **New Trigger** - In the target list choose **Write a prompt…**, paste the prompt your schedule runs, and add its start URLs if it has any - Optionally set a result webhook URL, then click **Create Trigger** and copy the trigger URL from the table - POST to that URL with an API key that has cloud agent access ```bash curl -X POST "https://mcp.rtrvr.ai/v1/webhooks/trigger/YOUR_TRIGGER_ID" \ -H "Authorization: Bearer rtrvr_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "input": "Only report products whose price changed by more than 5%", "webhookUrl": "https://your-app.com/rtrvr/price-check" }' ``` - The stored prompt always runs as written. `input` is optional; it is added after the prompt as extra instructions and never replaces it. - `urls` (optional) replaces the trigger's stored start URLs for that call. - `webhookUrl` (HTTPS only) receives the run's result when it finishes; add `webhookSecret` to have the payload signed. Without a `webhookUrl`, the result webhook saved on the trigger is used, if there is one. - If the run finishes within about 25 seconds, the response contains its result (HTTP 200). Otherwise the call returns HTTP 202 with a `trajectoryId`. The run keeps going, and its result goes to the webhook and shows in your Cloud executions. - Errors: 403 when the API key has no cloud agent access, 404 when the trigger does not belong to the key's account, 400 for a non-HTTPS webhook URL. ```json // HTTP 202: the run is still going { "success": true, "status": "accepted", "trigger": { "id": "YOUR_TRIGGER_ID", "name": "Price check", "targetType": "prompt", "toolName": null, "taskId": null, "promptPreview": "Open each competitor's pricing page and summarize what changed since the last run" }, "trajectoryId": "5f0c1c9e-2b7a-4d4e-9a57-0c3f2b8d1e44", "message": "The cloud run started and is still executing. ...", "requestId": "...", "timestamp": "2026-09-16T09:00:04.512Z" } ``` > **info**: Trigger runs are separate from the schedule. They don't appear in its Run History or change its next run time, and editing the schedule's prompt doesn't update the trigger, so change both. See [Webhooks](/docs/webhooks) for the full trigger reference and callback signatures. ## Error Handling - Every cloud run's outcome (success, error, timed out, cancelled or skipped) and its error message are kept in the schedule's Run History - If a schedule's target can no longer run (for example, its saved tool was deleted), that run is recorded as an error and the schedule pauses with the reason on its card. Fix the target, then resume. - Notifications fire for failed runs too, so a broken schedule reports on the same channel as a working one - When a run is due while the previous one is still going, the schedule's Concurrency Policy decides: **Queue latest** (the default) runs only the latest missed occurrence once the current run ends, **Skip if running** drops it, and **Allow overlap** runs both > **info**: Scheduled runs stop at the [credit ceiling](/docs/web-agent#credit-ceiling-per-task) rather than pausing to ask. An attended run parks and waits for your answer, but nobody is watching a cron run, so it finalizes with the work it has done and reports it through the normal cancelled webhook. If a schedule regularly does more work than the ceiling allows, raise it in [Settings → Storage & Execution](/cloud?view=settings§ion=storage) or per-run with `options.limits.creditCeiling`. ## Best Practices - Test schedules with a one-time execution before enabling recurring runs - Use tab reuse for authenticated sites to avoid login walls - Use sheet append mode to build historical datasets over time - Set appropriate intervals: don't overwhelm target sites - Use webhooks for real-time notifications on completion - Check a schedule's Run History regularly to catch failures and slow runs early - Consider timezone differences for global operations ## Platform Availability | Capability | Extension | Cloud | API key (REST / MCP) | | --- | --- | --- | --- | | Create schedules from chat | ✅ | ✅ | MCP `schedule` tool (extension schedule on a connected device) | | Edit, pause, resume, delete | ✅ side panel, or ask the agent | ✅ dashboard | MCP `schedule` with `schedule_id` edits, pauses or resumes a cloud schedule, or an extension schedule (extension 37.9.5+); deleting stays in the dashboard or side panel | | Run on demand | No | ✅ Run Now | A prompt trigger runs the same prompt (a separate run) | | Local browser execution | ✅ | No | No | | Smart tab reuse | ✅ | No | No | | 24/7 headless execution | No | ✅ | No | | Auto-append to sheets | ✅ | ✅ | No | | Multi-step workflows | ✅ | ✅ | No | | Email / Slack / Discord / WhatsApp / webhook notifications | ✅ sent via rtrvr.ai | ✅ | No | | Read results | ✅ side panel | ✅ Run History | `list` / `check_results` (cloud and extension schedules) | | Missed-run catch-up | ✅ | No | No | > **success**: Pro tip: Combine smart tab reuse + sheet append for the ultimate monitoring workflow on authenticated sites. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Secure logins Use your website accounts in cloud tasks. Save a password, sync from Chrome, or sign in once in Cloud. # Secure logins Open **Secure logins** in the [Cloud sidebar](/cloud?view=logins), or the lock icon in the Relay extension. This is where you add, update, and remove the website accounts your cloud tasks can use. ## Choose how to sign in | You want to… | Use | What happens | | --- | --- | --- | | Let Retriever sign in when a task needs it | **Add login** | Save the site's username or email and password. Retriever uses them on the site's sign-in page. | | Use an account already signed in to Chrome | **Sync from Chrome** | Copy that site's current sign-in to Cloud. Only sites you add are synced. | | Sign in yourself, including SSO or verification | **Take control** | Use the site's own sign-in page in the cloud browser, then continue the task. | These work together. A task can reuse a saved session and use your saved password if the site asks for sign-in again. Chrome sync requires a paid plan. See [plans](/pricing#free-mode) for task and schedule access. ![Secure logins in Cloud, with Add login, saved accounts, and each site's actions menu.](https://rtrvr.ai/docs/logins/cloud-light.webp) Cloud keeps synced sign-ins and saved passwords together by site. Example accounts shown. [Dark theme screenshot](https://rtrvr.ai/docs/logins/cloud-dark.webp) ## Saved logins Save a password when you want Retriever to sign in for your tasks, including when a copied Chrome session stops working. - Open **Secure logins** and choose **Add login**. You can also choose **Add login** from the **Logins** menu below the Cloud prompt. - Enter the website, your username or email, and your password. If you use a named browser profile, select it before saving in Cloud. Relay saves to Default. - If the site uses an authenticator app, expand **2FA code (optional)** and enter its setup key or setup link. This is the key used to generate codes, not a six-digit code that expires. - If the site has a separate sign-in page, add its URL under **More options** in Cloud, or **Sign-in page (optional)** in Relay. Choose **Save**. > **info**: Your password and authenticator setup key are encrypted when saved. Retriever's sign-in code fills them on the website; the AI model does not receive them. Never paste a password or setup key into chat. When a task needs sign-in, Retriever tries the matching saved login. If the site rejects it, asks for an email or text code, or requires a CAPTCHA or passkey, the task pauses for you. A saved password cannot bypass the site's verification. ## Sync from Chrome - Sign in to the website in the Chrome profile where Relay is installed. Use the same Retriever account in Relay and Cloud. - Open the lock icon in Relay. Under **Sync from Chrome**, enter the **Website or URL** and choose **Add site**. Allow Chrome access if prompted. - Check the site's status under **Syncing from Chrome**. Choose **Sync now** to send a fresh copy. The refresh button beside **Saved in Cloud** reloads that list; it does not start a new sync. - Open [Secure logins in Cloud](/cloud?view=logins) to review the site, then start your task with **Default** selected in the **Logins** menu. ![Relay's Secure logins panel showing Sync from Chrome, Add login, Sync now, and Auto-refresh enabled.](https://rtrvr.ai/docs/logins/relay-light.webp) Relay syncs the sites you choose from this Chrome profile. Example accounts shown. [Dark theme screenshot](https://rtrvr.ai/docs/logins/relay-dark.webp) ### Auto-refresh Auto-refresh turns on when you add your first site, unless you previously paused it. **Auto (recommended)** checks every 15–30 minutes. You can choose a different interval under **Sync settings**. Pausing Auto-refresh stops scheduled checks; login changes still sync for enabled sites while Chrome is open. Chrome must be open to send updates. Cloud can use the last saved session while Chrome is closed, or sign in with a saved password when needed. A site can still expire or reject a copied session. Chrome sync reads only the current Chrome profile and saves to Default in Cloud. For separate client or work accounts, use [named browser profiles](/docs/profiles) and add each account in its profile. ## Sign in during a task If a task pauses at sign-in, **Review login** lets you update a saved password. If none is saved, choose **Add login**, or **Sync from Chrome** when offered. Choose **Continue** after saving or syncing. Saving a password gives Retriever the details it needs to sign in; it does not sign the browser in by itself. To sign in yourself, choose **Sign in yourself** or **Take control** and complete the site's sign-in in the cloud browser. Hand control back and continue. The task keeps its original instructions, URLs, and files, so you do not need to resend them. ## Reuse a cloud sign-in After a successful cloud sign-in, Retriever saves the site's cookies and supported browser storage for later tasks in the same profile. The next task restores that session. It does not need the same cloud browser or an open Chrome window. For a daily task, choose the right profile and run the task once before scheduling it. Later runs reuse that profile's sign-in. If it expires, the agent can sign in again with a matching saved password. Verification or a rejected password can still pause a scheduled run. See [Schedules](/docs/schedules). **No logins** starts a task signed out and does not use your saved passwords. Sessions belong to your Retriever account and selected profile; another user allocated a cloud browser does not receive them. ## Choose an account You can save different accounts for the same site. Name the account in your task, for example, **Use alex.work@example.com for LinkedIn**. If the choice is unclear, Retriever asks. For recurring tasks that use different accounts on one site, keep each account in a [separate profile](/docs/profiles). Saving the same site and username or email in the same profile offers **Update existing login**. It does not silently overwrite the password. If older duplicate copies exist, the confirmation also offers to remove those copies while keeping the selected login. Other accounts stay separate. Similar masked email labels alone do not make two records duplicates. ## Edit or remove access | Control | What it changes | | --- | --- | | **Edit** | Update a saved login. The masked password means a password is already saved. Leave it unchanged to keep it; type a new one to replace it. | | **Delete login** in the site's actions menu | Delete that saved password and setup key. An existing synced or cloud sign-in stays. | | **Remove sign-in** in the site's actions menu | Remove that site's stored session from the selected Cloud profile. Its saved password stays. In Default, Cloud also asks the connected extension to stop syncing that site. | | **Remove** in Relay | Stop syncing that site from this Chrome profile and remove its stored Default session. Saved passwords stay. | | **Disconnect Chrome** under Relay's Sync settings | Revoke this extension's cookie access. Data already saved in Cloud stays until you remove it there. | To stop future access to a site, remove both its saved password and its sign-in, and stop syncing it from any other Chrome profiles. Removing a sign-in does not cancel an active task. Cancel the task too if it should stop now. Signing in again deliberately can save a new session. ## Privacy and storage Saved passwords and authenticator setup keys use AES-256-GCM encryption and cannot be revealed from the login list. The list shows the site and a masked username or email. Synced sessions are stored under your account. Default cookies are access-controlled but are not encrypted by the browser-profile key. Named profiles encrypt cookies and site sign-in state with their own key, protected by Google Cloud KMS. Saved passwords are encrypted separately in both cases. A Workspace shares credits, not members' website logins. Deleting a named profile removes its stored sessions and saved passwords. Browser logins are also separate from app connections: a Google website login does not grant Drive file access. Use [Connectors](/docs/connectors) for that. ## Troubleshooting | What you see | What to do | | --- | --- | | The site still asks for sign-in | Check the selected profile. Review its saved password, sync a fresh Chrome session, or sign in with Take control. | | Auto-refresh is paused | Turn it on in Relay if you want scheduled checks. A previous pause is remembered. | | A verification request | Complete the site's code, CAPTCHA, passkey, or SSO step in the cloud browser, then continue. | | More than one account | Choose the saved account or name its username/email in your task. Use separate profiles for recurring work. | | A sign-in returns after removal | Check other Chrome profiles for sync and whether a saved password can sign in again. Remove both forms of access if neither is wanted. | --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # Permissions & Privacy See what rtrvr can access, why each permission exists, and the boundaries enforced by the API. # Permissions & Privacy ## Free Mode and paid plans Free Mode includes supported AI models and Cloud browser time for tasks you start in the extension or Cloud dashboard. No AI API key or paid AI subscription is required. Sponsored cards and a daily fair-use allowance apply. Your account shows the current allowance and reset time. When you reach it, wait for the reset, use your own AI provider, or choose a paid plan. Your provider may charge for its usage. New accounts receive 100 one-time welcome credits for paid usage. They are separate from the recurring Free Mode allowance. One schedule that runs once a day or less often, in the Cloud or in your Chrome, is included, paid from the daily allowance. More schedules, faster schedules, triggers, cookie sync, API runs, rtrvr's agent over MCP, and WhatsApp tasks require a paid plan. Browser tools that let your own AI drive your Chrome over MCP are free on every plan. Data enrichment and managed proxies can use credits separately. On the free plan, Cloud API calls made with an API key, the MCP Cloud tools (cloud_agent, cloud_scrape, and agent or scrape when they run in Cloud), and WhatsApp tasks need a paid plan, as does running rtrvr's agent in your Chrome through API or MCP. Free Mode covers the tasks you start in the extension or Cloud dashboard. On a paid plan, API, MCP, and WhatsApp runs use credits for the resources they consume. Free Mode involves sponsored content in both the Chrome extension and Cloud, as described in the Terms and Privacy Notice. [Compare plans](/pricing#free-mode), read the [Free Mode terms](/terms#free-mode), or see the [Privacy Notice](/privacy). ## Why Google Sheets? rtrvr.ai uses Google Sheets as a "memory layer" for complex workflows. When you run multi-tab automations, each tab operates as an independent sub-agent that needs to read inputs and write results. Sheets provide a structured way to orchestrate these parallel operations. Need to connect or reconnect Drive? Follow the [Connectors guide](/docs/connectors). ## Google Drive: drive.file Scope We use Google's most restrictive Drive scope: drive.file. This is the smallest permission available and gives us access ONLY to files we create or files you explicitly select through the Google Drive Picker. rtrvr asks for it only when a task touches a Google Sheet, Doc, or Slides: an attached sheet or a Google link up front, or, once the plan is generated, a plan that writes a spreadsheet (you see the plan and decide). Other tasks run without it, and any rows a task collects come back in chat, where you can save them to a Sheet later. | Allowed | Not Allowed | | --- | --- | | Create new Google Sheets for workflow outputs | Browse or search your Drive | | Access Sheets you explicitly select via file picker | Access your existing documents | | Write results to Sheets rtrvr.ai created | Read files you haven't explicitly shared | | | Access shared drives or team files | > **success**: This restriction is enforced by Google at the API level, not just by our code. It's technically impossible for rtrvr.ai to access files you haven't explicitly granted. ## Local Actions rtrvr.ai is built on a local-first architecture. The agent runs primarily in YOUR browser using Chrome Extension APIs. In Chrome, the agent uses your existing logged-in sessions, and your credentials stay on your machine. It never asks for a password in chat. Cloud tasks use the selected profile's stored sessions and saved passwords. You can sync a session from Chrome, save a password, or sign in during a cloud task. Retriever can keep that cloud sign-in for later tasks in the same profile. Saved passwords are encrypted and filled by sign-in code. See [Secure logins](/docs/cookie-sync) for setup, storage, and removal. ## Data Retention - We don't store Sheet data: it lives in YOUR Google account - Task artifacts are retained only for workflow replay purposes - Execution logs are automatically deleted after one week - Logs are retained only for debugging and customer support ## AI & Training Data Your data is NOT used to train AI models. Our contract with Google explicitly forbids training on inference data, and rtrvr.ai does not perform any model training. Your workflows are processed and results returned: nothing more. ## Best Practice: Dedicated Chrome Profile For maximum peace of mind, use a dedicated Chrome profile for rtrvr.ai. This provides complete isolation from your main browsing and work accounts. - Click your profile icon in Chrome (top right) - Click "Add" to create a new profile - Name it "rtrvr.ai Automation" - Install the extension in this profile only > **info**: This eliminates any concerns about cross-contamination with work accounts. Questions? Email security@rtrvr.ai or join our Discord at rtrvr.ai/discord. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # FAQ Quick answers to the most common questions: attaching files, models and BYOK, credits, voice, schedules, logged-in sites, and Rover. # Frequently Asked Questions Quick answers to the questions users ask most, with links to the full docs for each topic. ## How do I attach a file (resume, PDF, CSV, image) to a task? Drag and drop the file anywhere onto the extension side panel (a "Drop files or images here" target appears; files up to 128 MB, or 20 MB in Private Mode), or click the + button next to the prompt box and choose Add Files. The same + menu also has Add Sheets (attach a Google Sheet whose rows drive a workflow) and Add Tabs (select browser tabs for multi-page workflows). The cloud dashboard composer accepts attachments the same way. ## How does the agent upload my file into a web form? Attach the file first, then reference it in your prompt: for example "fill this job application and upload my resume." The agent can read attached documents and upload any attached file into a page's file input while filling forms. A file over 20 MB isn't read by the model, but the agent can still upload it. For security it cannot browse files on your computer that you haven't explicitly attached to the task. ## Where are the files the agent downloaded? In the extension, downloads go through Chrome's normal download flow, so they're in your browser's Downloads folder: open `chrome://downloads` in a new tab to see every file the agent saved with a "Show in folder" link (the run's result also lists each file with a 💾 chip that opens that page). In cloud runs the files are backed up to your [Files](/cloud?view=files) and attached to the run. If the agent reported several files but you only find one, Chrome blocked the extra automatic downloads: click the blocked-downloads icon at the right end of the address bar, choose "Always allow", and re-run. See [Files & PDFs](/docs/web-agent#files--pdfs). ## Is rtrvr free? Are the APIs free? What do credits cost? Free Mode is ongoing for interactive tasks in the extension and Cloud dashboard, with sponsored cards and a daily fair-use allowance. New accounts also receive 100 one-time welcome credits for paid usage; these are not a monthly refill. API runs, the MCP Cloud tools (cloud_agent, cloud_scrape) and WhatsApp tasks need a paid plan, where they bill the resources they consume; the MCP browser tools your own AI drives are free on every plan. Bringing your own LLM API key shifts model usage to your own provider instead of platform credits, and nothing deducts from the free plan's daily Free Mode allowance. The free plan is sponsored either way (a small card appears beside results); ad-free runs come with paid plans. Current plans, credit allowances, and prices are always at [Pricing](https://rtrvr.ai/pricing); Rover site subscriptions are priced separately at [Rover Pricing](https://rtrvr.ai/rover/pricing). ## My task paused and asked whether to keep going: what is the credit ceiling? That is the per-task credit ceiling: a cap on what a single run may spend before it checks with you, so a task that loops or crawls further than expected can't quietly burn your balance. The default is 100 credits on paid plans and 25 on Free. Answer "Continue" to resume from exactly where it stopped with a fresh budget (nothing already done is repeated), or "Stop here" to keep the result and end the task. If your work routinely costs more than that, raise the ceiling once instead of answering every time: in the extension it is Settings → Agent Settings → "Credit Ceiling / Task", and in the cloud it is [Settings → Storage & Execution](/cloud?view=settings§ion=storage). 0 turns the check off. Full details in [Web Agent → Credit Ceiling per Task](/docs/web-agent#credit-ceiling-per-task). ## How do I add my own API key (BYOK)? Open Model Settings in the composer and use the "Add your LLM API" flow: it accepts keys from any major provider (OpenAI GPT models, Google Gemini, DeepSeek, OpenRouter models, or a local/custom endpoint), and you can also sign in with your ChatGPT plan directly. For Gemini, typing /add-gemini-key in the extension walks you through getting a free key from Google AI Studio. Keys are stored encrypted and work in cloud runs too. See [Getting Started](/docs) → Models & Bring Your Own Key. ## Which AI models does rtrvr use? Free Mode includes the supported models shown in Model Settings. You do not need your own AI subscription or API key to start. Paid plans unlock additional managed models and features; your account shows the current choices. ## Can the agent hear me? Can it listen to audio on a page? Voice input works: tap the microphone button in the composer to speak your task, and once WhatsApp is connected you can send voice messages to trigger workflows (see [Cloud & Mobile](/docs/cloud-mobile)). However, the agent cannot listen to audio playing inside a web page: it reads the page's structure (DOM), so tasks that depend on hearing page audio (e.g. transcribing an embedded player) are not supported. ## Why does the cloud browser show about:blank? A cloud run starts on about:blank while a fresh browser instance boots and the automation script loads. As soon as the workflow performs its first navigation, the live preview switches to the real page. ## Do scheduled tasks run when my browser is closed? Extension schedules run inside your Chrome with your logged-in sessions, so they execute while the browser is open: a missed run fires automatically when Chrome reopens. For true 24/7 execution, export the workflow to Cloud and schedule it there. See [Schedules](/docs/schedules). ## Can the agent use my logged-in accounts? In the extension, yes: it works in your browser with your existing sessions, no credential sharing needed. Cloud tasks can reuse a saved session, sign in with a saved password, or pause for you to sign in. Choose the account in [Secure logins](/docs/cookie-sync). ## Why does a Subroutine say a token or ID is invalid? If the error appears before a draft tool opens, refresh your rtrvr sign-in and retry once. If the tool was created and fails when it starts, sign in to the target site again, make a fresh recording, and regenerate the Subroutine once. If it fails again, keep the run and contact support: the generated request may be missing a current token or request ID. A Workspace shares credits, not member logins or target-site credentials. See [Recordings → If a Token or ID Is Invalid](/docs/recordings#if-a-token-or-id-is-invalid) for the full check and the details to send support. ## Does rtrvr take over my screen or mouse? No. The agent is DOM-native: it acts directly on browser tabs (clicking, typing, extracting against the page structure) and you can watch it work in real time. It never controls your mouse, keyboard, or anything outside the browser. ## How do I put an AI agent on my own website? That's [Rover](https://rtrvr.ai/rover): create your site in the [Rover Workspace](https://rover.rtrvr.ai/workspace), copy your Site ID, and add one script tag to your site. See the [Rover docs](https://rtrvr.ai/rover/docs) for installation and configuration. --- Agents: live prices and self-serve payment for Retriever AI are at the agent storefront, https://agents.rtrvr.ai/llms.txt?src=llms-txt --- # rtrvr.ai Changelog What you can do with rtrvr now, what comes back, and what works more reliably. Newest first. ## v66: Screenshots and files as links from /agent, pages read without a tab, site maps, and every reasoning level in Free Mode on paid plans. *November 11, 2026* Extension 38.3.13 is with the Chrome Web Store for review, and Cloud, the API and the website have updated. Every screenshot and file a Cloud run makes now comes back from /agent as a link with its checksum and source page, and evidence screenshots tie each record to the page it came from. The agent reads pages by URL without opening a tab, Map lists a site's pages for free, and a new endpoint lists where the managed proxy can exit. Any paid plan now runs Free Mode at every reasoning level, with schedules that use the daily allowance first. - **Context:** Extension 38.3.13 is with the Chrome Web Store for review, and Chrome installs it on its own once it is approved. It carries the extension side of this release: reading pages without a tab, Map, Free Mode on paid plans, longer runs, lesson-site widgets, next steps and the one-click repeat schedule. Extension 38.3.12 shipped on November 5 with the act agent reading every open tab in full and the dropdown fix below. Nothing in either needs new permissions. - **New:** Screenshots and files come back as links from /agent. Every screenshot, image, PDF and file a Cloud run makes is listed in the response's artifacts, each with a link that works for 7 days, its size, a sha256 checksum, the page it came from and when it was captured. GET /artifacts/{id} returns the same list with fresh links. Add options.evidence.screenshots: true and the agent captures every page it takes data from and tags each record with the screenshot's evidenceArtifactId, so each row can be checked against the page. Webhooks list images too, and MCP cloud_agent returns the same list. ([Agent API](/docs/agent)) - **New:** See where the managed proxy can exit before you run. GET /proxy-locations lists every country code a location accepts and whether the managed proxy had an exit there when we last checked: 120 of 249 countries on November 11. It also gives the region and city format and the fallback a run uses (city, then region, then the whole country, never another country). The docs list the countries, and POST /proxy-location/check still answers for a region, a city or a list right now. ([Supported locations](/docs/agent#proxy-locations)) - **New:** Pages read without opening a tab. The agent can now read a page by its URL off the browser: directly first, then through the residential proxy, then through an unblocker on a bot wall (0.15 credits a page). It gets the same page structure a tab read gives, and an error page counts as a failed step instead of content. This is live in Cloud and over MCP fetch now, and reaches the extension with 38.3.13. - **New:** Map lists a site's pages before reading them. Map reads the site's robots.txt and sitemaps and, when they list nothing you asked for, follows the site's own links for a short crawl, with no browser and no model. A section such as docs.python.org/3/library/ that the sitemap leaves out now returns its 307 pages instead of none. It is free, apart from 0.15 credits a page when a bot-walled page needs the unblocker (at most 3 a map). Use it from the API (POST /map), MCP map and Cloud tasks now, and in the extension with 38.3.13. - **New:** Every reasoning level in Free Mode on any paid plan. A paid plan runs Free Mode's value models at every reasoning level, up to Max, while premium models run on credits. Schedules use the daily Free Mode allowance first, then credits, and each schedule has a Billing choice: Free Mode first, or credits only with no ads. Cloud has this now; the extension gets it with 38.3.13. ([Pricing](/pricing)) - **New:** Next steps after every finished run. A completed run suggests what to do next, its first suggestion fills the empty message box, and Tab sends it in. A short reply such as "next" or "the second one" now goes out as the suggestion it names, instead of starting the work over. A new user's first finished run also offers to run it again tomorrow. - **New:** One-click schedules for tasks you repeat. When you run the same prompt on two or more earlier days, the side panel offers to schedule it on that Chrome, emailed to you by default. With 38.3.13. - **Improved:** Long runs keep going. A pass no longer starts with under 3 minutes left in a run's 45-minute window, the window renews while the run keeps making progress, and the time a run spends waiting for your answer no longer counts against it. With 38.3.13. - **Improved:** Runs check their own work. The end-of-run review now reads a record of every call each script actually made, so a run's last pass answers from what happened rather than from the script's own summary. It runs once per run and no longer uses up the run's repairs. In Cloud and in the extension. - **Improved:** Longer tasks stay quick and cheap. A run keeps every earlier step's element ids and history until a size budget, instead of dropping the oldest after 20 steps and re-sending the rest, so more of each pass is read from the model's cache. Since November 5 the act agent also reads every open tab in full (38.3.12), and a READ ONLY tab needs no switching. - **Improved:** GPT-6 Luna, GPT-6.1 Sol and GPT-6.1 Terra run on Bedrock global first, then regional Bedrock, then OpenAI, on every round. The models page shows the order. ([Models](/models)) - **Improved:** Lesson and course sites. The agent picks a radio answer by its label, drags with the keyboard where a widget only takes keys, describes canvas images, types into spreadsheet-style grids and commits with Enter, plays a lesson video the page waits on, and answers listening questions from the page's audio instead of guessing. Icon-only buttons are named by their icon, so the right one gets clicked. With 38.3.13; the radio, drag, canvas and grid fixes also run in Cloud. - **Fixed:** Lists extracted from one page stay whole in Cloud. Pulling a page's items into a structured result (all the quotes on a page, say) no longer comes back split into one record per item, which had left a saved CSV with 1 of 10 rows. - **Fixed:** Dropdowns and network reads. On a form of token pickers, another field's chosen chip no longer counts as this field's answer (38.3.12, and in Cloud). A network extract stops at the timeout it asked for, with a 60-second minimum, instead of 45 seconds later. - **Fixed:** Model failovers. A DeepSeek Flash image-count error moves the call to the next supplier at no cost. In the extension, an image-budget error fails over to OpenAI and AVIF images are converted to JPEG instead of dropped. With your own Anthropic key, MCP tools with dots in their names work instead of falling back to managed models and billing credits. - **Fixed:** Cloud and Tailscale. Asking Cloud to open localhost or a private address gets a plain refusal instead of a server error. A run paused for a Tailscale sign-in hands its tunnel to a newer run instead of holding your one route for 10 minutes, and auth-key refusals say they are auth-key problems. - **Improved:** For AI apps and the API: Enable Extension as MCP is on by default on every plan with 38.3.13, free tools are listed first, and a tool your plan cannot use answers with next steps instead of a protocol error. MCP gains fetch and map, and the API gains POST /map, GET /proxy-locations and GET /artifacts/{id}. - **Fixed:** Smaller fixes. The Free Mode device-limit notice names the masked account that holds Free Mode on that computer, with a Switch account button. The post-install page opens Retriever with a first task ready (38.3.13). Gmail's connect window explains its consent screen, Confirm cancel stays readable on hover, and the /scrape docs describe the page tree as the text outline it is. ## v65: Web answers read at their source, forms that pick their options in one call, and results that come back as clean tables and PDFs. *November 4, 2026* Extension 38.3.11 is rolling out on the Chrome Web Store, and Cloud, the API and the website update with it. A web lookup now reads the fact on its source's own page and cites it, in fewer passes and searches. Typing into a choice field picks the option, dropdowns pick only from their own list and read the value back, and the read after a click waits for the page. A table you ask for comes back as rows, a one-page PDF fits one page, and results leave out the page reads behind them. Runs can wait out a render or a build, clicks in background tabs and embedded frames land more often, and on the free plan research now runs in Free Mode. Since October 31, extensions 38.3.9 and 38.3.10 added sheet status tabs and stopped a Google Sheet tab from flashing over yours, and since November 1 helper steps think one level below your reasoning setting. - **Context:** Extension 38.3.11 is rolling out on the Chrome Web Store, and Chrome installs it on its own. It carries the extension side of this release: the form, dropdown, click and drag fixes, embedded frames, long waits, the new side panel message with one export button and a Schedule button, paste to attach, list batches and deep search. Extensions 38.3.9 and 38.3.10 shipped since October 31 with sheet status tabs, steadier background reads and the Google Sheet tab fix. Nothing in it needs new permissions. - **Improved:** Web lookups answer from the source's own page, in fewer passes. To look up a fact such as a version, a date, a price or who holds a role, the searching script now also opens the result on the source's own site, the next pass answers from that page and cites it, and "latest" means what the official page says. In our Cloud tests on four lookups, runs went from 4.9 planner passes and 5.9 searches on average to 3.2 and 1.8, every answer cited the official site, and model credits per run fell from 0.59 to 0.42. Search results count as snippets, not the answer, so a run no longer ends "success" with the field it searched for left blank. A local search the script did not flag ("near me", a service in a city) now gets places results first, and a name with "linkedin" gets a LinkedIn-filtered search. In Cloud and in the extension. ([Web search](/docs/search)) - **Improved:** Forms and dropdowns fill in one call. Typing into a choice field now picks the option the text names and reads it back. select_dropdown_value picks only from the field's own list (it had clicked options in a neighbouring list or the site's menu), checks the field's live value, types into the popup's own search box, gives Workday prompts their Enter and matches across accents and word order; a native select that lacks the exact wording names the nearest options, such as "BS" for "Bachelor's". The read after a click waits for the page to settle, so a form is no longer caught mid-submit, and it leaves open the menu the click opened, LinkedIn's More included. In Cloud and in the extension; needs extension 38.3.11 in the extension. - **Improved:** Helper steps think less, and Cloud plans at full speed again. Since November 1, act steps, page extraction and text processing run one reasoning level below your setting while the planner keeps it: max to high, high to medium, medium to low, low to off. DeepSeek, GLM and GPT-6.1 Sol stop at low, and an Off you picked stays Off. In our tests Luna act steps scored 98.3% at off, low and medium alike and page extraction 100% at every level, and image captions now really run at low: 2.3 seconds at the median instead of 3.9. Cloud's planner had been writing about 40% slower than the extension's since October 30 (a median planning call went from 8.1 to 13.2 seconds for the same output); this release fixes the routing that caused it. A planning pass over about 250K tokens now sends only its last three results in full, so very long runs stay quick. In Cloud and in the extension. - **Improved:** Tables, lists and results come back whole. A table you ask for now finishes as rows under a named field, never a Markdown string, and the Cloud result card also reads a table returned as text into rows: a "return them all as a table" run that showed 3 records now shows all 30, with Table, Sheet and CSV working. Opening each item of a list dedupes its links and reads the fields you named with extract: an 8-book task that ended Partial with its price column empty now returns all 8 rows with every field and no duplicate tabs. The finished result holds the answer fields and a summary that leads with the answer, never the page reads that checked them. A follow-up in the same chat treats earlier replies as finished tasks and checks their facts again when the new task depends on them. In Cloud and in the extension; the extension's Result and MCP output need 38.3.11. - **Improved:** Plans take fewer passes and ask less. The planner now puts the page steps it can already name in one script and hands a run of dependent steps to one act, where a third of planner passes had only clicked or typed one to three times and read the page back. An act step the page confirmed counts as done, so acts stop answering "could not be verified" after doing the work. An act now takes up to 25 steps by default, up from 15: 87% of acts that stopped at exactly 15 were followed by another act averaging 9.8 more steps. In the extension, the planner asks first only for a required input nothing supplies or an outward step you didn't ask for, and a "don't ask" holds for the rest of the run, never for a sign-in, payment or personal detail. In Cloud and in the extension; the 25-step default and "don't ask" need extension 38.3.11 in the extension. - **New:** PDFs fit the page count you ask for. A one-page or landscape request now reaches the generator, which steps type, spacing and margins down until the PDF fits without cutting anything and states the page count, so the run no longer reads it back. Long table cells stay whole, and a row taller than a page carries on under the repeated header. In our test, a one-page PDF of every quote on a tag, which had run the generator four times and paused at eight steps, came back from one call as one page with all 14 quotes and authors, in 1.5 minutes and 2.72 credits. A file that still misses a layout after one retry is delivered with what differs, never generated a third time. In Cloud and in the extension. - **New:** Deep web search, and research on the free plan. The planner can now run one deep search that reads the top pages and writes a cited answer, in the shape you ask for when you name fields: about 10 to 12 seconds, billed as 8 searches (free units first, then 1.2 credits a call), and nothing when it fails. On the free plan, research now runs in Free Mode runs, paid only from your free monthly data-tool allowance and never from credits. Research always runs at its low effort, about 2.5 credits a call on paid plans, and now asks for the number of rows you want: 64 of 65 Cloud research calls had left it out and stopped near 10. Deep search is in Cloud now and in the extension with 38.3.11 and Web Search on; the research changes apply in both. - **New:** Runs wait out long jobs. A wait can now last its whole duration, up to 2 minutes at a time, so a render, an app build or a queued video is waited out instead of ending at the page's first change, and the planner waits out a running job in one script, up to 10 minutes on the finished control. Before, extension runs spent 769 planner passes in two weeks on 10-second waits that ended early (AI Studio builds took 63 to 67 per task). Stop still ends a wait at once. In Cloud and in the extension; needs extension 38.3.11 in the extension. - **New:** A cleaner side panel answer, with one export and a Schedule button. A finished run's message leads with the planner's reasoning, then one closed row per step, then Artifacts and the Result, one level deep; Copy still gives the whole run, and a data block longer than 12 lines folds to its first 6. A table gets one export button: Google Sheet when Sheets access is granted, CSV otherwise. Every completed run has a Run this on a schedule button, prefilled. Pasting a skill link, @name or skill name attaches the skill, a Google Sheets link joins the run's tabs, and clipboard files upload as if dropped; the Skills menu leads with Suggested and Recent. Guidance you type stops a running script so the next pass plans with it, and sent guidance shows ✓, then ✓✓ once read. A one-question choice answers on the first click, a retry with a note carries the task, and Connect Gmail sits at the top of the Tools menu. Needs extension 38.3.11. ([Schedules guide](/docs/schedules)) - **New:** Skills, schedule cards and Gmail in Cloud. A new Skills button in the Cloud composer opens a picker with search, Suggested, Recent and All skills, and the skills you pick ride the run; pasting a skill link, @name or skill name attaches it, a Google Sheets link attaches as a sheet even past the 3-link limit, and clipboard files attach like the Files button. Each skill in the Skills panel has Use in a run. A run that makes schedules shows a card for each one, and a repair pass now updates the run's schedule instead of making a duplicate. Connect Gmail is in the Tools picker and in Secure logins. Generated files are named by their title, never a storage path, and a run's read-back copy of its own PDF no longer shows as another file. ([Skills guide](/docs/skills)) - **Improved:** Run in my browser waits for your answer. A run sent from the website to your Chrome that stops on a question now shows the question, with no confetti, and your answer goes back to the same browser to carry on; before, it read Done, as 86 of 225 such runs in 30 days did. A retry carries the task, and a send that cannot start says why (no browser picked, offline, signed out, update needed) and offers Open Retriever, Check again or Run in Cloud. A template's Run button is no longer greyed out for a missing browser, an account with one connected browser has it picked, and Cloud's sign-in wall offers Run in my browser when the extension is connected. - **New:** Sign-in codes from your inbox, and Gmail sends that report right. When your task asks for it, the agent can type your email at a sign-in page and read the code from your connected Gmail, and with no Gmail connected the connect offer says it covers sign-in codes. A Gmail send or draft now returns its sent flag and its message, thread or draft id, where 35 real sends from October 19 to November 2 had been reported as failed. A missing or revoked Gmail permission says to reconnect, and the next connect asks for it again. In Cloud and in the extension. ([Connectors](/docs/connectors)) - **Improved:** Sheet jobs keep their place, on any sheet. When a task or skill limits which columns may change, a sheet batch keeps its statuses in its own "rtrvr status" tab keyed by your key column, so sorting or inserting rows keeps the progress and a repeated key runs once. Any task with a Sheets link or an attached spreadsheet now gets the sheet batch guidance (on October 31 all 11 runs that worked through a sheet's rows by hand had missed it), and so does a task that puts per-item results in a sheet. In the extension, a per-item job over a list with no sheet keeps its progress the same way. A Google Sheet the run reads no longer opens a second copy in front of your tab, and a new sheet given rows writes them. A view-only read of a sheet the run has no access to reads its page instead of asking first: 44.8 seconds in our Cloud test, where it had waited 11 minutes. In Cloud and in the extension; list batches need extension 38.3.11. ([Sheets workflows](/docs/sheets-workflows)) - **Improved:** Executions show where your credits went. The Executions page has Today, This week and This billing cycle chips with totals for the period, a project filter for runs tagged from AI apps or the API, and now lists runs that AI apps started in your own Chrome, which were missing. The Account card shows the cycle's spend split into one-time and monthly credits, and get_current_credits reports the cycle's real spend instead of 0. - **Improved:** For AI apps and the API: agent, scrape, extract_from_tab, cloud_agent and cloud_scrape take a project tag that list_executions filters on; scrape, get_page_data and take_page_action point list gathering at extract_from_tab (one app had spent 45 calls and 88 minutes on 9 listings); a browser that stops responding answers not retryable, with a retry-after and, after 5 minutes, a note to open Chrome; a busy browser queues scrape like the page commands; on the free plan, a scrape or agent call with no browser to run in is told what it needs instead of going to the paid Cloud browser; check_results questions are answered on GLM Flash; and a client that keeps sending a dead API key gets 429 with Retry-After. ([MCP guide](/docs/mcp)) - **Improved:** Background tabs and parallel runs read and click more reliably. A click in a tab you are not looking at that changes nothing is now always retried with the tab shown, instead of being refused after six shows in ten minutes (117 clicks from 20 users failed that way in the week before). At the task's tab limit, an act that wanted a new tab opens the page in its own tab instead of being refused, as 313 of 492 such opens had been inside parallel runs. Parallel reads take turns at the page, and a read that ran out of time gets one more try, where a quarter of reads in fan-outs of four or more had come back empty. Typing that timed out in a background tab brings the tab forward and checks the field before typing again, and activate_tab shows a tab until it draws, then gives you yours back. Since 38.3.9, a page that keeps changing in a background tab, like Google results, is read without a 3-second wait. Needs extension 38.3.11; the tab-limit and typing fixes also apply in Cloud. - **Improved:** Embedded frames and downloads. Frames now get their read time after the page itself is read, a child frame answers before its parent stops waiting, and frames identify themselves even in background tabs, so notebooks, course players and embedded apps read from inside: in our tests Colab read all 8 output frames in a background tab, and a lone 3,000-row frame read whole where it had come back with 302 to 2,039 rows. Ad frames no longer mark retail and game pages partial. A PDF shown in a viewer frame downloads as the PDF, not the viewer page; download_file saves any file except a web page, and an installer only when you ask for one; and a link that answered 401 to 410 is not fetched again in the run. Needs extension 38.3.11. - **Improved:** Clicks, drags and keys land. A click whose effect shows on the next read (its target changed, or its popup opened) now counts as done, and a step with an unconfirmed result reads the page again instead of re-sending the old view. Look-alike buttons, such as each row's Edit, are told apart by their row. A drag presses the widget's own hit layer and follows its pointer capture, keyboard handles drawn in graphs (Khan Academy's points, where all 19 drags had failed in a week) can be focused and moved, press_key takes a count of up to 20 arrow, Tab or Backspace presses in one call, a video slider lands within a step, and typing into a web terminal sends each key once. In Cloud and in the extension; needs extension 38.3.11 in the extension. - **Fixed:** Cloud runs keep their work and their credits. A Cloud run that ends in error before its first step is no longer billed for browser time. A run whose time limit cuts a planning call after it already has output keeps that work: a run you are watching pauses with Continue or Stop here, and a scheduled one ends partial. Continuing a paused Free Mode run after a page reload no longer fails with "Could not verify Free Mode", which 14 of 23 such refusals had been. A write to a Google Sheet the run cannot open stops and says so instead of typing into the grid. - **Fixed:** Smaller fixes. For you suggestions think at their usual level again, after the November 1 change had left about a third of feeds empty. A free-plan Chrome schedule saved to run more often than daily moves to daily once, with one notification, instead of being refused at every run, and the one-schedule rules also apply when you resume, switch on or edit one. A new Rover site no longer reads Live before Rover has loaded on it. Chat history no longer shows a Firebase Storage permission error on every panel open. A Google Doc or Slides deck that Drive refuses costs no credits and names the access it needs. A file excerpt a plan returns to itself shows whole up to the step's budget instead of 3,000 characters. Extensions older than 38.2.0 are asked to update before planning, with nothing run and no credits used. An act the model provider refused is not sent again, the network tool runs only when you want every record and says quickly when a site has no usable endpoint, and the website's contact links open Gmail compose in a new tab. ## v64: Secure logins, guidance that follows WordPress, job portals, course sites and seller centres to any domain, and widgets that stop derailing runs. *October 31, 2026* Extension 38.3.8 is rolling out on the Chrome Web Store, and Cloud, the API and the website update with it. Save a site's login and 2FA key once and Cloud runs sign in for you, without the model ever seeing the password. What the agent knows about WordPress, WooCommerce, Workday, Greenhouse, Canvas, Moodle, n8n, Odoo and the big seller centres now applies on every site built on them, not only on one address. Date pickers, typeahead lists, code editors, long grids and pop-up dialogs get their own handling, background tabs read whole (LinkedIn profiles and Luma guest lists included), long Google Sheets jobs track every row and pick up where they stopped, and a finished run suggests a next step or a schedule. Since October 27 you can also pay yearly with two months free, run a daily schedule on the free plan, and build a lead list in one step with research. - **Context:** Extension 38.3.8 is rolling out on the Chrome Web Store, and Chrome installs it on its own. It carries the extension side of this release: platform guidance from the first step, the new widget and dialog handling, sheet batch mode, next steps after a run, whole reads of background tabs, faster runs from AI apps, and the search and typing fixes. Extensions 38.3.3 to 38.3.7 shipped earlier this week. Nothing in it needs new permissions. - **New:** Secure logins. Save a site's username, password and optional 2FA key once, from the Logins page in Cloud or the side panel's Secure logins panel, where the site you are on is one click away. At that site's sign-in page, a Cloud run types the login, makes the 2FA code and keeps the session for later runs; the model never sees the password, and email or SMS codes, captchas and passkeys still come to you. Each site shows a plain status (Synced from Chrome, Kept from cloud sign-in, Signed out by the site), and saving a second login for the same account offers to update the existing one. ([Logins and cookie sync](/docs/cookie-sync)) - **New:** WordPress on any site. wp-admin, Elementor, WooCommerce and cPanel get the agent's guidance on every host, where what it learned on one site used to stay there. It builds an Elementor page as real widgets in one go, creates WooCommerce variations in one batch, and fills Rank Math, Yoast and ACF fields without fighting the editor: in our tests a 10-widget Elementor page took 53 seconds and under a credit. For WordPress.com and Jetpack sites, the agent can offer to connect the WordPress.com connector instead. In Cloud and in the extension. - **New:** Job portals, course sites, back offices and seller centres on any domain. Guidance now follows the platform, not the address: job applications on Workday, Greenhouse, Lever, SmartRecruiters, Ashby, iCIMS, Taleo, SuccessFactors and Dayforce (including forms embedded on an employer's careers page); Canvas, Brightspace, Blackboard and Moodle on school domains; n8n, GoHighLevel and Odoo on any host; Xero, Amazon Seller Central and Ads, Meta's business tools; and seller centres for Etsy, eBay, Walmart, Meesho, Shopee, TikTok Shop, Flipkart, Lazada and Trendyol. Replaying failed runs, the right guidance was there from the first step in 71 of 84 job and course runs (from 51) and 79 of 90 seller runs (from 37). Your own skills can now target a platform too, such as all Workday job sites. Naming a site in your prompt also brings its guidance from the first step in more languages, including Spanish, Italian, Portuguese, Vietnamese, Indonesian, and Hindi or Bengali typed in Latin letters: 70% of such prompts in our replays, from 47%. ([Skills guide](/docs/skills)) - **Improved:** Date pickers, typeahead lists, code editors, grids and search boxes. A date fills a calendar in one call, including month and year menus and both ends of a range; typeahead lists find options that load late; Monaco, CodeMirror, Ace and VS Code for the Web are written through the editor itself, so a long file goes in whole and undoes in one step; and scrolling a long virtual grid reads every row. Calendars now also open in tabs you are not looking at, and a picker or grid that only updates on screen says to bring its tab forward. A dropdown option already chosen is not clicked again in a background tab, so the click no longer lands on the next field. A search box that stands alone is submitted with Enter, and a box that already holds the query moves on to the next step instead of being retyped. In Cloud and in the extension; needs extension 38.3.8 in the extension. - **Improved:** Back-office runs stop tripping over the browser. We went through hundreds of failed runs from people managing stores, sites and admin panels and fixed the causes that were ours. A JavaScript alert, confirm or prompt is answered the way the task says instead of freezing the tab, including one a page shows while it is still loading (on https pages). A tab that stops responding is reopened fresh. An approval you gave covers the run, notices that leave the page usable no longer stop it, and cookie banners are declined. A form missing details is filled as far as it can go and asks you once, every change is read back from the live page before the run says done, and a request lost to a dropped connection is sent again. In Cloud and in the extension. - **New:** Next steps after a finished run. A completed answer now shows one-click follow-ups, and at most one offer to run the task again daily, on weekdays or weekly at the time you ran it. Offers appear only on a run you are watching, never in Private Mode or on scheduled runs, and you can snooze or turn off the schedule offer. In Cloud and in the extension. ([Schedules guide](/docs/schedules)) - **New:** Sheet batch mode. A task that works through a Google Sheet keeps each row's progress in an "rtrvr status" column, writes in blocks, and picks up where it stopped on the next run. It never rewrites a row marked done, skipped or failed, and a job that produces nothing for its first rows stops instead of stamping the whole sheet. In our test a 21-row job wrote all 21 rows in 37 seconds. Rows that found nothing are listed at the end and can be retried in one go, a list you ask to have in a new sheet is written there first and then worked row by row, and a website is checked for a contact page before a field is left blank. In Cloud and in the extension. ([Sheets workflows](/docs/sheets-workflows)) - **Improved:** Background tabs read whole. Chrome draws nothing in a tab it is not showing, so feeds like YouTube, Reddit and LinkedIn used to read thin there. In the extension the tab now draws the moment the agent reads it, without coming to the front: first reads found 16 to 24 YouTube videos and 27 to 46 Reddit posts, and runs on Amazon, Indeed and Fiverr finished without pulling the window over your work. LinkedIn profiles read whole: a profile the agent opens in a background tab draws itself within about half a second, so the agent's next look has every section (a run listing a profile's sections answered in full in 24 seconds), and a run through six profiles in one background tab finished in 83 seconds. Pages that are already drawn, like Hacker News, are read at once, and lists that load as you scroll fill in without the tab coming forward: a Luma guest list read all 317 guests. In Cloud a tab is shown just until it draws, and four parallel YouTube reads went from 4 or 5 videos each to 22 to 30. - **New:** Research builds a list in one step, and search is faster. On paid plans the planner can hand a lead list or an enrichment job to one research run instead of searching and reading each site itself: on 10 sample tasks it took a median 26 seconds and 2.5 credits, with 90 of 100 rows checking out, where a planned run took about 200 seconds and 13.5 credits. It is billed at cost, uses your free monthly data-tool allowance first, needs Web Search on, and is off in Private Mode. News, site: and local searches answer in a median 0.43 seconds instead of 3, and local results carry phone numbers and websites. Live since October 27. - **New:** Annual plans and a free daily schedule. Paying yearly gives two months free: Starter $100, Pro $300, Team $1,000 and Scale $5,000 a year, and plan credits still refill every month. The free plan now includes one daily Cloud schedule and one in Chrome, run on Free Mode. Live since October 27. - **Improved:** Questions don't stall a run. A how-many or which-ones question marks a recommended choice, and the side panel takes it after 2 minutes without an answer and says so. A waiting run badges the extension icon and shows a Chrome notification, and how many is asked up front only before a live action. In Cloud, each step shows the question it asked and your answer, and files you attach while answering stay with the run. Live since October 27. - **New:** Better ways in, offered. Instead of clicking through Gmail, GitHub, Notion or Slack page by page, the agent can offer to connect the app. It can also offer to share a Google Sheet with it, ask you for a file, or ask you to sign in first. Saying no snoozes that offer for 14 days. Live since October 27. - **Improved:** Getting started is quicker. On a computer, the first-day welcome in Cloud now leads with the extension and a short walkthrough video, with Start in Cloud still one click away, and after your first clean Cloud run one card suggests running it in your own Chrome next time; on a phone, Cloud leads. Right after install, the page the extension opens signs it in as the account you already use on rtrvr.ai, or offers sign-in right there. In the side panel, the empty message box types out real example tasks, and Tab puts the one shown into the box. - **Improved:** Tailscale never switches IP without asking. If the tunnel cannot connect, the run stops before touching a site and offers Retry Tailscale, Use Retriever proxy for this run (at the normal proxy rate) or Cancel, and a retry keeps your prompt, files and login profile. Schedules retry once and skip that run unless you allowed the proxy on that schedule. Startup gives up in about 10 seconds, and each exit node is its own clear choice in the picker. ([Tailscale tunnels guide](/docs/tailscale)) - **Improved:** Chrome logins hold in Cloud. Cookie Sync now carries a site's partitioned cookies and browser storage from one consistent copy, and a login made in the cloud browser stays until you choose Sync from Chrome. Auto refresh checks social sites every 15 minutes and other sites every 30, a partly restored login carries on with a one-click resync, a login you removed never comes back, and Continue after Take control keeps the session you just fixed. Page reads mask password fields. - **Fixed:** Cloud asks you to sign in instead of stopping short. After you accept Sign in now, or when a saved login needs a code only you have, the run pauses for Take control instead of ending as a partial result. With a password already saved the card offers Review login, and with several accounts on one site you pick one and Continue keeps your choice. - **Improved:** Schedules refuse what cannot run, and say why. A save that would fail at its first run, such as a page tool with no page to open, is refused with the reason on the editor tab that needs fixing, and tools a schedule cannot run are greyed out. A schedule whose tool broke later can still be renamed, retimed or paused. The schedule editor is reorganised into Task, Timing and Options, and switching views in Cloud no longer blanks the page. A Weekdays preset joins Daily, and switching a weekdays schedule to Daily now runs it every day instead of Monday to Friday. - **Fixed:** Answers that match the ask. A top-10 request with a field list returns ten rows, not one (8 of 8 replays, from 1 of 5). The agent ranks candidates before acting on the best one, a task that says apply or pick any password carries that permission to the step that fills the form, and extraction keeps only each item's own values, so a directory's own email and phone stop filling every company row. A result that prints undefined gets one more look, and one failed search no longer fails the whole step. - **Fixed:** Clicks, keys and page reads behave. Reading a page no longer leaves it scrolled to the bottom (on X a single read had dropped the first 9 posts). A loose match never clicks Dismiss inside a card the plan meant to open, Space toggles checkboxes and chips, Enter opens a link in the same tab, a late pop-up gets its own tab, and a drag that changed nothing retries as a mouse drag. LinkedIn member lists read whole, the first read sees past a cookie dialog, and a confirm the agent cancelled is accepted on the retry. - **Improved:** Long runs answer faster and cost less. Each planning pass starts from the run's progress so far instead of recounting finished items, the pass after you answer a question reuses its cached history, and resuming over MCP no longer re-sends the whole run. A lead-list run no longer pauses before free lookups or holds its scoring while slow profile scrapes catch up. Page reads drop repeated icons and duplicate long names and never carry page script text or an icon's own stylesheet, about 26% fewer tokens on the largest pages. - **Improved:** For AI apps and the API: check_results pages a long run's steps (one reply went from 560,095 to 37,799 characters) and a resume keeps the run's output schema; the MCP schedule tool edits, pauses and resumes Cloud schedules with no browser connected; cloud_agent takes continue_from and dataInputs, and treats a reused trajectoryId as already started (409 over REST); and a $V: variable named without a value is reported instead of typed, while extract and crawl now accept variables. A run sent to your browser starts and answers about 3 seconds sooner: it waits for its tabs to load instead of a fixed 2 seconds and closes them after the answer, so outside the model a Hacker News top 10 went from 4.9 to 1.8 seconds. ([MCP guide](/docs/mcp)) - **Fixed:** Smaller fixes. GPT-6.1 Terra takes GPT-6.1 Sol's place in the model menus at half the price, and a saved Sol keeps working. readFile reads every Excel column, row and sheet once per run (48.5 seconds became 0.6). A dropped connection right after sending no longer shows "Couldn't reach" for a run that started, and Cancel no longer leaves a run on Running. A finished run ends with its own closing note instead of the model's last reasoning, and Cloud plays its success sound and confetti only for a clean success, never for a failed, cancelled or partial run. A Free Mode run in Cloud checks the daily allowance at each step, as the extension does. Cloud and scheduled Sheets runs check Drive access with a fresh token before asking you to reconnect, a file the model provider cannot fetch no longer fails the step, element labels never include page script text, and site guidance is refreshed for LinkedIn, Pearson MyLab, Zillow, MercadoLibre and Reddit search. ## v63: Tailscale Tunnels beta: cloud runs from your own IP, and browser profiles for every client. *October 26, 2026* Tailscale Tunnels are live in beta. Retriever's cloud browser can now send its traffic out through a computer on your own network, such as an old laptop, a Mac mini or a Raspberry Pi, so sites see the IP address and time zone you already browse from. Sign in with Tailscale once from the Routing menu and the tunnel is saved; it uses no proxy credits. Browser profiles arrive alongside: named sets of saved logins, each with its own exit location, so the logins of one client never mix with another's. You can also bring logins in from a cookie file or a Playwright session. - **Context:** Tailscale Tunnels are in beta. Install Tailscale on a computer that stays on, make it an exit node, then open Routing in Cloud, choose Add a proxy or Tailscale tunnel, then Tailscale, and press Sign in with Tailscale. The tunnel is saved as Home via Tailscale: pick it for one chat or make it your default, and a schedule made from a run keeps its route. Sites see your connection's IP, and the browser's time zone and language match your exit node. ([Tailscale tunnels guide](/docs/tailscale)) - **New:** Safe by design. The cloud browser cannot open your router, printer, NAS or any other device on your network or tailnet; only public sites go through the tunnel. If your exit node is offline, the run stops before it starts and says why, and it never falls back to a data-center route. WebRTC stays inside the tunnel, so it cannot reveal the cloud server's address. Traffic uses your own connection, so it costs no proxy credits, and an OAuth client or auth key you connect with is encrypted and never shown again. - **Improved:** Beta limits. A tunnel you signed in with runs one task at a time; connect with a Tailscale OAuth client for parallel runs. The exit node has to stay on and awake, pages load at your upload speed, and the rtrvr device's key expires after 180 days unless you turn off key expiry for it in Tailscale. ([Read the launch post](/blog/tailscale-tunnels-home-ip)) - **New:** Browser profiles. A profile is a named set of saved logins with its own exit location, such as one per client. A run on a profile reads only that profile's logins and starts signed out everywhere else, and a sign-in made during the run is saved back to it. Default keeps working as before: the logins Cookie Sync uploads plus the sign-ins saved during cloud runs. Switch, create, rename and delete profiles from the Logins chip under the composer, and set your account default there. Free on every plan. ([Browser profiles guide](/docs/profiles)) - **New:** Bring your logins in. Import a Playwright storage state, a cookies.txt file or a Cookie header into Default or into a profile, from the Logins menu or over the API. A profile's cookie values are encrypted with that profile's own key, and the API lists names only: values are never returned and there is no export. - **Improved:** For AI apps and the API: manage profiles at /v1/profiles with the same API key as /agent and /scrape, and pass profile on /agent or on the MCP cloud_agent tool to run on one. ## v62: Fewer Continue pauses, every run says how it ended, and counts you can trust. *October 24, 2026* Extension 38.2.3 is rolling out on the Chrome Web Store, and Cloud, the API and the website update with it. A run now pauses for Continue only after 4 rounds in a row without progress, so long tasks that are still working keep going. Every run says how it ended: a run that kept what it had and stopped short is Partial, not an error, and a run whose side panel closed or whose extension restarted is recorded instead of disappearing. Each browser step now lists what its calls really did, so a task that reloads a page 8 times reports 8. A run that only read a page ends with an answer on more pages, Stop takes seconds even while a script is waiting, a resumed Cloud run shows its whole cost, and a file saved to rtrvr Files comes back with its link. - **Context:** Extension 38.2.3 is rolling out on the Chrome Web Store, and Chrome installs it on its own. It carries the extension side of this release: the new Continue rule, Partial and abandoned run endings, honest step counts, answers on more page-read runs, faster Stop, whole page reads when a script reads one tab several times at once, and a stricter tab filter for AI apps. Nothing in it needs new permissions. - **Improved:** Fewer Continue pauses. A run now pauses for Continue after 4 rounds in a row with no measurable progress, where it used to pause after 2, and the 40-round ceiling stops only a run that has stopped making progress. A run that never makes progress still pauses after its 5 free rounds, as before. Replaying a week of runs with the real pause logic, Continue clicks fell 54% and the share of tasks that needed a click went from 9.2% to 4.2%; after a first Continue, most runs had gone on to finish. Every pause now also records why it fired. In Cloud and in the extension; needs extension 38.2.3 in the extension. - **Improved:** Every run says how it ended. A run that kept what it had and stopped short ends as Partial, and the side panel says Partial result instead of Error. A run whose side panel was closed, whose extension restarted, or that another task replaced is now recorded as abandoned instead of sending no ending at all; on October 23 that was about 1 in 5 extension runs. A Cloud, API or MCP run that stopped short is recorded as partial too, and the schedules panel shows a partial run as its own state, not a failure. Needs extension 38.2.3 in the extension. - **Fixed:** Counts you can trust. Every browser step now ends with what its own calls did, such as "refresh_page ran 4 times; refused, not run: 1", whether it finished, stopped short or was stopped by the repeat guard, and the planner counts from that instead of the step's own summary. Asked to reload a page 8 times, a run that split the work across two steps used to report 4; it now reports the 8 that ran. In Cloud and in the extension; needs extension 38.2.3 in the extension. - **Fixed:** A run that only read a page ends with an answer on more pages. The check that spots a raw page read now recognises pages whose only element ids are on links, such as an author's page on a quotes site or most article pages, so a run that returns only what it read is held for one review that writes the answer, instead of returning the page. A one-pass Cloud run gets the same review. In Cloud and in the extension; needs extension 38.2.3 in the extension. - **Fixed:** Stop takes seconds while a script waits. A run stopped inside rtrvr.waitFor or rtrvr.waitForUrl ends at the next check, where it used to take about 40 seconds, and a stopped Cloud run's card shows its final credits. In Cloud and in the extension; needs extension 38.2.3 in the extension. - **Fixed:** A resumed Cloud run shows its whole cost. After you answer a question a run asked, its card, live credits, end line and stored record add the phases before the pause; before, a run that cost 4.08 credits could show 2.31. Billing was always correct. - **Fixed:** Files saved to rtrvr Files come back with their link. A Cloud run that saves a file to rtrvr Files gets the file's id and link in its result and gives you that, and it never opens rtrvr.ai's own app in the cloud browser to look for it; one run had waited 5 minutes on a sign-in page there. A plan told to save to rtrvr Files no longer saves to Google Drive. - **Improved:** Page reads hold up. In the extension, a plan script's own page read now waits for an app such as Google Maps to draw, as Cloud's does. Several reads of one tab at the same moment each get the whole page, where most used to come back broken, and a new tab is read once it has left its blank starting page. In Cloud and in the extension; needs extension 38.2.3 in the extension. - **Improved:** A click that does nothing says so. When a click had no effect because the element wants another gesture, the hint now starts with "your click did nothing: this target expects a drag" (or a double click, a choice from a list, a scroll) before the call to make, so the agent stops retrying the click. In Cloud and in the extension; needs extension 38.2.3 in the extension. - **Fixed:** Free Mode on shared networks. Accounts signed in with Google no longer count toward or get refused by the per-network account limit, so students and coworkers on one school or office network each keep Free Mode; on the website this needs the browser to pass Free Mode's device check. When the network is the reason for a refusal, the message now says network instead of device. Live since October 23. - **Fixed:** AI apps see only the tabs they ask for. Over MCP, get_browser_tabs with a domain filter returns only matching tabs; it used to add your active tab even when it did not match. Needs extension 38.2.3. - **Improved:** For AI apps and the API: a page the cloud browser's network route refuses, or a page that cannot be read, answers 422 instead of a server error; a tool that ran in your browser and failed answers 424 device_tool_failed over the Direct API, while a browser that does not respond keeps its 503; a call refused for a zero balance carries a Retry-After that grows while the key keeps retrying; and a prewarm that gives way to a real run answers 409. - **Fixed:** Smaller fixes. A pause at a run's credit limit no longer says a result came back with it when none did, and the tab list you resume with is current. Run records keep every step even when a script fires many calls at once. Background-tab notes reach the planner only when a page really drew less there. Cloud no longer warns about too many listeners on long sessions. ## v61: The planner stops second-guessing itself, rich editors keep their formatting, and Google Sheets stop asking for access. *October 23, 2026* Extension 38.2.2 is live on the Chrome Web Store, and Cloud, the API and the website updated with it. The planner, in Cloud and in the extension, gets one clear rule for each question it used to re-decide on every pass, so long tasks spend less of their thinking going in circles. Text the agent types into rich editors such as Wix, ProseMirror, Tiptap or Quill keeps its headings, bold and links. Google Sheets stop asking for access on every run, a sheet Google refuses gets a one-click Grant access fix, and a schedule that keeps failing on the same sheet pauses and tells you. A model answer cut off mid-stream is sent once more instead of ending the run, earlier results stay readable across replays and retries, and the extension no longer waits on its own record keeping between steps. In Cloud, every page read waits for an app such as Google Maps to draw, so a page opened partway through a run is no longer read as its empty shell. - **Context:** Extension 38.2.2 is live on the Chrome Web Store, and Chrome installs it on its own. It carries the extension side of this release: formatted typing into rich editors, Google Sheets access that stays granted and the Grant access notice, Private Mode in the model menu, Tools menu runs on Free Mode, clearer step records for the planner, and steps that no longer wait for the local record of the last one. Nothing in it needs new permissions. - **Improved:** The planner stops re-deciding the same questions. Reviewing 134 extension planner traces and 60 Cloud ones, we found much of the heaviest reasoning going to questions the instructions left open on every pass: whether earlier decisions still held, where a question to you belongs, when a script may finish the task, how much one act should take on, how sure a match must be. In Cloud, re-reading and re-deciding earlier passes alone took 23% of GPT-6 Luna's reasoning on its heaviest passes. Each question now has one rule: an earlier step's decisions stand unless a new result contradicts them; an approval you gave covers later steps of the same kind on the same target; a blocker only you can clear gets one question, and the task then finishes with what it has; the agent keeps going while a source it has not tried can still add what you asked for; and the bar for a match is set once and kept. The agent also judges up to about 50 items it can already read itself, in the same step, instead of sending them to another model call. In Cloud and in the extension. - **New:** Formatted text reaches rich editors. When the agent types into a rich-text editor such as Wix's blog editor, ProseMirror, Tiptap or Quill, it can paste formatted text: headings, bold, italic, links and lists arrive as formatting instead of plain paragraphs, and the step says which kinds of formatting landed. A Google Doc can be read through Drive and pasted with its formatting. Before this, a Cloud schedule posting a Google Doc to a Wix blog lost every heading, bold run and link on all 17 of its runs; in our tests a pasted Doc kept them on Wix's own editor. Plain typing into these editors now replaces their content instead of landing at an old cursor position. In Cloud and in the extension; needs extension 38.2.2 in the extension. - **Fixed:** Google Sheets stop asking for access on every run. When Chrome itself was not signed in to Google, or in Edge or Brave, the extension's Google access came from a one-hour token that was never renewed, so the access prompt and then the sheet picker reopened on every run. It now renews quietly, counts access you already granted, and checks a sheet with the Google account the run reads it with. When Google still refuses a sheet, the side panel, the Cloud run card and the error message offer Grant access, which opens the Google picker on that one sheet. Needs extension 38.2.2 in the extension. - **New:** Schedules check the sheets they name. A schedule now checks every Google Sheet its task names, when you save it and before each run, and saving lists any sheet it cannot open with a Grant access link. After 3 runs in a row refused on the same sheet, the schedule pauses and emails you a one-click fix. Before, it ended partial every day without telling anyone: one daily schedule did that from October 15 to 21. In Cloud. - **Fixed:** A model answer cut off mid-stream is sent once more. When a provider's response stream broke partway, the step ended with The model response was interrupted and the run stopped: 19 Cloud runs from October 7 to 21, one of them a scheduled article that never got its Google Doc. Now the call is sent once more, to the same provider when its answer had started or to the next provider of the same model, never to another model, and the cut attempt bills only what the provider reports. In Cloud and in the extension. - **Improved:** Cloud reads apps after they draw. Every page the Cloud agent reads, not only a run's first, now waits up to 5 seconds for a single-page app such as Google Maps or LinkedIn to draw, once per page and inside the read's own time budget, and so does a plan script's own getPageTree read. Before, an app opened partway through a run was read as its empty shell, so the agent spent a step waiting or an extraction came back empty. In the first 8 hours after the update, a Cloud run's first page read came back empty 7% of the time, against 14 to 15% before. In Cloud; the extension already waited this way. - **Improved:** Earlier results stay readable. `rtrvr.priorResult(id)` now numbers results in the order a script makes its calls, so an id no longer points at a different result from one run to the next, a replayed shortcut reads the results its earlier scripts stored, and a resumed, retried or continued task never reads a newer result under an old id. A replayed shortcut in Cloud also hands each script the variables the script before it saved, and a pass that failed the first time is not replayed: its repair runs instead. In Cloud and in the extension; needs extension 38.2.2 in the extension. - **Improved:** The planner's record of each step is clearer. A call that answered with a failure is now marked failed, with its error code, instead of done; a step that saved no data for the next one says so; and the record leads with the progress the script reported and which of its calls failed. When the agent's own finish is held for one review of the sheet it wrote, it is told why and how to finish. In Cloud and in the extension; the extension's record needs 38.2.2. In the extension, a tab the agent reads in the background also says why it counts as background: another tab is active in its window, or the window is minimized, covered or not focused. - **Improved:** Steps start sooner in the extension. Before each call to rtrvr, the extension waited for its local record of the step to be saved; that record is now saved while the next step runs, still in order and with nothing dropped. Needs extension 38.2.2. - **New:** Private Mode moves into the model menu of the side panel, right under Free Mode. Turning it on turns Free Mode off and says so. Needs extension 38.2.2. - **Fixed:** On the free plan, a Tools menu tool that uses AI runs on Free Mode with its own sponsored card, shown in the tool's window while it runs. Before, such a tool failed with Free Mode is unavailable unless a task was running beside it. Needs extension 38.2.2. - **Fixed:** The agent submits only when you ask. A task to fill in a form, type text or draft a message now stops before Send, Submit or Post and leaves that click to you; before, a draft-only task could click Send. In Cloud and in the extension. - **Improved:** An action that keeps getting the same result is stopped. When the agent is about to make the same call a 5th time and every earlier try came back the same, or keeps switching between two calls that undo each other, that call is not run: the agent is told why, such as the same page loading again or the same error, and what to try instead, and asking for it once more ends that browser step as incomplete. A background tab is named as the cause only when its page really drew less there. In Cloud and in the extension; needs extension 38.2.2 in the extension. - **Fixed:** Browser shortcuts are refused with the tool that does the job. A key the agent presses lands in the page, so Ctrl+R, F5, Ctrl+T or Alt+Left never reached the browser, yet the step came back as a success: asked to refresh a page six times, the agent counted presses that reloaded nothing. Now such a press fails and names the tool to use, such as goto_url with action reload, and Backspace, Delete, the scrolling keys and Ctrl+A do what a real keystroke does. In Cloud and in the extension; needs extension 38.2.2 in the extension. - **Fixed:** The agent reads text in ProseMirror editors, Tiptap among them. Reading the page made these editors redraw their content, so the agent saw an empty text box and called the editor blank. Reading now leaves the editor's content untouched, and its headings, text and links show up. In Cloud and in the extension; needs extension 38.2.2 in the extension. - **Improved:** A run that only read a page leads with its answer. When a plan script reads a page and the agent answers from what it read, the run's result is that answer, over the API and MCP too, instead of the page's whole tree and every link on it. The Cloud run card and the Result tab put the answer first and keep the page data one click away, and a partial run names the page that failed. In Cloud and in the extension; needs extension 38.2.2 in the extension. - **Fixed:** Extraction-only tasks finish when they are done. The extension held a finished task for one more review of a Google Sheet whenever it had extracted data, even data kept only in memory, so 46 of 206 held finishes in one week went back for a review with no sheet to check. Now only a sheet the task wrote or read holds it, and the review shows an extraction's header row as its header. Needs extension 38.2.2. - **Fixed:** Smaller fixes. An answer never carries a link placeholder the page could not fill: a field meant to hold a URL from the page, when the page had none, is left empty and named in the answer. Over MCP, a free account's saved tool and webhook trigger get the paid-plan notice instead of starting a Cloud run. Rover's planner never rejects a visitor's complete answer for a missing receipt, and visitors no longer see an internal retry error. In the Cloud composer, the Cookies, Tools and Models pickers can use the window's full height, so the Cookies site list shows about three times as many sites and Tools about twice as many rows. A page title cut mid-emoji no longer loses that step's page record in Cloud. Every Cloud charge made through an API key, MCP, a webhook, a schedule or WhatsApp is now recorded against its run. Cloud and its live view run on Node.js 22 with the latest security fixes. - **Context:** Site guidance gets its monthly review: 51 site skills refreshed from a month of runs and recordings, and 16 new ones, among them coursework platforms. ## v60: The agent finishes what it starts, Retry picks up where a run stopped, and results reach your inbox. *October 21, 2026* Extension 38.2.1 is live on the Chrome Web Store, and Cloud, the API and the website updated with it. The agent keeps working until the task is done: a reply that only announces its next step is sent back to do that step, and after you press Continue a run is no longer paused again while it is still making progress. Retry with note and follow-ups continue from what the stopped run finished instead of starting over, in Cloud and in the extension. Clicks land in background tabs while Chrome is on screen, on buttons a page wires up after it loads and in math fields. Schedule emails now carry the results, a Cloud run you ask to email you does, and every run reads today in your own time zone. Scheduled runs longer than 5 minutes, runs that hit their credit limit and public PDF links all behave, Sheets runs only change the rows they wrote, Private Mode keeps screenshots and files in your browser, and Inkling models bill 99% off. - **Context:** Extension 38.2.1 is live on the Chrome Web Store, and Chrome installs it on its own. It carries the extension side of this release: background-tab clicks, Retry with note continuing a run, fewer pauses after Continue, public document links, math fields, Private Mode files kept in your browser, and smaller uploads. Nothing in it needs new permissions. - **Improved:** The agent keeps working until the task is done. When a planning step ends with a reply that only announces what it will do next, such as "I'll now open each profile", the agent is sent back to do it instead of the run ending there; across 1,266 runs that ended on a written reply, the check caught 35, and 28 of the 30 we read had stopped right after a promise. A long task's 45-minute stretch is no longer read as its end, and the agent is told to serve the goal behind your words, so a task that asks for a button that is not on the page opens the menu that holds it. In Cloud and in the extension. - **Improved:** Fewer pauses once you press Continue. After you answer a pause with Continue, rounds that make no visible progress no longer pause the run again, and a round that adds 3 or more new lines to the page counts as progress; a repeated script, the run's time limit and its credit limit still pause it. Replaying the Continue clicks of 451 runs from October 5 to 18, pauses fell by 42% and runs that paused 3 or more times went from 113 to 1. In Cloud and in the extension; needs extension 38.2.1 in the extension. - **New:** Retry continues, it does not restart. Retry with note on a run that stopped or failed carries on from the progress that run had saved instead of planning from scratch: in Cloud from a checkpoint the run leaves behind, and in the extension for up to 2 hours. A plan that works through a list records which item comes next, so continuing picks up there, and a follow-up in the same chat hears what a stopped, failed or paused run finished. Stop gives a running script up to 40 seconds to save the sheet rows it was writing, and asking a run to stop and hand over what it has gets you the deliverable built from what it collected so far. A Cloud follow-up that names no page starts on the page the previous run ended on, with a note in the chat saying so. Needs extension 38.2.1 for Retry with note in the extension. - **Fixed:** Clicks land in background tabs. Chrome draws nothing in a tab you are not looking at, so a click whose effect shows on the next frame read as no effect, and the agent clicked again, closing the menu it had just opened: 185 of 357 such clicks from October 18 to 20 were in background tabs. Now, while the Chrome window is on screen, the agent shows that tab for a moment without taking focus from your window, checks the first click there, and puts your previous tab back. In our test, a menu that took 2 clicks and 2 seconds and ended closed now opens with 1 click, confirmed in 0.3 seconds. Needs extension 38.2.1. - **Improved:** More of the page is clickable, and a dead click says what to try. Buttons a page wires up after it loads, through jQuery or as plain elements that only show a pointer cursor, are now click targets: on a Bubble app's page, 47 of 47 such buttons, against none before. When a click does nothing because the element wants another gesture, such as a drag to rank, a double click, a custom dropdown or a picker wheel, the agent is told which one. The agent also sees which field has focus when its tab is in the background or you are in another window, where 230 of 474 focus steps looked like nothing had happened. After three actions in a row that leave the page exactly as it was, the agent gets a note on what it tried and where to look next; it is a note, never a stop. In Cloud and in the extension; the extension half needs 38.2.1. - **New:** Results reach your inbox. A schedule with email turned on now sends the run's answer, its rows as a table and links to the Sheets, Docs, Slides and pages it wrote, instead of only saying it finished, and Slack and Discord get a summary too. In a Cloud run, ask to have the results emailed and close the tab: when the run finishes, they arrive at your account's verified email address, once per run. A scheduled run sends only its schedule's email, so asking in the prompt as well does not send two. - **Fixed:** Today means your today. Every Cloud run you start on the website now carries your browser's time zone, and a scheduled run carries its schedule's, so the agent reads today, yesterday and the last 24 hours on your clock instead of the cloud browser's. Before, a run started in Melbourne read today as the day before. - **Fixed:** Scheduled runs longer than 5 minutes are tracked to the end. Since October 16, every scheduled run that worked past 5 minutes lost contact with the scheduler at that mark, 5 of 5, while the run itself carried on, so its status could be wrong. A schedule whose run could not start because a lookup on our side failed now says it did not run and used no credits, tries again, and no longer counts toward pausing the schedule. In Cloud. - **Fixed:** A run that reaches its credit limit ends as Partial. It keeps what it did, says Stopped at this run's credit limit with the number of credits, where it was shown as Task Cancelled by User. Your own Stop still reads as cancelled. Over the API, such a run's webhook is rtrvr.execution.failed with status partial instead of rtrvr.execution.cancelled. In Cloud. - **New:** Public documents read from their link. readFile, searchFile and file inputs in plan scripts now take a public link to a PDF or other document: in the extension your browser downloads it into the run, up to 25 MB, and in Cloud the cloud browser does. A fillable PDF form gives the values typed into its fields under their printed labels instead of an empty form, and a scanned page is read with OCR. Before, a link answered No attached file matches, and some government sites refuse downloads from anything but a browser. In Cloud and in the extension; needs extension 38.2.1 in the extension. - **Improved:** Sheets runs only change the rows they wrote. A task that works through a list adds each row as it reads that item, so a run that stops early keeps every row it finished; in Cloud, a run about to end without writing to a sheet you made required gets one more pass to write first; and fixes and follow-up passes may change only the rows this run wrote, never your older rows. In Cloud and in the extension. - **Fixed:** Private Mode keeps your files in your browser. With extension 38.2.1, screenshots, generated images, PDFs, webpages and filled-in forms come back inline and nothing is stored on our side. On every extension version, a message sent after you stop a run no longer fails before it starts because a file was missing. - **Context:** Inkling and Inkling Small bill 99% off Tinker's list price: $0.01 per million input tokens, $0.0017 cached and $0.0405 output for Inkling, and $0.003, $0.0006 and $0.012 for Inkling Small. The model pickers in the side panel and the Cloud composer show a 99% off chip, with the list price on hover. ([Compare models](/models)) - **Improved:** Models and search. DeepSeek Flash on Merge now runs DeepSeek V4.1 Flash 1017, the newer build, at the same price. When a provider's content filter cuts a reply short, rtrvr treats it as that provider refusing and tries the next provider once, and on your own key the error says so; before, about 160 steps from October 7 to 16 ended as a success with a cut-off answer. Web search results from Liner now respect site: and -site: in your query, and a list left empty moves on to the next provider. - **Fixed:** Math fields and drawn surfaces. Typing into a math editor such as Desmos or DeltaMath goes in key by key and counts only when the equation on screen changes, keys report what they typed, and punctuation keys type the right character. Taps and drags reach shapes drawn in SVG, such as a music editor's note grid. In Cloud and in the extension; needs extension 38.2.1 in the extension. - **New:** Crawls in Cloud get the crawl fixes the extension got on October 16: they keep paging up to the number of pages you set, reaching it counts as complete, each page's extraction reads only its own page, and a failed page is reported as an error instead of ending the crawl as if the listing were over. - **Context:** On the free plan, Cloud API calls made with an API key, the MCP Cloud tools (cloud_agent and cloud_scrape, and agent or scrape when they run in Cloud), WhatsApp tasks and the extension agent's Cloud steps now need a paid plan. Free Mode covers the tasks you start in the extension or the Cloud dashboard, and the browser tools your own AI drives over MCP stay free on every plan. An API key stops working when its owner's account is deleted or disabled. ([See plans](/pricing)) - **Fixed:** Smaller fixes. Sign-in checks on Bubble sites no longer take a visitor id for a login or miss a live one, in Cloud, in the extension and on the website. A wildcard host such as *.example.com stays text in the Cloud composer instead of becoming a start URL, and Cloud answers TARGET_UNREACHABLE for one instead of failing. Plan Timeout in the extension takes whole minutes from 1 to 60 and says it limits one plan script, not the whole task. A Cloud run that stops to ask you something no longer fails with a server error when its browser is briefly stuck: it asks, and picks up on the run's starting page. A Jev step that never answers ends at its own time limit, unbilled, instead of holding the run for 15 minutes. The extension compresses what it sends to rtrvr, so a page read is several times smaller on the wire. A model's thinking tags no longer show in the side panel or in Cloud. - **Improved:** For AI apps and plan scripts: the context field of an MCP planner call now reaches the agent, where runs in your browser ignored it; a Cloud tool called with too few credits answers MCP error -32007 or REST 402 with the credit numbers behind the refusal; upload_file answers 422 FILE_FETCH_FAILED with the host and reason when its source URL cannot be fetched, instead of 500; and a later plan script can read an earlier act, extract or crawl result in full with rtrvr.priorResult(id). - **Context:** Simulations v2: approved results on all 113 tasks, with re-recorded reference runs. Claude Opus 5.5 solved 92.9% at $17.79 an episode at list price, GPT-6.1 Sol 90.3% at $3.54, and DeepSeek V4 Flash at Max reasoning 62.4% at $1.38. ([Explore Simulations](/simulations)) ## v59: GPT-6 Luna and Sol keep their train of thought, the agent gets faster, and your AI drives your browser on every plan. *October 16, 2026* Extension 38.2.0 is live on the Chrome Web Store, and Cloud, the API and the website updated with it. GPT-6 Luna and GPT-6.1 Sol now carry their reasoning from one step to the next instead of losing it at every step, so expect much better results from them: in our multi-page tests, Luna finished 11 of 15 runs, against 1 of 4 before. The agent is faster: Luna and Sol answer from Amazon Bedrock first, its instructions are about 30% shorter, it works with 18 page tools instead of 41, and it reads a page once the page has drawn. Claude, ChatGPT, Cursor and other MCP apps can drive your browser with rtrvr's browser tools on the free plan too. In Free Mode, Run in my browser sends a Cloud task to your own Chrome for free. Quick settings in the Cloud composer set how long a run works and whether it may fall back to another model, and the models page shows how each model is routed. Crawls finish every page you ask for, the agent asks you to sign in only when it must, a key of yours that stops working is paused instead of failing every step, and a long list of fixes from your reports is in. - **Context:** Extension 38.2.0 is live on the Chrome Web Store, and Chrome installs it on its own. It carries the extension side of this release, including the browser tools your own AI can drive on every plan, Free Mode runs sent from Cloud to your browser, crawls that finish every page, the sign-in checks, Stop ending a run's model calls on the server, and the side panel's chat order and run clock fixes. - **Fixed:** GPT-6 Luna and GPT-6.1 Sol keep their train of thought. Each step's reasoning was dropped before the next step, so on a task spanning several pages these models lost what they had worked out on the earlier ones. Now every step's reasoning carries into the next, for Luna and Sol on rtrvr's route and for OpenAI models on your own key or ChatGPT sign-in, so a value the model noted on one page is still there after it moves on. In our multi-page test tasks, GPT-6 Luna finished 11 of 15 runs, against 1 of 4 before: expect much better results from Luna and Sol. In Cloud and in the extension. - **Improved:** The agent is faster. GPT-6 Luna and GPT-6.1 Sol answer from Amazon Bedrock first, where a page action took 1.2 seconds in our benchmark, against 3.0 on Azure, which served Luna first until now. The page-action prompt is about 30% shorter in Cloud and in the extension, with each rule stated once and the rules for LinkedIn, Zillow, Crunchbase, X, YouTube and flight booking sites loaded only on those sites, and with extension 38.2.0 the planner's prompt is 11% shorter too, so every step sends less. The agent picks from 18 page tools instead of 41, reads a page that is still drawing once it has drawn instead of spending steps waiting on it, and the slowest news searches finish in about 15 seconds instead of 67. - **New:** Your own AI can drive your browser on every plan. Turn on Enable Extension as MCP, now on the free plan too, and Claude, ChatGPT, Cursor or any MCP app can use rtrvr's browser tools, get_browser_tabs, get_page_data, take_page_action, scrape and your saved tools, with no call limit: your AI decides each step and rtrvr runs no model. The agent tools that run rtrvr's AI (planner, act_on_tab, extract_from_tab, crawl_and_extract_from_tab and replay_workflow) still need a paid plan, and so do take_page_action's AI actions, discover_and_extract_network_data and generate_image. The MCP panel shows the two groups as Browser tools and Agent tools. Needs extension 38.2.0. ([MCP docs](/docs/mcp)) - **New:** Run in my browser works in Free Mode and follows the whole run. In Free Mode, a task you send from Cloud to your own Chrome is now free on the sponsored card the page already showed you; when today's free allowance is used up, the card says the run uses credits. Such a run no longer fails at 5 minutes: the card shows its steps live, Stop works, a reload picks the run back up, a run that reaches its time limit keeps what it did, and a browser that does not answer is named, with Run in Cloud instead. When the agent's review pass answers your question, the card and MCP and API results end with that answer. With My browsers chosen and no browser ticked, the send stops and says so instead of running in Cloud. Free Mode runs in your browser need extension 38.2.0, and an older extension is asked to update. - **New:** Quick settings in the Cloud composer: choose how long a run works. Every Cloud run gets 15 minutes by default. On a paid plan with Free Mode off you can set Max run time from 5 to 55 minutes in the composer's new Quick settings, in Settings, or by asking the agent, and time spent waiting for your answer is given back. A run that stops on its limit says which limit it hit and how to get more time, and Continue gives it a fresh stretch. Free Mode runs are 15 minutes, and a scheduled run works up to its owner's Max run time, at most 27 minutes. - **New:** Disable fallbacks keeps a run on the model you chose. Turn on Disable fallbacks (only use the selected model) in Settings, in Quick settings, or per call over MCP and the API with disable_fallbacks, and rtrvr never moves the run to another model. When that model cannot answer, the run stops with MODEL_UNAVAILABLE, keeps what it already produced as a partial result, and the run card says why; Retry with fallbacks runs it again with them on. Web search is not affected. With fallbacks on, a model on your own key that fails runs on rtrvr's route for the same model first, then on GLM 5.3 Flash, and Gemini is never used as a fallback. - **Improved:** GPT-6 Luna and GPT-6.1 Sol run on Amazon Bedrock first and switch to OpenAI by themselves when Bedrock slows down. GLM 5.3 runs on OpenRouter's Sail Research with zero data retention, and DeepSeek Pro now runs DeepSeek V4 Pro there instead of a Flash model served from China. The models page now shows how each model is routed: every provider, in the order they are tried. ([Compare models](/models)) - **Fixed:** Crawls finish the pages you ask for. In the extension, a crawl keeps paging while the listing has a next page, up to the number of pages you set, and reaching that number counts as a complete crawl, not a partial one. Each page's extraction reads only its own page, and a crawl without a schema gets one column per field. A crawl into a Google Sheet shows the rows saved and an Open sheet link instead of an empty result. In our test, crawling the first 5 pages of Hacker News saved 150 rows in 6 columns in 1 minute 36 seconds. When a page's model call fails, the crawl reports the error instead of ending as if the listing were over, and crawls started from AI apps no longer stop after about 13 seconds, as they did on extension 38.1.9. The saved-collection options that came with 38.1.9 are retired, and a call that still passes them gets a clear error. Needs extension 38.2.0. - **Improved:** The agent asks you to sign in only when it must. Before it asks, it checks the site's tab and the login this browser holds for the site, and if you are already signed in it carries on without asking. After you click I signed in, it checks the page again, and if the sign-in form is still there it asks again and says the sign-in did not finish. Over 30 days, a quarter of the questions the agent asked in the extension were sign-ins. In Cloud, a site whose login the cloud browser already holds is not asked, Continue on an unfinished sign-in comes back titled Still signed out of the site, an answer to Google's sign-in check holds for the rest of the run, and a cookie that says you are signed out is no longer taken for a login. Needs extension 38.2.0 in the extension. - **New:** Your own model key is paused when it cannot work. When a key you added runs out of balance, reaches its provider's daily limit or is rejected, rtrvr pauses it for your account and skips it without a call, instead of failing on every step: a spent balance is tried again once an hour, a daily limit waits for the provider's reset, and a rejected key waits until you change it. The run carries on with rtrvr's route for the same model, or stops with MODEL_UNAVAILABLE when Disable fallbacks is on. The model picker, Settings and the side panel show Paused until with the reason, and let you Retry now, Resume, or pause a key yourself. In one week, a single key with no balance failed 3,892 times across 143 runs. In Cloud and in the extension; the side panel needs extension 38.2.0. Gemini keys keep their earlier handling. - **Fixed:** One address that does not exist no longer stops a whole Cloud run. A run or a cloud_scrape batch that held a domain with no DNS record was refused before any page opened, as Managed proxy routes unavailable: 18 of the 21 sites behind that refusal from September 29 to October 12 did not exist. Now only the page that asks for that address gets domain not found, and the rest of the run goes ahead. A site that a proxy provider refuses is tried once on each other route before the run answers TARGET_BLOCKED_BY_PROXY_PROVIDER, and a Cloud tool refusal over MCP or the API carries a request id you can send us. In Cloud. - **Improved:** Pages that draw themselves are read once they have drawn. When a single-page app still shows its empty shell, the agent's first read waits for it, and a page that never draws is reported as app_not_rendered instead of read as empty; MCP scrape and cloud_scrape say so too and suggest waitForSelector or pageLoadDelay. Cloud page reads keep every line of text and show page sections the way the extension does. Needs extension 38.2.0 in the extension. - **Improved:** The agent sees more of the page. Icon-only buttons and charts drawn in SVG reach it as compact drawings instead of bare buttons: in our test, GPT-6 Luna named 12 of 12 unlabeled icon buttons from the page read alone, and GLM 5.3 Flash clicked the right delete button. It reads everything a text field or code editor holds, so it can move a whole script into another field in one step, 300 of 300 lines in our test, and a field holding a very long value stays within its reach. Google Sheets tabs are read without touching your clipboard, in a background tab too and when you are signed in. In the extension, a Google Maps search is read with its results instead of as an empty page. In Cloud and in the extension; needs extension 38.2.0 in the extension. - **Improved:** Clicks and typing land more often. Custom dropdowns get a second try that matches the option's whole name, a letter or digit key is typed where the cursor is, a click waits up to 1.5 seconds for a disabled button to turn on, elements inside frames are reached, and picking the option already selected counts as done. A page action asked for in a form that cannot run as written, such as a triple click, is refused with the reason instead of running as something else. In the extension, every click watches for a late effect before it reports that nothing happened, and a long page task ends only after 3 failures in a row, not any 3 along the way. In Cloud and in the extension; needs extension 38.2.0 in the extension. - **Improved:** The agent works with simpler tools. Its page actions are 18 tools instead of 41: variants that take the same target, such as double click, hover, clear, back, reload or a new tab, ride one tool with a small option, which leaves smaller models less to get wrong. An element the page no longer resolves is found again and the action runs once more, and a control that only appears on hover is hovered first. In Cloud and in the extension. - **Improved:** A list of pictures is read where it is. When the items in a list are images, the agent describes them in one batch on the list page instead of opening each item, in Cloud and in the extension. - **Improved:** News and date-limited searches answer sooner. When Google has not answered a news search within 12 seconds, rtrvr moves on to Liner with the same date window instead of working through Google's retries, so more of these results now come from Liner's web results than from Google News. Replaying two days of news searches, the slowest one in ten finished in about 15 seconds instead of 67 in the extension, and 15 instead of 56 in Cloud. - **Improved:** Web search gets a third provider: Liner now sits between Bright Data and Merge. In our test of 60 production-shaped queries, Liner answered all 60, and a blind judge preferred its results to Merge's on 41 of 57. - **Improved:** The agent remembers your standing answers. When you answer a question that holds beyond the task, such as where results go or a default count, the agent saves it as one line in your general skill and checks there before asking again. Answers about the task at hand, sign-ins, files, passwords and payment details are never saved. The extension re-reads general before each task, so an edit made on the website or by a Cloud run reaches it, and the Skills panel no longer lists a skill the Cloud agent deleted. In Cloud and in the extension; the re-read needs extension 38.2.0. ([Skills docs](/docs/skills)) - **Improved:** Stop ends the work and the bill. Stopping a run in the side panel, over MCP, from the CLI, a schedule or WhatsApp now ends its model calls on the server, and the cancelled call bills 0 credits. Before, a stopped code plan could keep running on the server for up to 5 minutes and was billed in full, 2.39 credits for one run cancelled over MCP on October 9. Needs extension 38.2.0 for the side panel. - **New:** Claude 5.5 on your own Anthropic key. Claude Haiku 5.5 (recommended), Sonnet 5.5, Opus 5.5 and Fable 5.1 join the Anthropic list, newest first, in Cloud and in the extension. Claude 4.6 and every 5-generation model think adaptively at the reasoning level you pick, an answer can use the model's whole output limit instead of stopping at 8,192 or 16,384 tokens, and a long answer streams to its end instead of failing after 5 minutes. - **New:** Docs and Slides go into the Drive folder you pick. Ask for a Google Doc or Slides deck, choose a folder in the Drive picker, and rtrvr checks the folder before it writes, in Cloud and in the extension. - **Improved:** Your own site skills apply in full: a skill applied automatically now passes up to 20,000 characters to the agent instead of 6,000. - **Context:** GLM 5.3 Flash now shows the rate its first provider, Microsoft Azure, bills: $0.188 per million input tokens, $0.038 cached and $0.625 output, where $0.09, $0.018 and $0.30 were shown before. Calls Azure serves already billed this rate, and calls another supplier serves bill that supplier's rate. GPT-6 Luna is now the lowest-cost pick for everyday tasks on the models page. China routing now bills 90% off Z.ai's own list price instead of 90% off the shown price: $0.015, $0.003 and $0.05 per million for GLM 5.3 Flash, up from $0.009, $0.0018 and $0.03, and $0.14, $0.026 and $0.44 for GLM 5.3, up from $0.098, $0.0182 and $0.308. ([Compare models](/models)) - **Fixed:** The side panel keeps your chat in order. A prompt stays above its answer when the chat saves, so the sponsored card under it no longer disappears; saved chats keep their dates and are grouped by calendar day; and the run clock counts from this run's start, where a rerun read Running 48:56 a minute in. Free Mode says No credits used only when a task did not start, and says a run used credits only once billing confirms it. Each saved chat's Rename, Make a copy, Save to account and Delete sit behind one menu. Needs extension 38.2.0. In Cloud, history dates and the Free Mode card got the same fixes. - **Fixed:** Cloud run cards end the way the run did. A run the agent ended as partial finishes its card as partial instead of showing Running for 5 minutes and then could not start, and a run that ended while the page was away finishes its card when you come back. The live view of a new run streams again instead of sitting on Browser ready, starting stream, and the Tools page loads a large or partly unreadable tool list instead of failing with Tools failed to load. - **Fixed:** Cloud runs that wait for you behave. Cancelling a Cloud run while it waits for you frees its browser at once, so your next run starts; pausing a run no longer fails when a tab cannot be read; a Cloud script that reaches its time limit ends with what it did, without counting the time spent waiting for you; and a question asked after a sign-in shows on its own, with Continue task answering only sign-in pauses. - **Fixed:** Ratings are kept for every run, Private Mode included, and a wide advertiser logo on the sponsored card keeps its height instead of shrinking into a thin strip. - **Improved:** For AI apps and plan scripts: planner calls take max_steps, a hard limit on planning passes, and on an older extension max_steps runs without the limit and says so instead of being refused; page tools called without a tab_id act on the run's tab; a target whose CSS selector matched nothing says so; a saved tool you switched off in Tools is no longer listed or run, over MCP or in Cloud schedules; list_executions shows the credits a run on your browser used, where it read 0; act_on_tab's reply lists the actions it took; and take_page_action's wait_for_element fails when nothing appears and honors its duration. In plan scripts a Google Drive file works wherever a file does, readFile reads the file a generator just made and its matches carry the text of the matching line, and the Doc, Slides, webpage and PDF generators use the run's recording for context. A step whose return value is too large keeps its saved variables, each up to 32 MB, and no longer breaks the passes after it; a returned value that cannot be copied, such as a function, comes back as an error instead of hanging the run; and helpers that tasks looped on, such as extract with no data, say what to pass instead. Needs extension 38.2.0 in the extension. ([MCP docs](/docs/mcp)) - **Context:** Simulations: RL environments for signed-in SaaS apps. Twelve live, unbranded replicas of business software across hiring and HR, finance and purchasing, sales and support, IT and engineering, government services and workspace tools, with 100 long-horizon tasks of 60 to 300 actions, graded by deterministic checks on the final app state with no LLM judges. Tasks plug in through Harbor, an MCP tool server or a Gym API, and 75 are held out for hosted evaluation. The page publishes a five-model benchmark: Claude Opus 5.5 finished 97% of tasks at $18.78 an episode at list price, and DeepSeek Flash at Max reasoning finished 68.5% at $1.19. ([Explore Simulations](/simulations)) - **Context:** Retriever AI for GMI. A new page for GMI's AgentBox users shows how to research prospects, enrich leads and automate browser work with Retriever AI on GMI models, in Cloud, in Chrome, and over the API and MCP, and AgentBox tasks run only on GMI models. ([Retriever AI for GMI](/gmi)) ## v58: The agent checks its work, and every step starts sooner. *October 8, 2026* When a plan's script acts on a website, its own verdict no longer ends the task: the next pass reads the page and decides, in Cloud and in the extension. Steps start sooner: with extension 38.1.6 the agent waits less between steps and shows your answer before it saves the task, and Cloud tasks start sooner after you press Enter. In background tabs, the agent no longer gives up on a feed that will not load, and brings a tab to the front only when the page is missing something the task needs. Max reasoning gets more time, GPT-6 Luna rides out a busy Azure, big attachments and very large Cloud results no longer fail, ratings of side-panel tasks are recorded, and site guidance for LinkedIn, Indeed, Upwork, Fiverr and Facebook is refreshed, with new guidance for Freelancer.com. - **Improved:** The agent checks its work before it calls a task finished. When a plan's script clicked, typed or submitted something on a website, its own verdict, done, partly done or failed, no longer ends the task: the next pass reads the page and decides whether to finish, carry on with what is left, or say what blocked it. In the 7 days to October 8, 61 Cloud runs ended right after acting on a partial or failed verdict that nothing checked; in one batch, three Substack notes that had been scheduled were reported as not done. Scripts that only read pages still finish in one pass. In Cloud and in the extension. - **Improved:** The agent waits less between steps. Pages are checked for readiness every 100 ms instead of every 500, a page that stays half-loaded is read once it goes quiet instead of after every timeout, a link that only changes the page's address settles at once instead of after up to 8 seconds, and a plan no longer waits twice for a page it already opened. In our tests on the same pages, the time between two model calls fell from 4.0 to 3.6 seconds on average, and the first step on a freshly opened background tab from 5.6 to 4.0 seconds at the 90th percentile. Your answer now shows before the task is saved, and the sponsored card after it is requested the moment the run ends. Needs extension 38.1.6. - **Improved:** Cloud tasks start sooner after you press Enter. Everything that does not depend on the sponsored card now runs alongside it instead of after it: your credit check, the chat's earlier runs, saving your message and opening the live view. In our local test, the run request went out 1.1 seconds after Enter instead of 2.8. - **Fixed:** The agent no longer gives up on a background tab that will not load. When a scroll does nothing in a tab behind your window, the agent is told why and brings the tab to the front once, and a background page that shows no sign of more content is no longer described as the whole page. In our test, a task reading the first 15 posts of a LinkedIn feed in a background tab got all 15 instead of stopping at 3. The agent also brings a tab to the front only when it is missing content the task needs, not just because the tab is in the background: after v57, 66 of 374 tasks on healthy background tabs did so on their first step. In the extension. - **Improved:** Max reasoning gets room to think. A planner step at Max now gets up to 6 minutes instead of 4 and never starts with less than 2.5 minutes left, and when one runs out of time, the next try goes one level lower instead of resending the same request. On October 7, 7 of 11 Max planner steps in Cloud ran out of time, and 6 of them were sent again unchanged. In Cloud and in the extension. ([Compare models](/models)) - **Fixed:** GPT-6 Luna rides out a busy Azure. When Azure's GPT-6 Luna capacity is used up for a moment before a step starts answering, rtrvr waits up to 2 seconds and asks again, or moves just that step to the next provider, and the run's next step goes back to Azure. Before, such a step ended the plan or moved the run to OpenAI for good: within half an hour on October 7, 3 planner steps ended that way and 9 page actions moved. In Cloud and in the extension. - **Fixed:** Big attachments and unusual Office files are read. A task with many attachments no longer fails with an internal error while rtrvr checks what each file is, as one with 98 attachments did on October 7, and an Excel, PowerPoint or Word file that contains a character reference outside Unicode, such as �, is read with that text as written instead of being reported unreadable. In Cloud and in the extension. - **Fixed:** Very large Cloud results are saved. A Cloud run whose result is larger than 1 MB is saved, with its largest parts stored beside it, instead of failing to save while reporting success, as three large scrapes did on October 7. A run whose result truly could not be saved now says so. - **Fixed:** Ratings of side-panel tasks are recorded. Since October 5, rating a task you ran in the side panel on a model rtrvr provides was refused as unfinished; now the rating is kept with the task, and Run via API can turn such a task into an API request instead of answering Execution not found. - **Improved:** Page actions from AI apps wait for a busy browser. take_page_action now waits for your browser to finish its previous command instead of being refused as busy, as 50 of 332 calls were on October 7, and over MCP both it and get_page_data wait up to 15 seconds, up from 5. ([MCP docs](/docs/mcp)) - **Improved:** On the free plan, a task that asks for a schedule, a trigger, MCP or Cookie Sync still gets done: the agent does the work once now and says in one sentence which plan the feature needs, with a link to pricing, instead of ending on the paid-plan error. In Cloud and in the extension. ([See plans](/pricing)) - **Improved:** Site guidance is refreshed for LinkedIn, LinkedIn Jobs, Facebook, Indeed, Upwork and Fiverr, and new for Freelancer.com, from what worked and what failed in recent tasks. On Indeed, a disabled Submit after Preparing review is not a CAPTCHA, so the agent waits and submits, where 17 of 22 tasks that saw it gave up; on Facebook, an empty page read usually recovers on the next read, as it did 244 of 350 times. Substack guidance finds a scheduled note by its time and refuses a time in the past. - **New:** New extension users land in Cloud. With extension 38.1.6, the first time you sign in on a new install, Cloud opens signed in as the same account, with a short welcome, so you can start a task that keeps running after Chrome closes. Installs that were already set up are not sent there after the update. ## v57: GPT-6 Luna gets faster, and Free Mode tasks start sooner. *October 7, 2026* GPT-6 Luna now runs on Microsoft Azure first, where a planner step took about 3 to 4 seconds in our tests, and Auto runs GPT-6 Luna and GPT-6.1 Sol at Medium reasoning. Free Mode tasks no longer wait for the sponsored card before they start, in Cloud and in the side panel. The agent recognizes a page that did not load at once instead of reloading it, and going to a page now waits for that page. AI apps connected over MCP get rows under their own field names, a Google Sheet only when they ask for one, failed runs that say they failed, and the model you selected even with Free Mode on. The agent can also look up LinkedIn profiles by name, and phone numbers no longer turn into #ERROR! in Google Sheets. - **Improved:** GPT-6 Luna runs on Microsoft Azure first, with OpenAI and then Amazon Bedrock as backups. Planner steps gain the most: in our tests on October 7 they took about 3 to 4 seconds on Azure, several times faster than on Bedrock, which ran them first until now. When Azure slows down, new runs start on OpenAI until it recovers, and runs already under way keep going. ([Compare models](/models)) - **Improved:** Free Mode tasks start sooner. A task no longer waits for the sponsored card: it starts as soon as your Free Mode session is confirmed, and the card appears when it is ready. In the side panel, your credit check and the agent's first look at the page also begin the moment you press Enter, where before they waited for the card, which took 1.4 seconds at the median in production. In Cloud, a chat's earlier runs load while the card is chosen. Every model call also makes fewer database round trips before it starts, and site guidance no longer holds up a step while it refreshes. Needs extension 38.1.5 for the side panel. - **Improved:** GPT-6 answers sooner on Auto. Auto now runs GPT-6 Luna and GPT-6.1 Sol at Medium reasoning on every plan instead of High on paid plans; in production, paid GPT-6 Luna tasks at High took about 45 seconds longer. In Free Mode and on the free plan, GPT-6 Luna's page actions run at Low, which took 1.9 seconds at the median against 4.0 at Medium in production, with no measurable difference in results. Off on GPT-6 Luna now really turns reasoning off, and Max on GPT-6 Luna and GPT-6.1 Sol runs at max instead of high. The Auto tooltip says so in Cloud, and in the extension with 38.1.5. - **Improved:** The agent knows when a page did not load. When a tab shows Chrome's error page, for example for an address that does not exist, the agent is told at once that the page did not load and why, and goes to an address that works or tells you. Before, it spent a page read on such a tab, then brought your window to the front and reloaded, which took 38 seconds and 0.60 credits in one MCP run on October 7. Other open tabs, browser pages and empty tabs are labeled the same way, including in get_browser_tabs, get_page_data and scrape, and a task that says it opened a page that did not load gets one more check. Needs extension 38.1.5 in the extension. - **Fixed:** Going to a page waits for that page. Opening an address, a Google search, or a reload now waits until the new page has replaced the old one, so the agent no longer reads the page it was leaving as the one it opened. In Cloud, a page that loaded is no longer reported as a failed navigation, a failed visit to a dead address is no longer shown with the previous page's content, and a new tab waits past its blank start page. Needs extension 38.1.5 in the extension. - **Improved:** Fewer plans are thrown away over formatting. When the planner puts notes above its script, wraps it in extra markup, or leaves a stray code fence, rtrvr recovers the script in the same request instead of asking the model for a new one. In a replay of recent planner output, 203 of 288 rejected Cloud plans and 29 of 156 rejected extension plans are now accepted, and in the extension each one saves a retry of about 8 seconds at the median. A reply that only describes the plan is never shown as the task's answer, and when a backup model rescues a plan that ran out of time, a mistake in its first plan gets the usual retry instead of ending the run. In Cloud and in the extension. - **Improved:** Extraction requested by AI apps and the API returns what you asked for. extract_from_tab and crawl_and_extract_from_tab key rows and sheet headers by the field names and types you list, act_on_tab and planner calls receive your fields too, and schema reads Applied only when your fields were used. A Google Sheet is written only when the call asks for one, with output_destination type google_sheet or a sheet id or title; otherwise the rows come back in the reply. Before, every call wrote a new sheet when Google was connected. Needs extension 38.1.5 for the sheet change. ([MCP docs](/docs/mcp)) - **Fixed:** AI apps see how a run really ended. An extract, crawl, act, agent or planner run on your browser that could not finish now ends failed with the agent's own error, and an error code for plans, instead of reading as a success with 0 rows or as partial; the rows, warnings and credits it produced stay in the reply. list_executions and check_results report how long a finished run took instead of counting on from its start. Screenshots taken in AI-app, scheduled and trigger runs now save, where most failed to upload before, and when an AI app answers a question the agent asked before a step, the run carries on with that answer instead of asking again. Needs extension 38.1.5 for runs on your browser. ([MCP docs](/docs/mcp)) - **New:** AI apps can keep the tabs a run opens. With keep_tabs_open, the tabs an MCP or API call opened stay open when it ends and are listed in its result, so the next call can read one, continue in it, or close it; they count against your browser's Max parallel tabs setting. You can also name each browser under Browser as API/MCP, Advanced, Device name, to tell them apart in list_devices. Needs extension 38.1.2. ([MCP docs](/docs/mcp)) - **Fixed:** Free Mode no longer changes the model of runs your AI apps start. With Free Mode on, tasks that AI apps and API calls send to the extension, and scheduled and trigger runs, use the model and reasoning level you selected, your own API keys included, and a call that asks for GPT-6.1 Sol gets it instead of an error. Free Mode covers tasks you start in the side panel: these runs were always billed as if it were off, and the agent no longer tells you they are free. Needs extension 38.1.5. - **New:** Look people up on LinkedIn by name. rtrvr Enrich now finds LinkedIn profiles by full name plus company, then city or job title, not only by profile link, and with only a name the agent first finds the profile link, for example from an event page or a web search. Enrichment takes job titles from each person's current role, ranks a top N in one pass, adds its columns beside your rows without repeating headers, and a search with too many filters says which limit it hit. In our test on a 290-guest Luma event, one lookup matched 226 of the 267 guests whose profiles linked to LinkedIn. In Cloud and in the extension. ([Enrichment docs](/docs/enrichment-datasets)) - **Fixed:** Phone numbers and other text that start with +, =, - or @ are written to Google Sheets as text, so +1 415-555-0100 shows as written instead of #ERROR!, and text copied from a page can never run as a formula. In Cloud and in the extension. - **Improved:** Web search answers sooner. When the main search provider has not answered within 6 seconds, rtrvr asks the second one at the same time and keeps whichever answers first, instead of waiting up to 12 seconds before switching, and you are still charged once per search. Replaying recent searches, the slowest one in ten finished in about 10 seconds instead of 16, or 9 instead of 14 in Cloud, and about 4% of searches got the second provider's results, which have no local business listings. - **Improved:** The agent knows what it has not seen. In the extension it is told whether it read a tab in front or in the background, and when a background tab shows too little or a list will not grow as it scrolls, as Google Maps results can, it brings the tab to the front once instead of scrolling again and again, or answers with what loaded and says what did not. In Cloud and in the extension, a page that could be read only in part no longer claims to be the whole page, so the agent stops deciding that something it did not reach, such as an open composer, is gone. - **Improved:** Cloud plans hold up better. Their scripts can wait and run steps side by side with setTimeout and mapLimit, which most often failed as not defined before; browser-only names such as document or window are caught while the plan is written, with what to use instead; and a step that fails the same way 20 times in a row stops the script with what failed and what to change, where the worst runs had retried one failing call hundreds of times. The agent also knows from the start when no Google account is connected. - **Fixed:** Fewer empty answers. Steps that summarize, rank or rewrite text no longer stop at a hidden length limit, which in 14 days cut off 121 of 1,721 of them, 109 before they wrote any answer. With Claude and Gemini models, the web pages, Google Docs, Slides and PDFs the agent writes now reason at the level you choose instead of a small fixed amount. - **Improved:** New site guidance for Partiful opens an event's full guest list, under View all and then Approved, and reads every guest. Luma guidance reads guests' profiles in parallel to find their LinkedIn links, and LinkedIn guidance keeps invite notes within 200 characters on free accounts and 300 on Premium, since a longer note leaves Send disabled. - **New:** See which model ran a Cloud run. Its Details tab in Executions shows the model and reasoning level it started with, the level each call was sent at and on which provider, and any other model that answered. API results, and MCP's cloud_agent and check_results, carry the same under model. - **Fixed:** Closing the last tab no longer ends a Cloud run. When the agent closes the browser's only tab, a blank tab takes its place and the run carries on, and if you close the last tab or window while you have control, a blank window of the same size comes back. - **Fixed:** MCP connectors whose servers refuse requests from a browser, such as Publer, now connect and run their tools, in Cloud and in the extension; if a server still refuses, the error names it and says the tool was not called. The Connectors page no longer shows Needs access every 10 hours for a connector such as Dart whose sign-in only needed renewing. Needs extension 38.1.3 in the extension. - **Fixed:** Writes to Google Sheets land. A scheduled Cloud run that writes to a chosen sheet no longer fails before writing because its script could not see which sheet to use, and one that gives up before writing gets one more pass to write, unless the sheet itself refused, for example with no edit access or no such tab. Rows kept locally while Google Sheets access was lost reach the sheet once access is back in the same task. Needs extension 38.1.3 in the extension. - **Fixed:** A tool the agent repairs during a run runs with the repair instead of handing back the broken version's earlier answer, in Cloud and in the extension. In the extension, after a brief server error the agent no longer takes its last click for one that did nothing, which could make it click again, such as a second add to cart; a daily limit or a model provider's rate limit is not retried; and MCP scrape returns each address's own page even when another failed to open or be read, and says when a page's capture was cut short. Needs extension 38.1.3. - **Improved:** New extension users are guided in. The page that opens after you install the extension walks you through pinning rtrvr, opening it, signing in with Google or email, and trying a first task. With extension 38.1.5, its Open Retriever button opens the side panel in one click. - **Improved:** GLM 5.3 Flash no longer falls back to Z.ai's own API, and neither do steps rescued after every provider of a model fails, so a step its first provider cannot answer moves to a faster backup. In our logs from September 29 to October 6, Z.ai started answering GLM 5.3 Flash page actions after 6.5 seconds at the median, against 1.3 seconds on that backup. GLM 5.3 and China routing are unchanged. ([Compare models](/models)) - **Improved:** GPT-6 Luna now describes the screenshots the agent asks about, scanned PDF pages, and images too large to send whole, moving to a backup provider when one is busy. For now, attached audio and video are not transcribed: the agent says so, and can still upload the original file to a site. ## v56: Schedules, rebuilt, and runs that finish the job. *October 4, 2026* Schedules were rebuilt. Each run remembers the last one, writes to the Sheet, Doc, or Slides you picked, cannot run away with your credits, and pauses itself and emails you when it keeps failing. Cloud runs can browse from the country you choose, on that place's clock and language. For you suggests tasks based on the sites you use, long tasks keep going while they make progress, and the agent checks the page before it says a task is done. You can cancel any Cloud run, API calls can pass exact values as variables, and uploads now attach even where a site hides its upload button. AI apps connected over MCP reach a browser that answers, and the Cloud runs they start use your saved logins. - **New:** For you suggests a few tasks you are likely to want, based on the sites and tabs you use, in Cloud and in the extension's side panel. Each idea opens as a draft you can edit, and nothing runs until you send it. Choose its sources and an optional email in your preferences, and turn on Chrome history only if you want sharper ideas. Needs extension 38.1.1 in the side panel. ([Meet the For you feed](/blog/for-you-ai-feed)) - **Improved:** Long tasks keep going until they are done. The agent no longer stops after five rounds and waits for you to type continue: while each pass makes progress it carries on and shows how far it has got, for example 106 of 200 leads. When it does need you, it pauses with Continue and Stop here. Works in Cloud, and in the extension with 38.1.1. - **Improved:** Done means done. After the agent clicks, types, or hits a failed step, it checks the page once more before it says the task is finished, and its final summary always appears in the result. A run that can only finish part of the job says it is partial, keeps what it collected, and says why. Summaries no longer end with a promise such as I'll check the settings. - **Fixed:** Nothing gets done twice. If a later pass of the agent repeats a write it already made, such as adding a row or creating a sheet, it gets the first result back instead of writing again, even after a dropped connection. Needs extension 38.1.1 in the extension. - **Fixed:** A sheet you told a run to write to gets only rows with data. A row that holds nothing is left out and named in a warning while the rest are written, and a write with no data at all fails with the reason, as adding a row already did. - **Improved:** Errors say what happened. When a model or provider refuses or fails a step, you see its own message instead of a generic one such as failed after 3 attempts, and a refusal is not retried. Needs extension 38.1.1 in the extension. - **Fixed:** A run's credit total includes the credits of steps that failed, so the total you see is the total you were charged. Needs extension 38.1.1. - **Improved:** Pop-up dialogs stay in view. On long pages the agent reads an open dialog, such as Substack's note composer, before the rest of the page, so it no longer loses track of a composer it just opened. In Cloud, and in the extension with 38.1.1. - **New:** Find and open your Google Drive files by name. In the extension the agent searches Drive through your signed-in browser and opens the file directly instead of clicking through folders. In Cloud it asks you to pick the file with the Google Drive picker, so rtrvr only sees the files you choose. Needs extension 38.1.1. - **New:** Save the media you find. The agent can list the images, videos, and audio on a page, including inside frames and embedded components, download the files you want, and save them to your Google Drive. Needs extension 38.1.1 in the extension. - **Improved:** Your tabs stay yours. The agent marks the tabs it opens, works in those, and never closes a tab you opened unless you name it, and it can tidy up several of its own tabs at once. Needs extension 38.1.1. - **Improved:** One sheet instead of copies. The agent reuses the Google Sheet you are working in, or one it already made in this chat, instead of creating a new one each time, and a scheduled run keeps writing to the same sheet or doc. Needs extension 38.1.1 in the extension. - **Improved:** Large tables are faster and have clear limits. An open sheet is read again only when it changes, so a huge upload no longer slows every step. API dataInputs take up to 16 MB per file and up to 1,000,000 rows or 5,000,000 cells for one request, and an input over a limit is refused with an error that names it. ([Agent API docs](/docs/agent)) - **New:** Schedules remember their last run. Each run sees what the previous one found, so it can report only what changed, and it keeps its own notes and its output file from one run to the next. A scheduled run that needs an answer nobody is there to give ends instead of waiting, and the question is emailed to you. ([Schedules docs](/docs/schedules)) - **Improved:** Scheduled Cloud runs write where you told them. Pick the Sheet, Doc, or Slides file with the Google Drive picker or a pasted link. For Sheets, rtrvr checks before saving that it can edit the file and that the tab exists, and every run writes to that exact tab, reads it back, and takes one more look when a write did not land. - **New:** Schedules cannot run away with your credits. Every schedule, in Cloud and in the extension, runs at most every 5 minutes, and the editor shows how many runs a day that means and what they cost. An extension schedule that suddenly uses far more credits than usual pauses itself and emails you. Needs extension 38.1.1 for extension schedules. - **New:** Schedules heal themselves. A Cloud schedule that fails 3 runs in a row pauses and emails you what went wrong, and the Schedules page shows the failed runs with a Resume button. A run that arrives while every cloud browser is busy is sent again instead of failing. - **Improved:** Schedules can start from a feed. Give a run an RSS or Atom feed or a sitemap and the agent reads it, so a daily check of a feed for new items works. - **New:** Choose where your Cloud runs browse from. With Retriever managed proxy selected, the Location chip in the composer picks a country, and optionally a region or city, for that chat, or a list of up to 5 countries, or of up to 5 regions or cities in one country, for an exit in any of them. The picker checks that each place has an exit before it takes it. Settings > Default proxy saves one for every run and schedule. The API takes it as settings.proxyConfig.location and MCP as proxy_location, a list included. A city with no exit falls back to its region and then the rest of the country, and if no place you chose has an exit, the run stops and says so instead of browsing from somewhere else. The browser uses the time zone and language of the country it exits in, and the result reports where the run exited. ([Agent API docs](/docs/agent)) - **Improved:** Cloud browsers keep a steady clock. A run never starts on a random time zone: it uses the zone and language you set with settings.browser in the API, else the proxy location, else the server's own location, and the agent is told the browser's time zone and converts the times you give it before it types them. - **Improved:** AI apps reach a browser that answers. An MCP or API call that names no device goes to one of your browsers that has been answering its commands. A browser that left its last command unanswered, such as a sleeping laptop, waits behind the others until it answers again. When a browser misses a command, the reply names it, says whether rtrvr picked it, and lists your other browsers with their status, and list_devices shows each browser's extension version, when it last answered, and whether it is responding, so two browsers with the same name are easy to tell apart. ([MCP docs](/docs/mcp)) - **Improved:** Cloud runs started from AI apps use your saved logins. The cloud browser starts with the logins you saved with Cookie Sync, or signed into inside a Cloud task with Take control, while Cookies is on. Results and check_results list which ones a run started with, never a cookie, and session_source runs a call without them or with one device's logins. ([MCP docs](/docs/mcp)) - **Fixed:** MCP answers more calls correctly. check_results returns a finished Cloud run's result from your stored record days later, not only within 24 hours. A take_page_action that acts on a page but names no tab is refused before it runs and lists your open tabs, instead of acting in a blank tab. cloud_scrape answers a location with no exit at once. - **Fixed:** Schedule time zones are exact. A time zone you set for a schedule must be a name such as Europe/London: an abbreviation such as BST was read as Bangladesh time and is now refused with a clear message. Schedules you already have keep running as before. - **New:** Collect Google Maps reviews with a dedicated scraper. Ask for how many, the sort order, and how recent; you get the full review text and star ratings with stable IDs, and you are charged only for reviews returned, after your free data allowance. - **New:** Cancel any running Cloud run from Executions, including runs started through the API. - **New:** API calls can pass variables. Send values such as a signed file link, a note's text, and a time as named fields, and the agent uses them exactly as given instead of copying them out of the prompt. The docs include the request body for n8n. ([Agent API docs](/docs/agent)) - **Fixed:** Uploads attach where a site hides its upload button. The agent puts the file on the hidden or click-created file input behind the button, choosing the video or image input by the file's type, and a video gets its real type from its extension. Attached files with the wrong type label are read by what is inside them. Needs extension 38.1.1 in the extension. - **Improved:** A model on your own API key runs on your own provider. A key whose endpoint rtrvr does not know is refused with a clear message instead of quietly running on rtrvr's models. - **Improved:** Web search fails less often. When Google results are throttled or slow, rtrvr.webSearch moves to a second search provider within seconds instead of failing. Those results have no local business listings, and the answer says so. - **Improved:** DeepSeek V4.1 Flash now runs on Microsoft Azure first, and both DeepSeek V4.1 Flash and GLM 5.3 Flash fail over between several providers, so they keep answering when one is busy. A step a provider refuses on content-safety grounds moves to the next provider, and GMI Cloud is no longer used. ([Compare models](/models)) - **New:** Connect more than one Gmail account. Each account you add becomes its own Gmail connector named after its address, so the agent reads and sends from the right inbox. Needs extension 38.1.1 in the extension. - **Fixed:** Custom MCP connectors connect again. The Invalid server ID error on every new connector is fixed, sign-in to servers such as Dart completes in its popup, Cloud runs renew an expired connector sign-in on their own, and Cloud calls to Dart tools no longer fail with Unknown tool. - **Improved:** API calls made with your own API key can use the Google connection you saved in Cloud, so Sheets, Docs, Slides, and Drive tools work without sending a separate Google token. - **Context:** Rover site owners now choose whether visitors' runs may use Cloud browsers. Turn it on in Rover's Install settings and set a per-run limit of 1 to 10 credits and a daily limit of up to 10,000 credits; it stays off until you do. ([Rover](/rover)) - **Context:** Free Mode in Cloud no longer includes a task data license, and the Cloud task data dialog is gone. - **Fixed:** Cloud runs are steadier. Taking control during a long run pauses it for you instead of letting it run out of time, a finished run is never relabeled as cancelled, a slow tab close no longer ends a run that reads many pages at once, fewer runs end with The model service could not complete this task, videos hosted on Mux play, and data a site loads in the background is decoded so the agent can read it. - **Fixed:** Executions show the real state of every run. A run that waited for your answer past its time reads Expired instead of sitting on top as Needs Input, and a run that was refused before it started, for example because every cloud browser was busy, reads Not started with the reason and your prompt instead of showing as completed. - **Fixed:** The Cloud sheet viewer shows your data even when Google's editor cannot load in the panel, including when Google asks you to sign in there: you get a read-only copy of the tab the run wrote, with a switch back to the editor and Open in Google Sheets. - **Improved:** Cookie access is optional again in the extension. Cookie Sync asks for it with Allow cookie access when you sync a site, and you can revoke it there. Needs extension 38.1.1. - **Improved:** In the extension, pasting a full link into Cookie Sync picks the right site, a page tree the agent returned no longer floods the Result, a new sheet opens in a background tab so the page you are on keeps loading, and less code is loaded into each page. Needs extension 38.1.1. - **Improved:** Refreshed guidance for 23 popular sites, 4 of them new, helps the agent finish tasks there in fewer steps. ## v55: Your AI apps can drive Edge, Brave, and Arc. *September 28, 2026* Claude, ChatGPT, Cursor and other AI apps connected over MCP can now run tasks in rtrvr inside Microsoft Edge, Brave, and Arc, not only Chrome, and long tasks come back with their results instead of timing out. You can attach files up to 128 MB, GLM 5.3 Flash answers about three times faster, GPT-6 Luna returns the rows it extracts directly, Take control in Cloud hands you the browser reliably, and schedules can be edited in place. - **New:** MCP now works in Microsoft Edge, Brave, and Arc. These browsers cannot receive Chrome's push messages, so the extension keeps a small listener open that picks up the tasks your AI app sends. Turn it on with Enable Extension as MCP in the extension's MCP panel. Needs extension 37.9.5 and a paid plan. ([MCP docs](/docs/mcp)) - **Context:** Running tasks in your own browser from MCP or WhatsApp is part of paid plans. Enable Extension as MCP is on by default for paid plans in Chrome. Free accounts can keep using Cloud browsers over MCP and now see a plain explanation instead of a setting they cannot turn on. - **New:** Long MCP tasks no longer time out in your AI app. After about 40 seconds the app gets a running status with an execution id, and check_results waits for the next steps and the final answer, so apps that give up after a minute still get the result. ([MCP docs](/docs/mcp)) - **Improved:** MCP is easier to connect and more reliable. Paste your API key as a plain key or in an x-api-key header, Allow Connected Apps no longer blocks Cloud tools, and extractions that return tables of rows are saved instead of refused. - **Improved:** Schedules are edited in place. Changing a schedule's timing or prompt updates it instead of making a copy, a pause or delete made during a run sticks, and a new Where runs start setting can open scheduled runs in their own background tab, so they do not take over the tab you are using. AI apps can edit, pause, and resume a schedule by its id. ([Schedules docs](/docs/schedules)) - **New:** Attach files up to 128 MB in the extension, in Cloud, and over MCP (20 MB in Private Mode). Uploads on rtrvr.ai show progress, can be cancelled, and pick up again after a dropped connection. For files over 20 MB the agent sees the name, type, and size instead of the whole contents, and can still upload the file to a site for you. - **Improved:** GLM 5.3 Flash is about three times faster: a typical agent step now takes about 3 seconds instead of 9. DeepSeek V4.1 Flash starts answering sooner too. Both are served from a faster provider, with Azure and GMI Cloud as backups. ([Compare models](/models)) - **Improved:** Planning with GPT-6 Luna is several times faster. Luna answers from OpenAI's own servers with Amazon Bedrock as the backup, and its plans now run where they finish quickest. - **Fixed:** GPT-6 Luna returns the rows it extracts in its answer. After Luna moved to OpenAI's servers its answers arrived with empty rows and a second pass had to extract them again. That extra pass is gone, so data tasks on Luna finish sooner and use fewer credits. - **Improved:** When the service behind a model is slow, busy, or cannot handle a request, the step moves to a backup model or provider on its own instead of stopping your task. - **Context:** MiMo is upgraded to V2.6 Flash and V2.6 Pro, served by Xiaomi in China and marked with a Routed to China badge in the model picker. GLM 5.3 and GLM 5.3 Flash have an optional China routing switch at half price. Private Mode never uses MiMo: a private MiMo pick runs on GPT-6 Luna. ([Compare models](/models)) - **Fixed:** Take control in Cloud works. Your clicks and typing reach the browser, the live view stays on screen for paused and parked runs (picture-in-picture included), a paused login continues from the run bar, Cancel on a paused run really cancels it, and a request sent twice never starts the run twice. - **Improved:** Cloud chat history goes past 100 chats with Load older and search, and recent chats sit under Agent. The composer stays responsive while your tools load, a page that is slow to open gets time to load instead of failing, and a scheduled Cloud run that arrives while every browser is busy is sent to a free one instead of failing. - **Improved:** Save cloud proxies by name and pick one per run in Cloud, the API, and MCP. Removing the proxy you use falls back to the Default proxy instead of no proxy at all. - **Improved:** The agent clicks more precisely in the extension. A checkbox hidden behind its label is ticked through the label, a radio button that was already selected is reported as unchanged, a link that went nowhere no longer counts as progress, and each action lands on the tab it names. When a page in a background tab will not draw, the agent brings that tab to the front. Needs extension 37.9.5. - **Improved:** Links and values you paste into a task are used exactly as written. Plans read your message directly instead of retyping it, so long download links and IDs are no longer garbled. A scanned PDF is recognized as scanned, and the agent uses its recognized text instead of stopping on an error. Needs extension 37.9.5. - **Improved:** Saved site logins stay fresh for Cloud. The extension shows when the next sync runs and how old each saved login is, refreshes a stale login in a background tab at most once a day, and explains how to remove one. Needs extension 37.9.5. ([Cookie sync docs](/docs/cookie-sync)) - **Improved:** Free Mode: Enhance shows a sponsored card while it rewrites your prompt, an expired Free Mode session refreshes once and then stops cleanly instead of retrying, and one free account per device now also covers reinstalling the extension on the same computer. Offices that share one network can have up to 10 free accounts. ([Pricing](/pricing)) - **Improved:** AppSumo credits are spent in a fairer order. Monthly AppSumo credits and Stripe plan credits are used before your one-time activation credits. - **Improved:** Rover speaks your visitors' language. The Rover widget and its voice follow the site's language, Workspace lets you choose the voice service, and connected assistants can propose Rover instructions and actions for you to review. ([Rover](/rover)) - **Improved:** The models page has a live board showing how each model performs as a browser agent, provider by provider, next to redesigned model comparisons. The docs now cover 128 MB attachments, long MCP runs, API key headers, and editing schedules. ([Live model board](/models)) ## v54: Record in one click. Google access only when a task needs it. *September 23, 2026* Recording a demo is now one button, and you name it when you finish. rtrvr asks for Google Drive access only when a task actually touches a Google Sheet, Doc, or Slides: up front when you attached one, otherwise once the plan on screen shows it will write one. GPT-6 Luna and Sol replace GPT-5.6 in the managed lineup with prices shown in the picker, Free Mode is back to 250 credits a day, and a finished Cloud run can be turned into an API call. - **New:** Start recording is one click. Open Recordings in the side panel and press Start recording; there is no name to type first. The recording starts as the site plus the day, for example linkedin Sep 23, and when you press Finish a dialog lets you name it before it saves, or keep recording. Needs extension 37.9.4. ([Recordings docs](/docs/recordings)) - **Improved:** The microphone is explained where it is asked for. The recording bar says Mic on or Mic off with one line of guidance, the Chrome permission window says why narrating your steps helps the agent, and Record without narration keeps capturing clicks only. A denied microphone or a failed save now shows as a message instead of disappearing. - **Improved:** Recordings, skills, shortcuts, and tools each end in one create button. The search box only searches or imports a shared link; Start recording, New skill, New shortcut, and New tool sit in a footer bar, so nobody has to type a name and then find a plus sign. - **New:** Google Drive access is requested only when a task needs it. In the extension the permission prompt appears up front only when you selected a Google Sheets, Docs, or Slides tab or attached a sheet; otherwise the agent asks once the generated plan is on screen and calls a Sheets, Docs, or Slides helper. Decline and the run continues, with collected rows returned as a table in chat. ([Permissions and privacy](/docs/permissions-privacy)) - **New:** Cloud no longer asks you to Enable Workflow Execution on every task. A launch needs Google only for an attached sheet or a Google link. A plan that turns out to write a Google file pauses with the plan on screen and asks Connect Google or Continue without a sheet, then resumes from where it stopped. - **Fixed:** A task without Sheets access no longer repeats its work. Rows collected in a local sheet are shown to the agent on every pass, so it stops re-creating sheets and asking Google for a spreadsheet that does not exist. - **Context:** GPT-6 Luna and GPT-6 Sol replace GPT-5.6 as the managed OpenAI models in the extension, in Cloud, and in the API. Saved settings and shortcuts that named the old ids keep working, the default model for new accounts is GPT-6 Luna, and the model picker shows what each managed model costs. ([Compare models](/models)) - **Context:** Free Mode covers 250 credits a day again, up from 150. The meter in the model picker and the sidebar shows today's draw to the cent. - **New:** A run control bar sits above the Cloud composer for the thread's active run: pause, resume, cancel, and a place to type a correction while it runs. A finished run can become an API call with Run via API: the request body plus cURL, Python, JavaScript, and n8n snippets, refined with the corrections and answers you gave during the run. ([API docs](/docs/api)) - **Improved:** The agent can play and pause video and audio on a page and wait for a lesson video to finish. A course player that reveals Next only when the video ends used to cost dozens of steps; one wait now covers it, in the extension and in Cloud. - **Improved:** Clicks report the truth. A pointer click no longer verifies itself, late page effects are watched, key presses get a receipt, and custom list boxes select properly, so a click that changed nothing is retried or reported instead of counted as done. - **New:** Connectors have a home. Cloud has a Connectors view below Tools with a setup guide, connection checks run on their own, and the extension keeps a compact entry with Drive status and Reconnect. Google Drive shows Connected only after its grant is verified, and switching accounts no longer mixes up Google connections. ([Connectors guide](/docs/connectors)) - **Improved:** Sign-in problems say what happened. A failed session refresh shows a notice with Sign in again instead of the app looking signed out or reporting Credits unavailable, Google and email sign-in are hardened, and connecting Drive is faster. - **Improved:** WhatsApp: questions from the agent reach you on WhatsApp again with the conversation kept, private media you send stays private through Cloud planning, and a scheduled WhatsApp task pinned to your device resumes instead of failing. - **Improved:** Sponsored cards match the task in front of you. Every card is chosen from the thread, the prompt, and any correction you typed mid-run, a cancelled run gets a card too, and an answer to a sensitive question is never sent to an ad partner. - **Improved:** Audio and video attachments keep their transcript, so reading or searching a media file in a task returns the settled transcript instead of nothing. A Cloud extraction that found nothing on its first pass now keeps working instead of looping on the same page. - **Improved:** The docs playground shows an importable n8n workflow, /install links straight to the Chrome Web Store listing, and the /models page compares the managed lineup on Artificial Analysis figures. AI agents can find rtrvr on the ZeroClick storefront at agents.rtrvr.ai. ## v53: Your Chrome schedules can send their results anywhere. *September 18, 2026* A schedule that runs in your browser can now deliver each run to a webhook, WhatsApp, email, Slack, or Discord, and you choose whether Chrome notifies you every time, only when something fails, or never. Free Mode's daily allowance goes up to 150 credits. When a request has a real decision in it, the agent asks before it starts instead of acting and asking afterwards. - **New:** Chrome schedules deliver their results. A schedule that runs in your extension can send each run to a webhook, your WhatsApp, your email, Slack, or Discord, the same channels cloud schedules already had. Set it up on rtrvr.ai under the schedule's When it runs section, or just ask: "schedule this every morning and WhatsApp me the results". Delivery is handled by rtrvr.ai, so it works even when the machine that ran the schedule is asleep, and a test send checks each channel before you rely on it. Needs extension 37.9.1. ([Schedules docs](/docs/schedules)) - **Improved:** You decide when Chrome speaks up. A scheduled run can notify you every time, only when the run or a delivery failed, or never. The Schedules button shows how many finished runs you have not looked at, each run shows where its results went, and a bell on the schedule opens its delivery settings. - **Context:** Free Mode now covers 150 credits a day, up from 100. Hover Free Mode in the model picker to see how much of today's allowance is used. - **Context:** Free Mode is one account per device. A second free account on the same browser or install is asked to subscribe instead of running. Paid plans, AppSumo accounts, workspace members, and anyone using their own key or ChatGPT sign-in are not affected. - **Improved:** The agent asks first. When your request leaves a real choice open, which account, which of two readings, whether to send or publish something, the agent now asks that question before it does anything, and continues once you answer. It no longer acts on a guess and asks afterwards, and it never asks during an unattended scheduled run. - **Improved:** The model picker is tidier in the extension and in Cloud. Try Jev sits right under Free Mode with its explanation on hover, the model you are using your own key or ChatGPT sign-in for wears one BYOK mark, the shipped default is labelled, and the Free Mode switch stays reachable under a long hint. ([Jev setup guide](/docs/jev)) - **Improved:** Local sites work in the extension. Ask the agent to open localhost:3000, a 127.0.0.1 or 192.168 address, or an internal server on your network and it opens the page, which is useful for testing something you are building. - **Improved:** GLM 5.3 Flash and DeepSeek V4.1 Flash are now served from GMI Cloud, with Azure AI Foundry as the backup when a request fails there. - **Improved:** MCP clients get more from check_results: a finished cloud run reports its output, and a run that paused to ask you something reports the question and how to resume it. - **Fixed:** A public page that blocks the cloud browser is retried through a different route on an explicit scrape, and a scrape checks that the paying account has credits before it starts work. ## v52: Slow pages stop holding up your task. *September 16, 2026* Cloud and Chrome now stop a page read after eight seconds and keep the useful text and links they already found. Take control reliably pauses the agent before handing you the browser, and your Free Mode, credit, and provider choices stay with the account you are signed into. - **Fixed:** A slow page read no longer traps a task in repair. Cloud and Chrome stop each read after eight seconds, make at most one recovery attempt inside that limit, and keep any useful text and links they already found. Repeated empty reads stop cleanly. - **Improved:** Forms work more like they do for you. rtrvr can choose native and custom dropdown options, add several choices to a multi-select, move sliders, enter dates, times and colors in the right format, upload files, and use controls that appear on hover. It waits for the page's actual work instead of adding the same delay after every action. - **Fixed:** Profile links no longer get mixed with matching image URLs. The agent can distinguish a page link from an avatar or other media, and keeps full URLs as read-only evidence when page controls cannot be used safely. - **Fixed:** Take control works reliably in Cloud. rtrvr pauses the agent, reconnects with permission for you to click and type, and resumes only the pause it created when you release control. - **Improved:** A Cloud task that pauses for you keeps its tabs, signed-in state, and unsaved form work. A lost or late browser reply cannot replay an action that may already have happened. - **Fixed:** Cloud model calls stop waiting when a provider stalls, keep usable partial output, and move to the next eligible supplier without starting an unaccounted second answer. A task deadline is reported as a timeout, not as if you cancelled it, and a busy browser pool returns a retryable wait instead of a false cancellation. - **Improved:** The extension side panel shows a loading view instead of staying blank while settings and history load. You can start typing immediately, and Retry keeps your draft if a saved-state read stalls. - **New:** MCP clients can run several device commands at once, list what is running, and cancel one while keeping its completed work. A release bug that left device commands stuck after the extension accepted them is fixed, and an action that opens a new tab runs once instead of twice. - **New:** Change what you saved by asking. rtrvr can rename, delete, enable, disable, pause, or resume tools, skills, schedules, triggers, recordings, and MCP connections when that action is available for the item. - **Fixed:** A task closes only the tabs it created. The tab you started from, paused forms, and generated documents stay open; the task's own working tabs are grouped and closed when it finishes. - **Improved:** A verification or challenge signal no longer stops a task by itself. The agent decides whether the page is actually blocked and asks for your help only when it needs it. - **New:** Free Mode consent is remembered once per account across Cloud and the extension. The ads choice follows you to another browser or device. Cloud still asks separately before task data can be licensed. - **Improved:** Free Mode keeps both Off and Low reasoning available and shows how much of today's allowance has been used. The run receipt and sidebar now show the same daily number. - **Fixed:** Credit source, workspace payer, API keys, and ChatGPT sign-in stay with the active account. ChatGPT sign-in can finish after the panel closes, and a temporary refresh problem no longer discards a token that still works. - **Improved:** Credit recovery tells you what can actually fix the task: Retry for a service problem, Use workspace credits when available, or ask the owner when a team limit is reached. A purchase link appears only when buying credits can help. - **Fixed:** Damaged Word, Excel, and PowerPoint uploads recover the readable parts within a strict memory limit. Empty, unsupported, or cut-short files now say what went wrong instead of returning nothing or failing later in the task. - **Improved:** Generated documents and web pages keep the structured data the task collected. Generated web pages can be opened and checked inside Cloud's artifact viewer. - **New:** Cookie preferences are available across rtrvr.ai. Necessary cookies stay on; analytics and advertising can be changed separately from the footer or privacy page, and an opt-out stops future analytics collection. - **Improved:** Cloud navigation starts collapsed to leave more room for the task. Ordinary rtrvr.ai pages also no longer load the Rover runtime; Rover pages and Rover Workspace keep it as before. ## v51: Ask for a tool. It runs when your browser is closed. *September 12, 2026* Turning a site with no API into something you can call used to be a recording, a generator, a save and a schedule: four screens. Now it is one sentence in chat: the agent drives the site, builds the tool, tests it with a real call, and hands back how to run it. Saved tools no longer need Chrome open, schedules can run a tool or a plain instruction instead of only repeating a past run, and MCP servers and cookie sync can be set up by asking. - **New:** Build a tool by asking for it. Type "build me a tool that logs into my billing site and returns this month's usage" and the agent opens the site, records one pass, writes the tool, saves it, and calls it once to check the answer before telling you it worked. Its reply names the tool, what it returns, and how to call it: @toolName in chat, or user_ from the API. Add "and run it daily at 8am" to the same sentence and it schedules it too. If the site needs a login it asks you to sign in first, and never asks for a password. - **New:** Saved tools run without your browser open. A tool called from the API, the MCP server, or a webhook used to fail when Chrome was closed. It now runs in your cloud browser instead, opening the page it needs and using the login you synced. Pass target to pin a run to one or the other. Cloud runs report the credits they used and, if the tool is still working after about 25 seconds, hand back a run id you can follow or receive by webhook. - **New:** Schedules and triggers can run a tool or a plain instruction. A cloud schedule used to be able to repeat a past run and nothing else. It can now run one of your saved tools with its parameters, run several in order, or just follow an instruction you type, with a time of day in your own timezone. Inbound webhook triggers work the same way, and the URL the Triggers page gives you now actually runs something. - **New:** Connect an MCP server by asking. "Connect my Zapier MCP" or "add this MCP server" sets it up in place, including sign-in. Built-in connectors need no URL. Imported tools arrive switched off so your tool list stays short, and you can say which to turn on. - **New:** Sync a site's login by asking. "Sync my cookies for linkedin.com" adds the site and syncs it, so scheduled and API runs start signed in. The first time, Chrome's permission is one button in the chat itself rather than a trip to the Cookie Sync panel and back. - **Improved:** A question from the agent no longer restarts the work. When it pauses to ask something with buttons, answering now continues the same run from where it stopped, instead of starting the script over and repeating everything it had already done. - **Fixed:** Webhook notifications on scheduled runs are sent. The Schedules form has offered a webhook for months and the server was discarding it, so nothing ever arrived. Scheduled runs now send the same payload the API does, signed the same way. - **Fixed:** Tools that need the live page work in the cloud. A tool written to read a page rather than call an endpoint was running against the wrong document in a cloud run and returning nonsense instead of failing. It now opens the page, waits for it, and runs there. - **New:** A skill you scope to a site applies itself on that site. Name the sites a skill is about and it is used in full whenever the agent works there, including while it is clicking through the page rather than only while it plans. Matching happens in the extension against your own saved skills, so an edit takes effect straight away, even offline. - **Improved:** The agent knows more sites out of the box. Built-in notes on how particular sites behave, such as which controls do nothing and which address actually applies a filter, now reach the part of the agent that clicks through a page instead of only the part that plans, and they cover more sites than before. - **Improved:** The Workspace section explains itself. An account without a workspace used to see nothing there at all; it now says what a workspace does and offers the one button that sets one up. A running task also shows what you asked for at the top of the progress panel. - **Improved:** The agent gets through a task in fewer steps, and pages load into it about twice as fast. Controls that used to be pressed and quietly ignored now work first time, including search boxes that swallow the Enter key and sort and filter options like "Price: low to high"; when a control really will not respond the agent says so and moves on instead of trying it again. Sites that came back blank read normally, a new tab is recognised as empty rather than waited on, and the agent no longer spends five to eight seconds waiting for wording it only guessed at. Updating the extension no longer strands tabs you already had open. ## v50: The free plan is sponsored. Your own key has no daily limit. *September 12, 2026* Free Mode is now how the free plan runs: value-tier models at zero credits with a small sponsored card beside the results and a daily fair-use limit, while paid plans run ad-free. Bring your own key or sign in with ChatGPT and nothing counts against the daily limit. Hover Free Mode to see today's allowance, and when it runs low the composer offers the ways forward. - **Context:** The free plan is sponsored. Every task from a free account runs in Free Mode with a small sponsored card beside the results; ad-free runs are included in every paid plan, the same way schedules, triggers, and cookie sync are. Free accounts see the updated terms once on their next task, with Continue or See plans. - **New:** Your own key never counts against the daily limit. Bring an API key or sign in with ChatGPT and the model runs on your account: the sponsored card still appears on the free plan, but nothing deducts from today's Free Mode allowance, and the fallback, vision, and cloud-browser legs stay covered while the allowance lasts. - **New:** See today's allowance on hover. Hovering Free Mode in the model picker, or the credits chip, shows how much of today's Free Mode allowance is used and when it resets. When most of it is used, a card under the composer offers ChatGPT sign-in, your own key, or plans; when it is spent, the next task waits on that choice instead of quietly using credits. - **Improved:** The daily Free Mode allowance is lower than before, and the number shown in the app comes from the server, so it can change without an update. A run out of credits now shows the same ways forward instead of a bare error. - **Fixed:** A key that fails mid-task under Free Mode no longer claims that credits were deducted; the notice says the fallback was covered by Free Mode. - **New:** Muse Spark on your own Meta key. Meta Model API joins the bring-your-own-key providers: paste a dev.meta.ai key in the extension's Bring Your Own AI screen, or add it under Add API key in Cloud, and Muse Spark runs at zero credits on the discounted Contributor tier or the Standard tier that is not trained on. Reasoning stays on and follows the Reasoning setting, and tools and images work. The Cloud model picker now keeps Free Mode at the top and Sign in with ChatGPT at the bottom while only the model list scrolls, as in the extension. - **Context:** Referrals are worth 1,000 credits each, for five referrals. You and the friend you invite each receive 1,000 credits, up from 250, once they upgrade to a paid plan, or right away when you are already on one. The limit moves from ten referrals to five. Referral credits never expire and are used only after the monthly credits on your plan run out. Codes redeemed before today pay the 250 they were accepted at, and credits already granted are untouched. ## v49: Clicks that land. DeepSeek Flash can see. *September 11, 2026* The agent notices when a click, scroll, or wait did nothing and tries harder, stops reusing element ids from old snapshots, and explains a failed run in plain words. DeepSeek Flash moves to V4.1 and reads images. Cookie sync shows the same synced sites in the extension, in Cloud, and in the cloud browser. Simple questions about the page finish in one step, and pages cost about a third less to read. - **New:** DeepSeek Flash is now DeepSeek V4.1 Flash and reads images. Screenshots, page captures, and image attachments go to the model directly instead of being captioned first, and the tier keeps its million-token context. It is served from GMI Cloud with DeepSeek-direct as failover, and bills at V4.1's listed rate, which is higher than the previous Flash rate. - **Context:** MiMo V2.5 Pro returns to paid plans. Free Mode runs and free accounts that had picked it now run MiMo V2.5. A million tokens of context is still free on GLM 5.3 Flash and MiMo V2.5. - **Improved:** A click that changes nothing is no longer reported as a success. In the extension, when the first click has no visible effect the agent tries a real pointer click on whatever sits under the cursor, keyboard activation, the page's own framework handlers, and for a stuck dialog Escape and then its backdrop. If nothing moves the page, the step fails with the strategies it tried and, when a real pointer would have landed on a different element, that element's id to click instead. A click whose page did not change, in the extension or in Cloud, now says why: disabled, covered by another element, off-screen, drawn on a canvas, opened a new tab, or started a download. - **Improved:** Controls that only appear on hover are reached. Tiles and menus that reveal their buttons on hover are hovered first, and the agent clicks the one control that appeared or is handed the list when several did, instead of clicking the tile again. - **Improved:** Links that open a new tab are followed. A click that opened a new tab used to leave the agent on an unchanged page, re-clicking or typing the URL by hand. The new tab now becomes the active tab, the page that opened it stays in view for one step, and tabs the agent leaves alone, such as other apps, the Chrome Web Store, or anything past eight open tabs, are reported rather than lost. - **Fixed:** Element ids from old snapshots are not clicked blindly. Ids are reassigned on every snapshot, and the model was copying them from earlier steps. Every past action now records which button or link an id pointed at, the agent is told to find that element again by its role and name, and if it still reuses a stale id the extension remaps it to the one confident match or fails the step with the current candidates instead of clicking the wrong thing. - **Improved:** Waits and scrolls end when the page is done. Every snapshot carries a page-activity line with requests in flight, spinners and progress bars, and DOM changes, a wait ends as soon as the page is idle, and the agent is told to wait only while something is in flight. A scroll reports how far the page extends and whether anything new loaded, and scrolling a list scrolls that list rather than the page behind it. - **New:** Cookie sync shows one truth. The extension, the Cloud composer, and the cloud browser now read the same synced jar: Cloud lists every site the cloud browser will carry a login for, can remove a site from every device, and can trigger a sync through your extension. Each site shows whether a login was detected, a Cloud run warns before it starts when a task site has no synced login, a run that reaches a login wall pauses with Take control instead of a question, and signing out of a site no longer overwrites the login already synced. Sync is simply on or off; the old matching setting is gone. - **Improved:** A Cloud run that never starts tells you. If the server has not picked up a run within 45 seconds the composer stops waiting, marks the run unreachable, and offers Retry, which resumes the same run rather than starting a duplicate. - **Improved:** Failed runs explain themselves. A run that ran out of time, found its document busy, sent the model more context than it can hold, reused a stale element, named a sheet tab that does not exist, or produced an extraction with invented references now shows the reason in plain words on the run card and in the side panel, along with whether a retry is likely to help. - **Improved:** Site playbooks guide the agent on familiar sites. Plans and page actions on sites such as Google, Gmail, Google Docs, LinkedIn, Amazon, Reddit, Facebook, Instagram, X, YouTube, GitHub, Notion, Upwork, Indeed, and Naukri start with what works and what to avoid there, chosen from the sites your task starts on. - **Improved:** Long code runs trim instead of failing. When a run's history outgrows the model's context window it is shortened in stages before the model is called again, and a run that is still too large stops at once with a clear reason rather than retrying. What a script prints now reaches the model's next pass and its review, in Cloud and in the extension, so counts and progress messages logged by the script are read rather than recomputed. - **Fixed:** Cloud code runs that call saved tools positionally, such as callTool(name, params), compile again. - **Improved:** Saved tools with defaults stop triggering questions. A parameter with a usable default is no longer treated as required, the prompt enhancer sees those defaults, and the agent is told never to ask you for a parameter that is not required. Default URLs are checked when you save a custom tool in Cloud or in the extension: a computed placeholder, an undeclared parameter, or a hardcoded value that should be a parameter is flagged inline with a one-click fix, and errors block the save. - **Improved:** Create Tool no longer hands back a tool that just re-runs the agent. A generated tool whose only work is an act, extract, or crawl call is rejected and regenerated once with the reason. - **Improved:** Spreadsheet inputs are read more reliably. Excel attachments are extracted in extension runs the way Cloud already did, data sent to the API as Excel, CSV, or Parquet is recognised even when labelled with the wrong type, every parser reports why a file could not be read instead of returning nothing, and an attachment the model cannot see is described to it with the reason. - **Fixed:** Writing to a sheet tab that does not exist fails with the tab's name instead of silently landing on the first tab. - **Fixed:** Extractions built on invented element references are discarded. When an extraction round's pointers were extrapolated from a renumbered snapshot rather than read from the page, the round is rejected with an explanation instead of returning made-up rows. - **Improved:** Schedule and trigger results asked for in the extension are read from the results stored in your browser, so they reflect this device's runs immediately. - **Improved:** Sponsored cards show their full text rather than a two-line cut, and cards rotated in mid-run are counted correctly. - **Improved:** Provider routing is more decisive in Cloud and in the extension: a severely slow host is left at once, quiet hours judge on the last twenty calls, and a host with no recent samples is marked stale rather than assumed healthy. The ChatGPT model gate and Sol to Terra to Luna step-down from v47 now apply to Cloud runs too. - **Improved:** Questions about the page you are already on are answered in one step. When the answer is right there, a headline, an author list, a page title, the agent replies at once instead of taking a second round to confirm it is done, so simple lookups finish in roughly half the time and cost. - **Improved:** Pages are cheaper to read. Repeated labels and empty spacer rows are trimmed from what the model reads, and ordinary links are no longer marked as things to drag around, so a typical page costs about a third fewer tokens with nothing lost. Long comment threads and listings benefit most. - **Improved:** Connected tools are described compactly. Each workspace tool is listed with its name, a one-line description and only the inputs you have to supply; the full definition is fetched when the agent needs it. That part of the instructions shrinks by about three quarters, and tool descriptions are read as documentation, not as commands. - **Improved:** The agent keeps its own notes between steps. What it worked out before moving to another page stays in view on the next step, in the place it expects, instead of being replayed as a stray message it was told never to write. - **Improved:** Skills are edited in place. A new learning is added as one line under the right section of the skill instead of rewriting or duplicating the file, and your own name, role and contact details are welcome in your general skill. - **Improved:** Loading and scrolling notes under each page snapshot state facts only, what is still loading and whether the page can scroll, and each agent decides for itself whether to wait. - **Improved:** Tools you create are plain scripts with no wrapper boilerplate, in the extension and in Cloud. - **Fixed:** Guidance mistakes fixed: posting a generated image attaches the file correctly, results from a multi-page crawl are read from the right field, spreadsheet checks appear only when a spreadsheet was written, the closing instruction sits where the model reads it last, and the current time carries its time zone. - **Fixed:** Element numbers are short again. Since September 9 every number the agent uses to name a button or link was at least seven digits long, and up to sixteen inside embedded frames or on pages Chrome had preloaded. A tab's numbers now start at 1, continue across the pages you visit in it so an old number can never point at a new element, and stay under six digits in practice, which trims every observation the model reads and removes a source of mistyped clicks. ## v48: Frames and shadow roots, seen whole. Teams choose who pays. *September 9, 2026* The agent reads and acts inside nested frames and shadow DOM as one page, keeps its evidence from step to step, and treats a verification widget as information rather than a wall. Workspaces gain multiple owners, team result views, and a chosen payer per run. - **Improved:** Nested frames and shadow DOM are read and acted on as one page. Elements inside same-origin and cross-origin iframes, open and accessible closed shadow roots, and slotted content get ids that the extension, the page tools, and the cloud runtime all resolve to the same element, so an id the agent sees is an id it can click. Hidden or inert controls and duplicate labels are left out, a newer snapshot always replaces an older one, and a capture that could not reach part of the page says so instead of claiming complete coverage. On the day this shipped, act rounds that only observed fell from 36% to 19% and rounds spent waiting from 27% to 12%. - **Fixed:** A checkbox inside a challenge iframe no longer vanishes from the snapshot. One workflow captured a reCAPTCHA checkbox but published a tree without it while reporting full coverage. The published tree and its coverage now agree, a wait is scoped to the document it targets instead of being answered by a hidden frame, and one recapture is allowed inside the original deadline while the page is still rearranging itself. - **Improved:** Verification widgets are evidence, not a wall. When a Cloudflare, hCaptcha, reCAPTCHA, or similar indicator is visible, the snapshot carries one neutral line about it and the agent decides whether your objective is actually blocked: keep going, wait for a pending check, take another route, or hand the step to you. Hidden or decorative indicators produce nothing, and the retired solve_captcha tool is gone in favour of ordinary click, hold, type, and pointer actions. - **Improved:** Uncertain actions are never replayed. A click or typing step that was dispatched but could not be confirmed is kept as uncertain rather than fired again, text is typed once through a single input channel, a synthetic Tab or Escape follows the page's real focus order and closes only an unambiguous dialog, and form submission goes through the browser's own validation instead of bypassing it. - **Improved:** A click that opens a new tab hands the plan over. Generated code and the planner used to keep working against the tab that opened the destination. The destination now flows through the executor, the sandbox, and the next planner step, and a popup is matched to the click that opened it rather than to whichever tab is newest. - **Improved:** Stuck runs get a review instead of a stop. Recovery evidence, whether progress, pending work, a verified failure, or unknown, now survives across act calls, planner repairs, and resumed workflows. After three suspicious rounds the agent is asked to reconsider in its next call, and a run is no longer ended merely for repeating an action whose conditions changed. - **Improved:** Screenshots keep their identity. A page screenshot records which document and capture it came from and when it was read, saved steps keep a compact receipt without the pixels, and the helper has one documented signature. Batches of up to 40 images across frames are described with per-image ids and errors, and a changed tile is read again rather than described from memory. - **New:** Workspaces gain multiple owners, roles, and team results. Owners assign owner, admin, and member roles and invite teammates, a member of several workspaces chooses which one pays for a run, and a Team executions view sits beside My executions with initiator, status, elapsed time, and net cost while personal history stays private. The extension's side panel offers the same workspace choice and team views. ([Compare plans](/pricing)) - **Improved:** Whoever pays for a run stays the payer. A run's account and payer are bound when it is admitted and carried through helpers, retries, continuations, and schedules; a refund returns to the original payer, and a scheduled run inherits the payer of the run that created it. Credit-source and workspace controls moved out of the task composer into account settings, shared between the extension and Cloud. - **Fixed:** Cloud runs sent to your extension could fail to start with an internal error when no credit source was selected. The default request encoded the unselected source as null, which the server rejected; both sides now treat it as no selection. The same fix covers opening the workspace view without a workspace id. - **Improved:** The Cloud dashboard is rebuilt around results. Workspace, personal, and team execution views share one layout in the site's paper and ink palette; the selected run reads as one scrolling document with Result, Steps, and Details; inline filters and labelled action menus replace the old popovers; a compact balance and plan action sit above the profile with Workspace restored under Work; and Cloud pricing reuses the public plan cards. - **Improved:** A cloud browser is never reused with someone's session left behind. Cleanup that failed or ran out of time used to report success; incomplete cleanup is now reported and that browser is retired. Public sessions read and write no synced cookies, and each selected browser profile keeps its own cookies, cache, and write-back. - **Fixed:** Rover on Wix finds your custom domain. Wix's published-URL list was being filtered so that some installations were authorised only for a placeholder domain. The full list is now read and domain rules are synchronised in one step, and verified domains are kept when Wix is unavailable. - **Improved:** Docs: the recordings guide links the recording-to-Subroutine walkthrough, adds a diagnostic path for invalid token or id failures, and clarifies that workspaces share credits, not sign-ins, site credentials, Google connections, or recording libraries. ([Read the docs](/docs)) ## v47: Sheets you can always read. Dialogs the agent can see. *September 8, 2026* Read a sheet through your own browser when the API says no, stop losing pop-ups from page snapshots, wait only as long as the page needs, and route around a slow provider before your run feels it. - **New:** Google Sheets you did not add through the picker can still be read. When the Sheets API refuses a spreadsheet, the extension captures the visible worksheet through your own signed-in session, works from it read-only, and tells you the one-click Add Sheets fix for full access. Sheet context now names every tab and labels columns with their letters, and switching tabs settles in about a second instead of eight. - **Improved:** Pop-ups and dialogs are no longer invisible to the agent. Apply flows and modals rendered inside adopted frames, such as LinkedIn Easy Apply, were being dropped from page snapshots, and a snapshot that timed out was presented as an empty but fresh page. A partial snapshot now ships before the deadline, a failed capture is retried, and the agent is told when a snapshot is incomplete. - **Improved:** Waiting is conditional and reports what it saw. Waiting for an element now matches on text or role instead of requiring a CSS selector, which used to fail silently and push the agent into blind sleeps. Waits end as soon as the page settles, cap at ten seconds instead of five minutes, and a click or type can wait for the element it needs inside the same step. - **Context:** Gemini models are now part of paid plans. Free Mode and free-plan runs use GLM 5.3 Flash with reasoning set to Low, in the extension and in Cloud. Your own Gemini key is unaffected. - **Improved:** Slow providers are routed around before your run feels it. Managed models are scored per host on time to first token, cache hits, and decode speed, and new runs move to a healthy host while a degraded one recovers instead of waiting on it. - **Fixed:** Model reasoning no longer leaks into answers. A thinking block that arrives inline with the reply is split out even when the model also returned structured reasoning, and a tool call is recovered from loose thought text only when its arguments parse completely, so an empty call is never fired. - **Fixed:** Code runs that end in a written answer complete instead of retrying. A model that answers in prose rather than a script now finishes the task, a script that does not compile is bounced with the exact helper it got wrong, and the run's earlier results are available to repair scripts. - **Improved:** Out of credits? You hear it before a browser is started. Cloud runs check your balance before provisioning a browser or calling a model, and a schedule on an empty account is paused with a reason instead of failing every run. - **Fixed:** Scheduled and triggered Free Mode runs are no longer refused. Background runs were sending a Free Mode claim without a sponsored card and being denied. The claim now travels only with a card, and a failed card auction is reported in the panel. - **Improved:** Long page, document, deck, and PDF generations stop at the deadline. A generation that cannot finish inside the request window now ends with a clear failure instead of running on after the timeout and spending credits on a result you never receive. - **Improved:** Image-heavy runs on GLM keep going. GLM accepts eight inline images per request, so a step with more now keeps the newest eight with placeholders for the rest instead of failing, and a large scanned PDF no longer brings the run down. - **Improved:** Screenshot descriptions come back faster. The agent's page screenshots are described in a few seconds at low effort rather than transcribed at length, on GLM for Free Mode and free accounts and on Gemini Flash Lite for paid plans. - **Improved:** ChatGPT sign-in picks a model your account can use. Retired GPT-5.4 selections migrate to Terra or Luna with a one-time notice, and a Codex model your account cannot run steps down from Sol to Terra to Luna on the same connection instead of failing. - **Fixed:** Workspace members see their workspace plan. Members were shown their dormant personal free tier, with an upgrade prompt, locked models, and Free Mode switched on by default. Plan and balance now reflect the workspace pool and the member's cap, live. - **Improved:** A Google Sheet the cloud browser cannot open says why. A sign-in or access wall used to end a Cloud run with an opaque code. The run now explains that the sheet needs link sharing or the Add Sheets picker, and when the other pages opened fine the sheet becomes a notice instead of a failure. - **Improved:** Rover runs owner-configured actions without a blanket confirmation prompt, and Wix site owners can upgrade from the pricing page even when the install was not finished or the account is bound to one site. - **Fixed:** Cloud API requests with a malformed payload are answered with a 400 and the reason, not a 500. ## v46: Free tier, rebalanced. *September 7, 2026* Free Mode stays free for everyday use. Welcome and referral credits now go to the people who stick around. - **New:** Xiaomi MiMo V2.5 Pro joins the free model set. Free Mode runs and free accounts can now pick it alongside MiMo V2.5, with a million tokens of context for pages that will not fit anywhere else. It counts toward the daily fair-use limit at its listed credit rate. - **Context:** New accounts start with 100 one-time welcome credits (previously 250). Free Mode is unchanged for everyday tasks: inference on the free model set still costs 0 credits with a sponsored card beside the result. - **Improved:** Referral credits are paid when your friend upgrades. You and the person you invite each still receive 250 credits, but the credits now land once the referred account is on a paid plan, or right away when the inviter already is. Credits already granted are untouched. - **Improved:** Free Mode tells you when today's allowance is used up. The daily fair-use limit is tighter, and when a run trips it you see a notice with the time Free Mode resumes and a one-click path to subscribe if you would rather keep going now. ## v45: The Cloud agent grows up. "Latest" finally means latest. *September 6, 2026* Close the tab without killing your run, ask for the last 24 hours and get the last 24 hours, and watch a repair pass reuse what the run already gathered instead of paying to scrape it twice. - **Improved:** A Cloud run no longer dies when you close the tab. Runs continue on the server and the dashboard picks them back up when you return. Reloading the page, losing your connection, or walking away mid run used to cancel the work partway through and still charge for it. Explicit Cancel still stops a run immediately. - **Fixed:** Ask for the last 24 hours and you get the last 24 hours. Web search can now be bounded to an hour, day, week, month, or year, or to explicit start and end dates, and every result comes back with the date it was published. Undated results are labelled as undated instead of being passed off as current, so a task asking for today's top stories can no longer quietly hand you an article from 2009. - **Improved:** A repair pass reuses what the run already gathered. When a task needs a second pass it now carries its collected data forward and reuses finished crawls, extractions, and searches instead of running them again. One run we looked at was re-crawling the same pages four times before it finished. - **Fixed:** Sheet writes keep your columns and your values. Structured rows are written straight to the sheet instead of being passed through a model first, which had been dropping fields and re-ordering columns alphabetically on the way. - **Improved:** Guidance you send while a run is going is actually applied. Messages sent mid run were being discarded unread on Cloud code runs. They now take precedence over the original wording of the task for the rest of the run. - **Improved:** Runs start faster and stop spinning. Planning begins before the browser has finished warming up, and a run that keeps asking the model the same question is now stopped instead of looping until it runs out of budget. - **Fixed:** Long extractions are bounded and billed correctly. A paginated extraction now stops at a page limit and tells you why it stopped, and a credit reporting bug that showed roughly twenty times the real cost on long runs is fixed. - **Improved:** Pages are read fresh. A scripted page fetch no longer serves you a copy your browser cached earlier, so re-running a task actually re-reads the page. - **Improved:** Cloud scraping hands back the links it found, so a task that harvests articles or listings gets the URLs directly instead of digging them out of the page text. ## v44: Workspaces arrive. GLM 5.3 Flash becomes the default. *September 2, 2026* Share one credit pool with your team, run on a faster default model, hand the agent whole files instead of excerpts, let it read scanned PDFs as pages, and never lose a run to runaway reasoning again. - **New:** Workspaces let a team share one pool of credits. Invite teammates by email from the Cloud dashboard, set a monthly credit cap per member, and watch the live pool balance in the extension and in Cloud. Workspaces are included from the Pro plan (or AppSumo Tier 3) and up: Pro includes 1 seat, Team 3, and Scale 10, and extra seats are $9.99 a month each and add 1,000 credits a month to the pool. ([Compare plans](/pricing)) - **Improved:** GLM 5.3 Flash is the default model in the extension and in Cloud. It answered faster than DeepSeek V4 Flash on every kind of model call in our production traffic and reads screenshots natively. Accounts still on the previous default are moved over once; every other model choice is left exactly as you set it, and you can switch back at any time from the model picker. ([Compare the models](/models)) - **New:** Attached files no longer get cut short. The agent now works from up to 100,000 characters of a document instead of 40,000, and when a file is longer than that it reads the rest on demand and searches inside the file for what the task needs, rather than guessing from a truncated excerpt. Word, Excel, and PowerPoint attachments are now extracted in Cloud runs too. - **New:** Scanned PDFs are read as pages. When the selected model can see images, a PDF with no text layer is handed over page by page instead of being transcribed first, and attached images go to the model as images. Text-only models keep the transcription path. - **Fixed:** A run can no longer disappear into a model's hidden reasoning for fifteen minutes. Every step now has an output budget and a hard time ceiling, and a step that hits either one fails over to the next provider instead of burning credits in silence. - **Improved:** Tasks that write data are verified before they finish. When a run has written rows to a sheet, the agent re-reads its output and takes a review pass even if review was turned off for that task, so a half-written sheet is not reported as done. - **Improved:** Free Mode now follows your plan. Paid accounts no longer start with Free Mode switched on or see the sponsored-card consent on their first run; free accounts keep it on by default, and your own toggle choice always wins. - **Improved:** Settings, schedules, and triggers can be managed from chat in the extension as well as Cloud. Schedules and triggers created from a conversation link straight to their Cloud pages, the Schedules, Triggers, and Settings menus are visible from the AI configuration panel, and the extension now scrolls to the result the moment a run finishes. - **Improved:** Your own proxy is easier to trust. Test a proxy from the routing settings before a run, and a run that cannot start through your proxy now names the proxy and the fix instead of failing with a generic fetch error. rtrvr never routes around a proxy you chose. - **Improved:** A leaner MCP tool list. The new list and check_results tools replace six near-identical inventory tools (the old names still work), agent and scrape run on your connected extension when you leave the target blank, the full page-action catalogue moved into an MCP resource so every connection starts smaller, and a malformed call is reported as your error rather than a server failure. ([MCP reference](/docs/mcp)) - **Improved:** Rover can be named. Site owners can rename their assistant from the Appearance view of the Rover dashboard, and the widget, its greeting, and its call to action pick up the new name together. - **Improved:** Results that span several sheets show as tabs in Cloud, and files a task downloads are surfaced with the result. ## v43: Recordings behave. Sheets edit in place. Stalls fail fast. *August 30, 2026* Recordings stop and save themselves instead of running forever, recordings now teach Cloud runs too, the agent can edit specific cells in your existing sheets, and a stalled model call fails over in seconds instead of minutes. - **Fixed:** Zombie recordings are gone. A screen recording now stops and saves itself when you close the side panel, caps at ten minutes with an automatic save instead of running unattended, and a visible REC badge shows whenever capture is active. Recordings that used to vanish if Chrome closed mid-save are now kept and uploaded once the browser is back. - **New:** Recordings can now be attached to Cloud runs. Record yourself doing a task once in the extension, then hand that recording to the cloud agent as a demonstration, the same way you attach files or tabs. - **New:** The agent can now update specific cells, rows, and columns in your existing Google Sheets. Fixing one value, replacing a single column, or clearing a range edits the sheet in place instead of appending, and the write is verified by re-reading the sheet before the task reports success. - **Improved:** Model calls now stream, so a provider that stalls mid-response fails over to a healthy one in seconds. The rare run that previously sat frozen for minutes on a hung connection now recovers almost immediately. - **Improved:** When the agent saves or updates one of your skills during a task, the chat now shows a skill chip you can click to see exactly what was written. - **Fixed:** Very large pages no longer break MCP page-data requests. Full page trees are stored out of band, so connected clients like Claude and Cursor can read big pages that previously failed on a size limit. ## v42: GPT-5.6 and GLM 5.3 arrive. Paperwork fills itself. *August 29, 2026* Two new model families with a free-plan tier in each, scanned PDFs and existing Google Docs filled in place, recurring automations you set up by asking, and long Free Mode runs that stay free. - **New:** GPT-5.6 Luna and GLM 5.3 join the managed model lineup, and each family has a tier that runs on the free plan. Luna brings frontier quality with quick tool calls and screenshot reading, and GLM 5.3 Flash is the lowest-cost option while still reading screenshots. GPT-5.6 Terra and GLM 5.3 are available on paid plans, and a new comparison page puts speed, cost, context, and vision support side by side. ([Compare the models](/models)) - **New:** Scanned and printed PDFs can now be filled in. A worksheet, form, or application that is only an image of a page, with no fillable fields anywhere in it, is completed in place and returned as a finished PDF instead of coming back as something rtrvr could not open. - **New:** An existing Google Doc can be filled in without being disturbed. Answers are inserted beneath each question or heading, so a worksheet, assignment, or form keeps its original text and structure rather than being overwritten. - **Fixed:** Long Free Mode runs stay free. The sponsored card now refreshes while a task is still working, so a run that continues past the old fifteen-minute window no longer starts quietly drawing down credits partway through. - **New:** Ask for a recurring or event-fired automation in plain language. "Check this price every morning" now creates the schedule itself and opens its detail page, and you can ask what past scheduled runs produced without opening a dashboard. - **Improved:** The agent now works pages with real mouse, keyboard, and scroll input. Hover menus open, list and kanban items can be dragged and reordered, sliders can be set, Enter submits a form and Tab moves focus, and the wheel scrolls maps and long virtual lists, including across embedded frames. Controls sitting under a cookie banner or modal are marked so they are not clicked blind, and date fields now state the format they accept. - **Improved:** Cloud tasks can run in parallel. Sending while a workflow is still going now opens a fresh chat and runs both at once instead of blocking, and a run that dies on the server resolves with a specific reason instead of spinning on "executing" indefinitely. - **Improved:** Watching a Cloud run is steadier. The live browser view connects before the agent starts so you see the first actions, it pauses and resumes instead of collapsing on a brief hiccup, and a result that did not fully finish is marked partial or expired with a note on what was missing. - **Improved:** When your own AI provider fails, you can retry on credits in one click. The card explains the actual reason, such as an exhausted quota and the date it resets, and the retry allows credits for that run only without changing your saved setting. - **Improved:** Cloud runs load ad-heavy pages faster. Ad and tracker requests are now blocked at the network level rather than only hidden from the agent, so pages read faster and use less of your proxy traffic. - **Improved:** Files a run downloads are surfaced in the result with a link to your downloads, and an API key, password, or one-time code is typed into a masked field that never reaches chat history or stored runs. The Schedules, Triggers, and connected-app menus now explain what they are for. - **Fixed:** A model that returns an empty response now fails fast and moves to your next key or the managed fallback instead of stalling the run. A dead provider key reports a specific reason rather than being retried and recharged on every planning pass. ## v41: Downloads come back with the run. Setup by conversation. *August 24, 2026* Files a task downloads now arrive with the result, you can change models and keys just by asking, and your skills are available to any connected MCP client. - **New:** Files a run downloads now come back with the task. Chrome runs point you to the exact files saved to your downloads folder, and Cloud runs keep a copy so you can retrieve them later. - **New:** Set rtrvr up by asking. Switch models, add your own provider key, or turn Free Mode on and off in plain language, without opening settings. - **New:** Your skills now work in any connected MCP client. The same saved know-how is available from Claude, Cursor, or your own tools, not just from rtrvr. - **Improved:** Every plan now includes 1,000 free enrichment and web search lookups each month before any credits are used. - **Improved:** Cookie access is now an optional permission you can decline, and sponsored cards are requested by our servers with personal details removed before anything reaches an advertising partner. - **Improved:** Large spreadsheets no longer crowd out a task. Sheet data is passed in a compact form, so long sheets leave room for the actual work and repeated runs start faster. - **Fixed:** Full page screenshots stitch correctly again, generated PDFs download reliably, and a task that stalls no longer blocks the next one from starting. - **Fixed:** Checkout collects tax and business details correctly on every plan and upgrade path. ## v40: Free Mode arrives. Skills replace Knowledge Bases. *August 19, 2026* Run tasks free with sponsored cards, teach rtrvr skills it loads automatically on later runs, and pick from new models on a redesigned site and a rebuilt Cloud dashboard. - **Context:** Free Mode brings free, ad-supported runs to Chrome and Cloud. Sponsored cards fund the work, usage stays within a daily fair-use limit, and a Settings toggle controls whether limited account data is shared with our advertising partner. - **New:** The skills library replaces Knowledge Bases. Save what worked as a personal or site-specific skill and rtrvr loads the right skills automatically on future runs. Skills are plain Markdown you can read and edit any time. - **New:** Thinking Machines Inkling and Xiaomi MiMo join the managed model lineup. A simplified model picker puts every model, reasoning control, and your own provider keys in one compact list. - **New:** Attach a file to a Cloud run from any MCP client. The new upload_file tool accepts a direct attachment or a URL, and the agent can use the file in forms, uploads, and later steps. - **Context:** The public site was redesigned end to end, with rebuilt pricing pages and a reorganized Cloud dashboard that makes tasks, schedules, tools, and results easier to find. - **Improved:** Authorize an MCP client with an email magic link from the website instead of copying keys, and add custom headers for servers that require them. - **Improved:** Images and files the agent creates during a run now render directly in the task result, ready to download or reuse in a later step. - **Fixed:** Content inside iframes no longer comes back blank in page snapshots, transient provider errors retry automatically, and a run that stops early keeps its completed work and returns a partial result. ## v39: Create and edit images inside a run. *August 9, 2026* Generate an image, revise a screenshot, or read a chart without leaving the task. Runs also use less context and return more useful partial results when a site gets in the way. - **New:** Generate a new image or edit an existing one during a task, then use the result in a form or upload. The same flow works in Chrome and Cloud. - **New:** Ask a specific question about a screenshot. A vision model can read labels, charts, maps, and canvases even when the selected task model only accepts text. - **New:** Ask rtrvr about its own features, plans, and pricing. Answers come from the current docs, FAQ, and changelog. - **Improved:** A missing Google Sheets permission no longer ends the task. rtrvr keeps the rows in a built-in table and lets you download them as CSV without repeating the permission prompt. - **Improved:** Page snapshots are 43% smaller, repeated steps reuse cached context, and the agent no longer rereads a page it can already see. The result is less model input and faster repeated work. - **Improved:** A run that reaches its safety limit now returns the completed work and a progress summary instead of a bare error. Final answers state the facts found during the run. - **Improved:** The model picker hides retired models, marks plan requirements, and routes free runs to the current default. MCP connections also support email-link authorization and custom request headers. - **Improved:** Cloud can start a clean chat in one click, run several tasks at once, and render tables, Sheets, and Markdown more clearly. - **Fixed:** Text now stays in Notion-style, Quill, and Monaco editors. Google sign-in also works more reliably on Edge and other Chromium browsers. - **Fixed:** Web search retries transient failures, long DeepSeek responses finish cleanly, older Gemini names no longer crash a run, and connected-tool sessions refresh without another sign-in. ## v38: Cloud catches up. Rover steps forward. *August 3, 2026* Run enrichment, search, planning, PDFs, and image work in Cloud as well as Chrome. Rover adds proactive greetings, shareable demos, new themes, and steadier narration. - **Context:** rtrvr is available on AppSumo with lifetime access, monthly rtrvr credits, and Rover sites. An AppSumo license now signs in directly. ([See the AppSumo offer](https://appsumo.com/products/retriever-ai/?p=1)) - **Improved:** Long tasks follow a complete plan, verify the result before stopping, and return the best partial result with a clear explanation when a site blocks the remaining work. - **New:** Cloud runs now include data enrichment, web search, PDF generation, and the same advanced planning path available in the extension. - **New:** Capture an entire page as a file, inspect it with a vision model, and pass it to a later step. Text-only models receive an automatic image description. - **New:** Extract the data behind directories and long feeds in one pass. If a batch is malformed, rtrvr re-extracts it into a clean result instead of mixing good and bad rows. - **New:** Use a provider key or a ChatGPT subscription in Chrome and Cloud. Connect Gmail, HubSpot, Notion, Slack, GitHub, Zapier, or a custom MCP server from the site. - **Improved:** Cloud keeps site sessions between runs and shows credit use for AI, browser time, proxy traffic, enrichment, and search while the task is running. - **Improved:** The Cloud composer accepts voice, can turn a rough request into a clearer brief, resumes after short questions, and previews generated PDFs and images in the result. - **New:** Rover adds five themes, automatic dark mode, more placement options, spoken greetings for returning visitors, and demos that can be shared by URL. ([Go to Rover Workspace](https://rover.rtrvr.ai/workspace)) - **Improved:** Rover narration continues across navigation and new tabs. Captured screenshots are files that later steps can attach, send, or upload. - **Context:** The first case study shows how Bright Data and rtrvr turned a signed-in event roster into an enriched outreach shortlist. ([Read the case study](/case-studies)) - **Fixed:** Large pages now fit the model automatically. Invalid custom model URLs fail when saved, Unicode text stays intact, duplicate tool calls stop, and long extension sessions use less memory. ## v37: Enrich a list. Search the web. Export the result. *July 14, 2026* Plans can enrich people and companies, search Google, generate a PDF, and continue from prior work. Claude Code, Codex, and other MCP clients can drive the signed-in browser again. - **New:** Call rtrvr.enrich from a plan to find people or companies, add available contact data, or collect records from supported public sources. Results write directly to the active Sheet. ([Read enrichment docs](/docs/enrichment-datasets)) - **Fixed:** Claude Code, Codex, and other MCP clients can again trigger the extension through mcp.rtrvr.ai. OAuth supplies access without a separate API key. ([Set up MCP](/docs/mcp)) - **New:** Use rtrvr.webSearch inside a plan to search Google and continue through the relevant results. Each query costs 0.15 credits. - **New:** Turn task output into a PDF with headings, tables, images, and links. Generated webpages now receive the collected rows as structured data instead of asking another model to retype them. - **New:** Copy the same clean page text that rtrvr reads from the Chrome context menu, ready for a chatbot, prompt, or code agent. - **Improved:** Continue a successful plan without starting over, reuse variables from earlier runs, and resume immediately after answering a multiple-choice question. - **Improved:** Stopping a run preserves completed Sheet writes. Navigation clicks, iframes, LinkedIn Easy Apply, long feeds, configurable timeouts, and parallel-tab limits are handled more reliably. - **New:** Connect Gmail so a task can fetch, draft, or send email as one step in the run. - **Improved:** The model catalog adds GPT-5.6 sol, terra, and luna, plus MiniMax, Tencent Hunyuan through OpenRouter, and Gemini Flash 3.5. - **Context:** AppSumo lifetime plans were announced ahead of launch, with monthly credits and Rover sites tied to the AppSumo license. ## v36: Plans become code. Sites become callable. *June 24, 2026* rtrvr can write and run a JavaScript plan against its browser harness, while Rover exposes more of a site to customers and outside agents. - **New:** Code-as-Plan reads the current page, writes a JavaScript plan, and executes it through the rtrvr harness. A planned sequence no longer needs a model call for every click. ([Read the technical note](/blog/code-as-plan-deepseek-flash-text-only-browser-agent)) - **New:** Rover can move beyond chat to handle identity, policy, payments, human handoff, and product actions owned by the site. ([Read the product thesis](/rover/blog/the-web-needs-headless-website-agents)) - **New:** Rover Scout can draft ACP and UCP payment surfaces plus sign-in and account actions from the site's real flows. ([Run Scout on a site](https://rover.rtrvr.ai/workspace/all/home)) - **New:** Rover Workspace brings voice, instructions, policies, knowledge, tools, analytics, reviews, interviews, memory, and webhooks into one owner surface. ([Go to Rover Workspace](https://rover.rtrvr.ai/workspace)) - **Improved:** Managed DeepSeek becomes the default planner when no model key is supplied. The hosted route uses a US provider configured for zero data retention. - **Improved:** Selected-tab state, files, PDFs, clicks, typing, uploads, iframes, shadow DOM, pause, cancel, retry, and code-plan review are more reliable on difficult sites. - **New:** A generated code plan can call rtrvr.scrape({ urls }) to send a list of pages to credit-aware Cloud browsers. - **Context:** Work began on Rover distribution for Wix, Webflow, AppSumo, and an rtrvr API listing in the OKX Agent Marketplace. ## v35: Guide Rover while it works. *May 15, 2026* Correct an in-progress Rover run by typing or speaking. The run keeps its place and applies the guidance at the next safe step. - **New:** Call rover.sendFeedback(text, opts?) during an active run. Accepted guidance returns an id and reports whether it was queued, applied at a step, or dropped after the run ended. ([See the API example](/rover/docs/examples)) - **New:** The composer stays available during a run for typed or spoken guidance. Sending feedback does not create a second task. - **Improved:** Mid-run guidance is limited to 16 items of 500 characters and cleaned before it reaches the agent, reducing the risk of control text being treated as instructions. - **Fixed:** Rover now speaks follow-up questions, final responses, and tool results when voice is on, including second messages in the same conversation. ## v34: Build a tool once. Run it anywhere. *May 8, 2026* Record a useful action, inspect the generated tool, then run it from Chrome, Cloud, a schedule, a trigger, or an MCP client. - **New:** Connect HubSpot, Notion, Slack, GitHub, Zapier, and Google Calendar as MCP tools from the product. - **New:** Private Mode can disable run logs and accessibility-tree storage, keep task state in the extension, and send uploaded files as bytes for private and non-Gemini runs. - **Improved:** Monthly credits refresh at the start of each cycle instead of accumulating as separate grants. - **New:** Email-link sign-in becomes the default account path. Password signups are rejected by the backend. - **New:** Tools created from recordings or Cloud runs now appear in shared tasks, task detail, schedules, and triggers. They can create Sheets, append data, read pages, and call connected or MCP tools. ([Read custom tool docs](/docs/tool-calling#custom-javascript-tools)) - **Improved:** Generated tools use roles, labels, and accessibility data so page changes are less likely to break them. Temporary tools, complex MCP schemas, and sandbox cleanup also behave more predictably. - **Improved:** Save a useful subroutine as a shortcut, pin it, call it from Claude or ChatGPT, or run it later from a schedule or trigger. - **Fixed:** LinkedIn and Instagram no longer receive duplicate text, Calendar MCP checks recover correctly, and recordings capture documents even when recording has just begun. - **New:** An outside assistant can discover Rover instructions, hand off a task, and let Rover complete the action in a Cloud browser. ([Read the handoff note](/rover/blog/protocol-vs-prompt-injection)) - **New:** Share a URL that opens a site with a Rover task already loaded, ready for a customer or teammate to try. ## v33: Turn a recording into a reusable action. *April 15, 2026* Capture the network request behind a repeated action, call it without another model turn, and trigger the same work from WhatsApp, MCP, or Cloud. - **New:** A recording can capture the network request behind an action and save it as a deterministic subroutine. The agent can call the saved action without spending tokens on each replay. - **New:** Sign in with an OpenAI or Anthropic subscription and use the plan you already pay for. Provider API keys remain supported. - **New:** Start a run, trigger a schedule, or check scheduled results from WhatsApp. The same commands work from the planner and MCP. - **New:** Add URLs from Cloud to scrape and index them into a Knowledge Base. MCP clients can list, query, and update those stores. - **New:** Copy the full accessibility tree of a tab for a Knowledge Base or another model, dictate prompts with Chrome transcription, and attach DOC, DOCX, XLSX, and PPT files. - **Improved:** Extraction rows can stream directly to a shared Google Sheet. Cloud panels also provide a copyable API request for rerunning the same execution. - **Improved:** The composer now uses one attachment control for files, tabs, Sheets, and Knowledge Bases. Suggestions adapt to the site in the active tab. - **Context:** Rover Analytics was introduced to show visits, runs, trajectories, outcomes, feedback, and memory notes across human and agent traffic. ([Read the Rover Analytics note](https://rover.rtrvr.ai/blog/roverbook-posthog-for-ai-agents)) - **Context:** Two research notes explain the agent web protocol stack and why declared site protocols are safer than prompt injection. ([Read the protocol research](https://rover.rtrvr.ai/blog/agent-web-protocol-stack)) - **New:** Rover Preview Helper can supply the site-side runtime for a custom agentic Chrome extension. ([Read Preview Helper docs](/rover/docs/instant-preview)) - **Context:** In exploration: a public library for community subroutines, templates, and datasets, plus a paid in-memory mode with no retained run data. ## v30: Find the API behind the page. *March 19, 2026* Observe the requests a site makes, identify the useful GraphQL or XHR call, and turn it into a script that can collect the same result at scale. - **New:** Vibe Hacking connects page interaction to the underlying network calls, then drafts a reusable extraction script from the requests that matter. ([Read the launch note](/blog/vibe-hacking-rover-gemini-flash-lite)) - **Improved:** Sandboxed code can replay a discovered request with the signed-in browser context, reducing the setup needed for authenticated extraction. - **Context:** In exploration: save network scripts as tools, run them in Cloud, and combine API calls with DOM parsing when neither source is complete on its own. - **New:** Rover can add a callable agent layer to a site and hand the same capability to browser automation, an extension, or an Electron app. ([Read Rover docs](/rover/docs)) - **Context:** In exploration for Rover: WebMCP, site action indexing, recorded demos, voice-led accessibility, and URL-triggered site actions. - **Improved:** Gemini Flash Lite becomes the default for lightweight work. Google AI Studio includes up to 500 requests a day on its free tier. ## v29: Bring your model. Connect MCP in the extension. *February 26, 2025* Use a hosted provider, a local model, or a direct MCP connection without editing a config file. - **Context:** Rover launched on Product Hunt with a one-month promotion for Product Hunt users. ([See the Product Hunt launch](https://www.producthunt.com/products/rtrvr-ai?launch=rover-by-rtrvr-ai)) - **New:** Add a key for OpenAI, Anthropic, OpenRouter, Moonshot, MiniMax, DeepSeek, Z.ai, or another supported provider. Gemini can take over when the selected provider fails. - **New:** Point the extension at an OpenAI-compatible local endpoint such as Ollama, LM Studio, or vLLM. - **New:** Connect HubSpot, Notion, Slack, GitHub, and other MCP servers from the extension. Servers without dynamic registration can accept a client id and secret directly. ## v28: Rover arrives. Repetitive runs get cheaper. *February 19, 2025* Put an agent inside a site, trigger browser work from notifications, and reuse the same browser state from Chrome, Cloud, CLI, MCP, or WhatsApp. - **New:** Install Rover with one script tag so customers can ask for help and let the agent click, fill, and navigate inside the product. ([Meet Rover](/rover)) - **New:** Use Rover for guided onboarding, in-product support, setup, and adoption flows that end in a completed product action. ([Read the product note](/blog/10-billion-proof-point-every-website-needs-ai-agent)) - **Improved:** Choose act, extract, or crawl directly when a planner is unnecessary. Token caching and extraction heuristics reduce the cost of repeated runs. - **New:** Browser Triggers watch selected tab notifications and start a workflow when a site has no webhook. ([Read trigger docs](/docs/triggers)) - **New:** Turn open tabs into a searchable Knowledge Base, refresh the sources, and share the result through an embedded chat. ([Read Knowledge Base docs](/docs/knowledge-base)) - **New:** Sync the cookies you choose from the extension to Cloud so later browser runs can stay signed in. - **New:** Start rtrvr from the command line and expose recordings, tools, and Knowledge Bases to CLI and MCP clients. ([Read CLI docs](/docs/cli)) - **New:** Start browser runs from WhatsApp and send a webhook when a workflow completes. - **Improved:** The docs, chat Markdown, and common extension flows received a complete usability pass. ## v26: Rotate your own keys. Start from a template. *January 16, 2025* Keep a run moving through provider rate limits, launch a common job without rewriting the prompt, and watch Cloud browsers while they work. - **New:** Add more than one model key and rotate to the next key when a provider rate limit is reached. - **New:** Gemini 3 Flash and Pro become available for rtrvr runs. - **New:** Start a common workflow from a template and edit the inputs before the run begins. ([Browse workflow templates](/retrieve)) - **New:** Watch parallel Cloud browsers in a live VNC view. - **Improved:** Replay a workflow through API or MCP, pass a URL or uploaded file into the run, and reuse a saved recording id. - **New:** Connect to mcp.rtrvr.ai with OAuth and call the Cloud scrape and agent APIs without copying an API key. - **Improved:** Files are easier to see and remove from task context. Google Drive permission is requested only when a run needs it. - **Fixed:** Improved Sheets planning, captcha iframes, shadow DOM handling, Comet sign-in, and first-run onboarding. ## Watch Cloud browsers work in parallel. *January 6, 2025* See each browser, take control when needed, and share the collected result without sending a file around. - **New:** Open a live VNC view for a Cloud browser and take control during the task. - **New:** Solve supported captcha challenges from the page structure without a separate captcha service. - **New:** Run many Cloud browsers in parallel. The release was tested with 53 concurrent browsers. - **New:** Start a template from the retrieve library and receive a structured result. ([Browse workflow templates](/retrieve)) - **New:** Share an extraction result with one link. - **Improved:** Cloud adds Gemini 3 Pro and Flash with fallback to Gemini 2.5. ## v25: Monitor a page on a schedule. *December 20, 2024* Revisit a page at a chosen interval, append new rows to a Sheet, and reuse an existing tab when the job should keep its session. - **New:** Schedule repeated page extraction and append each result to a Google Sheet. A schedule can reuse an existing tab. - **Improved:** The page parser reads more content from shadow DOM and cross-origin frames. - **Improved:** API and MCP triggers recover more reliably, and long Sheets workflows receive better planning. - **Improved:** A one-tab crawl now reuses the active tab instead of opening another. - **Fixed:** Fixed extension subscription management, schedule execution, adaptive shortcuts, referral credit redemption, and Gemini fallback errors. - **Fixed:** A newly created Sheet no longer adds itself to the selected browser tabs. - **New:** The agent can complete supported basic captcha challenges. ## v24: Upload a file. Trigger the extension by API. *December 3, 2024* Carry a file from the chat into a site, or start a multi-step browser action from a curl request. - **New:** Attach a file in chat and let the agent upload the same file to a site, including multi-step application forms. - **New:** Trigger an extension action from an API request. ([Read extension API docs](/docs/extension-mcp-server#available-tools)) - **Context:** The execute API was introduced for prompt-led, multi-step browser actions. - **Improved:** The accessibility tree uses less memory while covering more of the page. - **Fixed:** Added Gemini key validation and fixed the crawl agent, shortcut editor, and several extension UI paths. ## Call rtrvr from n8n. *November 26, 2024* Put a browser run inside an n8n workflow through the Cloud API or a remote MCP connection. - **Context:** The public Cloud API becomes available for browser tasks. ([Read API docs](/docs/api-reference)) - **New:** A new n8n example starts a Cloud browser through the API. ([Watch the API example](https://www.youtube.com/watch?v=FOmwVh1tJw0)) - **New:** A second n8n example triggers the browser through MCP. ([Watch the MCP example](https://www.youtube.com/watch?v=pcPRZsBs2aQ)) - **New:** The reference workflow starts from a calendar event, researches a LinkedIn profile, drafts contextual outreach, and continues across sites. ## v22: Tools return. Browser actions get steadier. *November 21, 2024* Connect an MCP server, create a reusable tool, and run Sheets or scheduled work with fewer duplicate actions and clearer errors. - **New:** Connect MCP servers, create a tool yourself, or let the agent draft a reusable tool during a run. - **Improved:** Sheets workflows write each row as it completes instead of waiting for the full run. - **Improved:** Browser actions avoid duplicate clicks and submissions, including repeated comments on social sites. - **New:** Resize the chat composer by dragging it and return to the default height with a double click. - **Improved:** Errors, warnings, cancellation, settings, and referral information are easier to understand. - **Fixed:** Fixed credit totals, schedules, Gemini key validation, and the billing portal for existing subscribers. ## v21: Drive the browser from your MCP client. *November 13, 2024* Read a page or take an action through MCP while using the model subscription in your own assistant. - **New:** The getPageData and takePageAction MCP tools let an outside assistant read and control the active browser without spending rtrvr model credits. - **New:** Choose exactly which browser tools an MCP client can call. - **New:** Add images and files to a task by dropping them into chat or choosing them from the file picker. - **New:** Replay a completed workflow from its model message and create, edit, or share a shortcut from one dialog. - **Fixed:** Non-Chrome browsers keep their authenticated session, and Gemini keys save with immediate validation feedback. ## Run the browser from Cloud, API, or MCP. *November 12, 2024* Record a task in Chrome, replay it in Cloud, or let another product trigger the same browser through an API, webhook, or MCP call. - **Context:** The extension can expose the active browser as an MCP endpoint for an outside assistant. - **Context:** Claude and ChatGPT can call rtrvr browser tools through MCP while using the customer's existing assistant subscription. - **New:** Start a workflow from an API call, web chat, webhook, automation service, or WhatsApp message. - **New:** Run recorded workflows across many Cloud browsers in parallel. - **New:** Record a task in the Chrome extension, then replay the saved workflow in Cloud.