RPA (Automation)

Build a process once — a sequence of steps, visually, no code — then run it on any profile. It drives the exact same isolated, fingerprinted browser a normal launch would, so it's indistinguishable from you clicking it by hand.

Building a process

Open ProcessesNew Process, name it, and add steps from the command palette one at a time. Steps run top to bottom; if and loop can nest other steps (including more if/loop) inside themselves.

CSS & XPath selectors

Anywhere a command takes a selector, you can use either a normal CSS selector or an XPath expression — XPath is auto-detected from its shape, no prefix needed:

PatternDetected as
//div[@id='x']XPath (absolute-ish)
/html/body/divXPath (absolute)
./spanXPath (relative)
../td[2]XPath (parent axis)
(//a)[1]XPath (parenthesized, for indexing)
anything elsePlain CSS selector

This means you can paste DevTools' "Copy XPath" output directly into any selector field with no changes.

Command reference

Navigation & interaction
CommandParametersWhat it does
gotourl, waitUntil?Navigate to a URL. waitUntil is load, domcontentloaded (default), networkidle0, or networkidle2.
clickselectorClick the matched element.
typeselector, text, delayMs?Type text into the matched element, optionally with a per-keystroke delay for a more human pace.
presskeyPress a single keyboard key (e.g. Enter, Tab).
keyCombo Keys combinationcomboA modifier chord: select all, copy, paste, or reload. Uses ⌘ on a macOS-fingerprinted profile and Ctrl otherwise — read from the profile's spoofed OS, not the host's.
focus FocusselectorPut the cursor in an element without clicking it — useful when a click would trigger a handler or dismiss an overlay.
hoverselectorMove the mouse over the matched element.
selectselector, valueChoose an option in a <select> element by value.
scrollselector? or x?/y?Scroll a specific element into view, or scroll the page to absolute coordinates.
waitmsPause for a fixed number of milliseconds.
waitForSelectorselector, timeoutMs?Wait for an element to appear before continuing.
waitForRequest Request to finishurlPattern, timeoutMs?Wait until the page makes a network call whose URL contains urlPattern and it completes. A barrier only — use the listener commands if you also need the response body.
Data & debugging
CommandParametersWhat it does
screenshotnameCapture the current page, saved under the given name in the run's Debug log.
extractTextselector, variableRead an element's text content into a variable for later steps to use.
extractAttributeselector, attribute, variableRead one attribute's value (e.g. href) into a variable.
evaluatescript, variable?Run raw JavaScript in the page and, if given, capture its return value into a variable. Times out after 30 seconds so a stuck script can't hang the whole run.
Tabs & browser
CommandParametersWhat it does
newTabOpen a new tab and switch to it.
closeTabClose the current tab and fall back to another. Refuses to close the last remaining tab.
closeOtherTabs Close Other TabsClose every tab except the current one.
switchTabindexSwitch to the tab at the given index.
goBackNavigate back in history.
refreshReload the current page.
closeBrowserClose the whole browser, ending the run.
Page info
CommandParametersWhat it does
getUrlvariableCapture the current page URL into a variable.
getTitlevariableCapture the current page title into a variable.
Get Data
CommandParametersWhat it does
getFocusedElement Focused ElementvariableWhatever currently has focus (document.activeElement) — its value for a form field, otherwise its text content.
getElementHtml Elementselector, variableThe matched element's full outerHTML — distinct from Extract text (text only) and Extract attribute (one attribute only).
getCookies Get Page CookievariableEvery cookie visible to the current page, as a JSON array string.
clearCookies Clear Page CookieDeletes every cookie visible to the current page.
saveToFile Save to Txtvariable, filenameWrites a variable's current value to a file, sandboxed to this profile's own RPA-files folder — a filename with ../ in it is stripped down to just the filename, it can never write outside that folder.
importFromFile Import Data from Txtpath, variableReads a file's whole text content into a variable, from that same sandboxed folder.
getClipboard Clipboard ContentvariableReads the system clipboard.
setClipboardtextWrites to the system clipboard.
startListener Listener Requestname, urlPatternStarts watching network responses whose URL contains urlPattern, capturing the latest match's body — non-blocking, the process keeps running while it watches.
awaitListener Listener Request Responsename, variable, timeoutMs?Waits (30s default) for the named listener to have captured a response, then saves its body into a variable.
stopListener Stop Listener RequestnameStops watching and discards a named listener.
downloadFile Download Fileselector, saveAs?, variable?Clicks an element expected to trigger a browser download, waits for the file to finish landing in this profile's downloads folder, optionally renames it, and can save the resulting path into a variable.
Not yet available: Save/Import to Excel, Email, Verification Code (inbox reading), and the Third-Party Tools integrations (2Captcha, Google Sheets, OpenAI) shown in some other RPA tools' command lists — these need either a new file-format dependency or your own account credentials/API keys for that service, so they're a deliberate next step rather than a silent gap.
Flow control
CommandParametersWhat it does
ifcondition, then, else?Branch on a condition (see below). else is optional — with no matching branch, execution just continues to the next step.
loop For Loop Timescount, bodyRepeat a set of steps count times, up to a cap of 10,000 iterations (enforced even if you paste a larger value via Import). A malformed count (zero, negative, fractional) safely floors to 1.
forElements For Loop Elementsselector, indexVariable, bodyRun once per element currently matching selector (also capped at 10,000). Each iteration sets indexVariable to that element's 0-based index as a string.
forData For Loop Dataitems, itemVariable, indexVariable?, bodyRun once per line in a fixed list typed into the step itself. Each iteration sets itemVariable to that line, and indexVariable (if given) to its 0-based index.
whileLoop While Loopcondition, bodyRepeat while condition holds, re-checked before every iteration. Also capped at 10,000 iterations — unlike the loops above, a condition has no natural bound of its own, so this is what stops a condition that never flips from spinning forever.
exitLoop Exit LoopImmediately stops the nearest enclosing loop (any of the four above) and continues with whatever comes after it — like break in a normal language. Works from inside a nested if too. With no enclosing loop at all, it just stops the remaining steps in its own sequence.
Third-party tools
CommandParametersWhat it does
googleSheet Google Sheet operation, spreadsheetId, worksheetName, scope?, firstRowIsKey?, variable?, values?, append? Read, write, or clear spreadsheet data — see the setup section below.

Using loop variables — ${...}

forElements, forData, and whileLoop are only useful if body steps can act on the current item — so any selector, text, URL, or value field elsewhere in the process can reference a captured variable with ${variableName}, substituted fresh on every iteration. This works with any variable — one set by extractText/extractAttribute/evaluate earlier in the process too, not just a loop's own index/item variable.

{ "type": "forData", "items": ["alice@example.com", "bob@example.com"],
  "itemVariable": "email",
  "body": [
    { "type": "type", "selector": "#email", "text": "${email}" },
    { "type": "click", "selector": "#submit" }
  ]
}
Not interpolated: evaluate's script (it's raw JavaScript — read a variable there via the run's own variable bag instead) and condition values (those compare against literal text).

Conditions (if / whileLoop)

ConditionParametersMatches when…
elementExistsselectorAn element matching the selector is present.
elementNotExistsselectorNo element matches the selector.
variableExistsvariableThe variable has a non-empty value. An extraction that found nothing saves "", which counts as not existing — that's the main thing this is for.
variableNotExistsvariableThe variable is unset or empty.
variableEquals / variableNotEqualsvariable, valueExact text match (or its inverse).
variableContains / variableNotContainsvariable, valueSubstring match (or its inverse).
variableGreaterThan / variableGreaterOrEqual / variableLessThan / variableLessOrEqualvariable, valueNumeric comparison — both sides parsed as numbers, so "50" correctly ranks above "9". A non-numeric value makes the condition false rather than falling back to a text compare.
variableOneOf / variableNotOneOfvariable, valueThe variable exactly matches one entry in a comma-separated set (or doesn't).

Data Processing

Pure variable transforms — no page interaction. Useful for reshaping whatever you extracted before branching on it.

CommandParametersWhat it does
extractRegex Extract from Txtvariable, pattern, saveToPulls the first regex match out of a variable. With a capture group, saves group 1; otherwise the whole match. No match saves an empty string rather than failing — branch on it with a variableExists condition.
toJson Convert to JSONvariable, saveToValidates a variable as JSON and re-saves it normalized. Required before extractField / randomExtract, which both refuse non-JSON input with a message saying so.
extractField Extract Fieldvariable, path, saveToReads a key or array index out of a JSON variable. Supports dotted paths — user.name, items.0.id — so a nested value doesn't need a chain of steps. An object/array result is re-serialized as JSON so you can keep digging.
randomExtract Random Extractionvariable, saveToLike extractField, but picks a random entry instead of a named one.

Profile Information

Writes back to the profile the process is running against — handy for recording an outcome that a later run (or you) can see in the Profiles grid.

CommandParametersWhat it does
updateProfileRemark Update Profile Remarktext, modeWrites the profile's notes. append adds below the existing text, replace overwrites. The text goes through ${variable} interpolation.
updateProfileGroup Update Profile TaggroupMoves the profile into a group — this app's equivalent of AdsPower's profile tag.

Google Sheets

The Google Sheet action reads a sheet into a variable, writes rows back, or clears a range — so a process can pull its input data from a spreadsheet and log its results to one. Combined with For Loop Data, that's the usual "run this once per row" pattern.

One-time setup

Access uses a Google service account — a robot Google account you create and share sheets with.

  1. In the Google Cloud console, create (or pick) a project and enable the Google Sheets API.
  2. Go to Credentials → Create credentials → Service account and create one.
  3. Open the new service account → Keys → Add key → Create new key → JSON. A .json file downloads.
  4. In Parallel, open ⚙ Settings → Google Sheets, paste the entire contents of that file, and click Connect. Parallel verifies the key immediately.
  5. Settings then shows the service account's email address. Open any spreadsheet you want to use, click Share, and share it with that address — Viewer is enough to read, Editor is required to write or clear.
The key never leaves your machine. It's encrypted at rest with your OS keychain and is deliberately excluded from cloud sync — unlike processes and schedules, which do sync, a private key stays on the machine you pasted it into. You'll need to paste it again on a second machine.

Fields

FieldWhat it does
Operation typeRead, Write, or Clear.
Spreadsheet IDFrom the sheet's URL — the part between /d/ and /edit.
Worksheet nameThe tab's name, e.g. Sheet1. Names containing spaces are handled for you.
ScopeOptional A1 range within that tab, e.g. A1:B10. Blank means the whole sheet.
The first line is set to key Read onlyReshapes the result into objects keyed by the header row instead of a raw grid of rows.
Save to Read onlyVariable the result is stored in, as a JSON string.
Values Write onlyOne row per line, cells separated by commas. Every cell goes through ${...} interpolation.
Append Write onlyAdds rows after the last existing row instead of overwriting the range — the right choice for logging results.

Example: run a process once per row

Read a sheet of accounts, loop over the rows, and append a result line for each — the shape most Sheets-driven automations take.

1. Google Sheet — Read
     Spreadsheet ID: 1AbC…                Worksheet: Accounts
     ☑ The first line is set to key       Save to: rows

2. Run JavaScript
     Script: JSON.parse(vars).map(r => r.email).join('\n')
     (turn the JSON into one email per line for the loop below)

3. For Loop Data — items: the emails, itemVariable: email
     └─ Go to URL:  https://example.com/login
     └─ Type:       selector #email, text ${email}
     └─ Google Sheet — Write
          Worksheet: Results   ☑ Append
          Values:    ${email},done
A read stores JSON text, since process variables are strings. To iterate it, parse it with a Run JavaScript step first (as above) — For Loop Data takes a plain list, not JSON.

Process settings

SettingOptionsWhat it does
GroupAny group, or noneShares the same Groups list as profiles.
On errorSkip (default) / StopSkip: a failed step is recorded and the run continues past it — useful when an occasional optional element (a cookie banner) shouldn't abort everything after it. Stop: halts at the first failure, like an unhandled exception would stop a hand-written script.
After task completesClear tab / Save tab, and Quit Browser / Keep browser openTwo independent choices for what happens to the browser once the process finishes.

Running & debugging

Click Debug in the process editor's header — a popup lets you pick which profile to run it on, then launches (or reuses an already-running) profile and executes the process against it.

Every run is recorded in that process's Debug logs — the last 20 runs per process, showing the full step tree exactly as it executed, including which nested steps inside an if or loop ran and whether each one succeeded or failed. Screenshots taken mid-run appear inline.

Run logs are local-only. They stay on the machine that ran the process and are never synced to the cloud, even though the process definition itself is.

Import / export

Export a process to JSON to share it, back it up, or version it outside the app. Import accepts pasted JSON with a choice of Append (add to your existing processes) or Replace (overwrite). Since a hand-pasted or scripted import bypasses the editor's own UI limits, the same 10,000-loop cap is enforced when the process actually runs, not just when you build it in the editor.

Signed in, processes sync to your account the same way profiles do — build one on one machine, sign in elsewhere, and it's already there.