CLI
Projects, Profiles and Sessions
Section titled “Projects, Profiles and Sessions”See Projects, Profiles and Sessions for explicit Project scope, independent Session state, deliberate sharing and configuration reapply. Profile names do not imply shared state. Public management uses Session IDs; group resource and reset APIs are not supported.
The recommended CLI is the rel binary bundled in the installed REL app and
linked from a writable directory already in PATH. Use REL → Settings… →
General → Install Command Line to create the link. If no safe destination is
available, REL leaves the filesystem unchanged so you can create the link
manually. The matching public client can also be installed from source:
# From a rel-tools checkout matching the app's API:cargo install --path crates/rel-cliThe CLI is a thin client built on the typed rel-client
Rust crate. Ordinary user-facing commands map to RPC v1 operations;
rel read and the profile/proxy transfer commands are bounded client-side
compositions of those operations. The standalone rel-mcp binary adapts a
focused subset of the same operations to stdio MCP; neither client implements
another browser or reads application data directly.
Related documents: Actions, MCP, SDK, and RPC.
When session creation omits a profile, REL uses Settings → General → Default Profile, or Custom if the preference is unset. Explicit profile choices always take precedence.
App discovery
Section titled “App discovery”When the local agent is unavailable, the CLI starts REL using REL_APP_PATH if
set, otherwise its enclosing app bundle, /Applications/REL.app,
~/Applications/REL.app, or the app registered with macOS under me.rel.Rel, in
that order. An invalid override reports an error without falling back. For a
custom location:
REL_APP_PATH="/Volumes/Apps/REL.app" rel navigate https://example.comCommands
Section titled “Commands”rel healthrel statusrel navigate [URL] [options]rel read [URL] [--query TEXT] [options]rel perform ACTIONS [options]rel capture [options]rel URL [options]rel capture URL [options]rel page attach [URL] [options]rel page action PAGE_ID --action JSON [options]rel observe [--page-id ID] [--mode semantic|hybrid|visual] [options]rel observation action OBSERVATION_ID --request JSONrel proxy listrel proxy get ALIASrel proxy create --alias ALIAS --upstream-host HOST --upstream-port PORT [options]rel proxy update ALIAS [options]rel proxy delete ALIASrel proxy export ALIAS [--output PATH]rel proxy import FILE [--alias ALIAS]rel profile listrel profile create --name NAME [--proxy ALIAS] [--viewport PRESET] [--browser-identity private|native]rel profile export NAME [--output PATH]rel profile import FILE [--name NAME]rel session listrel session get SESSION_IDrel session create [options]rel session update SESSION_ID [options]rel session pause SESSION_IDrel session play SESSION_IDrel session delete SESSION_IDrel-mcprel --help | -hrel --versionrel --agent exists only in the proprietary binary bundled with the REL app.
It is not part of the public rel-cli package.
health and status inspect the currently running agent without launching the
app. Every other ordinary CLI command, including proxy reads and session reads,
starts the REL app in the background when its agent is unavailable. rel-mcp
starts its stdio protocol server without launching the app; its operational
tools start REL lazily after their arguments have been validated.
REL_AGENT_PORT overrides the default local port, 17319.
rel navigate and rel page attach use REL_SESSION_URL when their otherwise
required positional URL is omitted. An explicit URL always wins. Argument-free
rel read and rel capture retain their current-page behavior and do not
reload from REL_SESSION_URL.
When a browser command targets a session while REL is in the background, REL selects that session by default without activating the app. Turn off REL → Settings… → General → Follow browser commands to keep the current session selected instead. Internal session synchronization and read-only resource commands do not change the selection.
REL Free supports up to two tab groups with two Sessions each (four Sessions
total), one custom Profile, and one Proxy. A third tab group or a third Session
in a group requires Pro. Close a Session or group to free its capacity.
Mutations that require
REL Pro fail with the non-retryable PRO_REQUIRED RPC error. Register Pro in
REL → Settings… → Plan to remove these limits. Read and delete operations
remain available so stored resources can be inspected or reduced after a
downgrade.
Capture with a URL is the default command: rel [options] URL [options].
The explicit rel capture [options] URL [options] form is equivalent. Options
can appear before or after the URL, using either --profile NAME or
--profile=NAME. For example, capture a page in a new Session created from the
saved RYM Profile:
rel --profile=RYM https://rateyourmusic.com/artist/nugreth/Creating a Session preserves existing Sessions. Capture events omit the obsolete
closed_session_ids field.
The named Profile must already exist; use rel profile list to list Profiles.
Argument-free
rel capture instead captures the current shorthand page selected by
rel navigate. Use rel status for service diagnostics and the app’s Logs view for events.
The app’s Logs view displays each event on one compact line. Browser request
summaries show the method, URL, HTTP status, failure or block reason, and duration
when available. Select a row to inspect the formatted JSON record, including its
structured data fields. Copy JSON (or Command-C) copies selected records as
newline-delimited JSON, one object per line, preserving multiline messages and
metadata for diagnostic tools. Session log files already use this NDJSON format.
rel observe returns bounded rendered semantics and observation-scoped element
refs. --mode=hybrid adds a synchronized viewport PNG resource; visual
returns minimal semantics plus the image. --page-id targets an attached page,
while the default uses the current shorthand page and accepts --session-id.
Use a returned ref without inventing a selector:
rel observe --mode=semanticrel observation action OBSERVATION_ID \ --request='{"ref":"e1","action":"click","mode":"semantic"}'The action response contains a new observation. Old observation refs fail with
OBSERVATION_STALE after navigation, document replacement, or bounded eviction.
rel read is the smaller retrieval path for reading and research. It observes
the current shorthand page, or navigates first when URL is supplied, then
returns query-ranked content and links as bounded Markdown. A supplementary heading
outline covers headings omitted from the selected content, and an unqueried read samples across loaded documents
instead of stopping at their first sections. It is always
semantic-only and does not return action refs or an image. --max-chars
defaults to 12000 (range 512–32768), and --max-sections defaults to 24 (range
1–100). Use rel observe instead when interaction refs or visual verification
are needed:
rel read https://example.com/docs --query="installation" --max-chars=6000rel read --session-id=Session1 --query="current plan"Queries preserve underscored and qualified identifiers, so Archive.copy_into
does not broaden into every mention of Archive. Exact matches rank above weak
word prefixes, with nearby descriptions retained within both output limits
before the selected blocks are arranged in document order. See
query context in semantic reads.
Dense lists in navigation, sidebar, header or footer regions may be omitted from an overview when substantive page content is also present. The output reports the omitted block/link counts, and ordinary selection counts still include those omissions. A literal query can retrieve the omitted region. Sparse menus and pages consisting mainly of navigation keep their usual overview behavior.
Omit --query for an overview when the desired page wording is unknown. A query
ranks lexical matches; it does not interpret an arbitrary question. Read output
preserves context, explicit advertisement labels, source/viewport metadata, and
separate same-label links to distinct destinations. Counts and truncation flags
refer to the loaded snapshot. Content already loaded offscreen, including
content-visibility: auto sections, is eligible for capture; truly hidden
content is excluded. An untruncated snapshot describes the finite loaded DOM,
not every item an infinite feed could later load. Use native scrolling or other
page actions to load further items, then read again.
The JSON envelope reports the source URL, title, observation ID, outline and selection counts, available content and link counts, whether the query matched, and independent source/output truncation.
Quick examples
Section titled “Quick examples”Like curl, but from a real browser
Section titled “Like curl, but from a real browser”Give REL a URL to load it in embedded Chromium and write the rendered HTML to standard output:
rel https://rel.meIt follows the same output model as curl: page data goes to standard output and capture events go to standard error. Redirect either stream independently when saving them is more useful:
rel https://rel.me > rel.html 2> capture.ndjsonNavigate, perform, and capture in one session
Section titled “Navigate, perform, and capture in one session”Create a Session in the chosen Project and preserve its exact ID for the workflow:
export REL_SESSION_ID="$(rel session create --project-id ProjectDefault --name Research --id-only)"
rel navigate https://rel.merel perform '[{"action":"wait","seconds":0.5}]'rel capture > rel.htmlThe final argument-free rel capture reads the page selected by rel navigate
after rel perform finishes. REL_SESSION_ID selects the same Session in each process.
For dynamically loaded content, add --wait-for to navigation so the next
command runs only after the chosen CSS selector appears:
rel navigate https://example.com --wait-for '#content' --timeout 60rel capture > example.htmlNavigation and the selector wait share the same page, session, and 60-second
budget. Intermediate HTTP error documents can redirect during the wait; REL
checks the final HTTP status after the selector matches. Use --wait-for to
wait for content and --wait to add a fixed settling delay. Without
--wait-for, navigation keeps its usual main-frame readiness behavior.
To pin a sequence while another shell or process may create sessions, export an ID and optional default URL under REL’s standard environment variables:
session_id="$(rel session create --name Research --id-only)"export REL_SESSION_ID="$session_id"export REL_SESSION_URL="https://example.com"
rel navigaterel perform '[{"action":"wait","seconds":0.5}]'rel capture > example.htmlAn explicit --session-id takes precedence over REL_SESSION_ID. An explicit URL takes precedence
over REL_SESSION_URL. REL’s embedded terminal exports both variables for its
browser session when the shell starts or restarts.
Output and errors
Section titled “Output and errors”Ordinary commands print the complete pretty-printed RPC v1 success envelope:
{ "status": "ok", "request_id": "req_...", "data": {}}Both capture forms write rendered HTML to standard output when --output is
omitted. URL capture writes validated NDJSON events to standard error, one
compact event envelope per physical line. For URL capture with --output,
stdout remains empty and events remain on stderr. Current-page capture with
--output prints its JSON response envelope. This keeps the primary artifact
pipeable without mixing it with progress metadata:
rel https://example.com > example.html 2> capture.ndjsonThe CLI verifies response content types and request IDs through rel-client.
Pressing Ctrl-C terminates the foreground CLI and closes its RPC connection.
If a browser operation is still active, the resident agent cancels the matching
Chromium work; the REL app, agent, and persistent browser session remain
available for later commands.
rel-mcp is a protocol process rather than an ordinary one-shot command. Its
standard output contains only newline-delimited JSON-RPC 2.0 messages for the
MCP client, and diagnostics use standard error. See MCP for its
version negotiation, tool results, and errors.
An RPC failure is printed to standard error as the complete structured error
envelope. Argument, transport, and protocol failures are plain text on standard
error. Clients should branch on the high numeric error.code or stable
error.id, not error.message or the HTTP status.
Exit status is:
| Status | Meaning |
|---|---|
0 |
Help/version or a successful RPC operation. status also requires overall_status:"ok". |
1 |
Usage, transport, protocol, or RPC failure; unhealthy status; or the terminal exit code from an unsuccessful capture. |
130 |
The shell terminated the CLI with Ctrl-C (SIGINT). |
For rel-mcp, clean stdin closure exits successfully; startup or stdio failure
exits unsuccessfully.
MCP server
Section titled “MCP server”/Applications/REL.app/Contents/Resources/rel-mcpThe adapter accepts no MCP options; --help and --version are available for
direct inspection. MCP clients normally launch it and own its
stdin/stdout pipes rather than running it in an interactive terminal. It
supports current 2026-07-28 discovery and legacy initialization through
2025-11-25, and exposes the tools supplied by its app build, including
rel_debug_state, rel_session_trace, and rel_debug_bundle when that build
contains diagnostics. See the MCP tool reference.
Every tool forwards through rel-client and RPC v1. Capture aggregates its
validated NDJSON stream into {request_id, exit_code, events}. Tool results
normally include their complete JSON in both a text content block and
structuredContent; rel_read puts bounded Markdown only in text and keeps
metadata in structuredContent to avoid duplicating page content. Captured files use absolute file:/// URIs at the MCP
boundary and are also returned as standard MCP resource_link content blocks.
Screenshot calls without an explicit output URI and hybrid or visual
observations additionally return standard MCP image content for multimodal
agents.
Health and status
Section titled “Health and status”rel healthrel statushealth calls GET /v1/health and reports agent worker readiness. status
calls GET /v1/status and reports the app, agent, Browser Proxy, and Chromium
bridge checks. Both responses include the installed build identity when the
agent was launched by a metadata-bearing app bundle. Neither command
synthesizes a local process report when the agent is unavailable.
Shorthand page workflow
Section titled “Shorthand page workflow”For sequential automation that does not need to manage page or session IDs:
rel navigate https://example.comrel perform '[{"action":"wait-for","selector":"button.more"},{"action":"click","selector":"button.more"},{"action":"wait","seconds":0.5}]'rel capture > final.htmlnavigate calls POST /v1/navigate, navigates the current shorthand page, and
prints the ordinary JSON response envelope. Supply --session-id or
REL_SESSION_ID to reuse a Session, or --project-id for Project scope.
--profile NAME creates an independent Session in that Project and
conflicts with --session-id. It also accepts --proxy, --output,
--timeout, --wait, and --wait-for. The positional URL may be omitted when
REL_SESSION_URL is set; an explicit URL always wins.
Navigation becomes ready after REL observes the requested HTTP(S) main-frame
load, that main frame finishes, and its rendered source is available. Subframe
and page-initiated background loading does not delay completion. --wait
applies a bounded settling delay after main-frame readiness; if another
main-frame navigation starts during that delay, REL waits for it and restarts
the delay. Use a timed wait action when the workflow needs additional
settling time before its next step.
For pages that redirect through an HTTP error document before becoming ready, combine navigation and a selector wait in one operation:
rel navigate https://example.com --wait-for '#content' --timeout 60--wait-for uses REL’s tolerant native selector wait on the same page and
session. Intermediate HTTP 4xx/5xx documents may redirect while it waits. Once
the selector matches, REL validates the final main-frame HTTP status; an error
status still fails with UPSTREAM_UNAVAILABLE. --timeout is one overall
budget for navigation and readiness, not a separate allowance for each phase.
Cancellation stops the combined operation without replacing the session. Omit
--wait-for to keep the existing navigation behavior described below.
A submitted navigation replaces the session’s active target immediately, even if the proxy or browser fails before the page loads. Refresh and retry use that target, so a second failed navigation does not send the session back to the first URL. Unsubmitted address-field edits do not change the retry target.
Fragment-only navigation and same-document Back/Forward complete using the existing document. They preserve its HTTP status without requiring a full load.
If the main frame returns HTTP 4xx or 5xx, navigate normally exits
unsuccessfully after the main-frame document finishes and REL inspects it,
without waiting for unrelated background loading. By default, detected Cloudflare
Turnstile and managed challenge documents with an HTTP error status receive the
remaining request timeout to complete verification and redirects in the same
session. A successful redirect completes normally. If verification remains
unresolved, the request fails with the target HTTP error or a timeout when the
budget expires. Successful pages with embedded
Turnstile widgets retain a maximum 15-second continuation window. Turn off
REL → Settings… → General → Wait for
Cloudflare Turnstile to restore immediate failure for every HTTP error. The
UPSTREAM_UNAVAILABLE error message and details include the exact target status
and final URL. The rendered page remains selected in the session. A retryable
error does not require replacing that session; replacement can interrupt
verification that is still running in its tab.
perform calls POST /v1/perform with one positional, non-empty JSON array of
canonical action objects. Actions run in array order. It accepts --session-id,
--output, --timeout, and --wait, then prints the JSON response envelope
containing the page and capture metadata. A single action must still be wrapped
in an array.
Argument-free capture calls POST /v1/capture. Without --output, it writes
the current rendered HTML to stdout. With --output, it prints the JSON response
envelope. It accepts --output, --timeout, and --wait but not URL-capture
options such as --action, --proxy, or --retry. It also accepts
--session-id.
For navigate, perform, and argument-free capture, --session-id defaults
to REL_SESSION_ID when set. Otherwise supply --project-id. The agent keeps
a distinct current shorthand page for each session, so embedded terminals can
use these commands concurrently. An explicit option always wins. The shorthand
registry is process-local and a session’s entry disappears when the agent
restarts or that session closes. Concurrent workflows that may create sessions
should set REL_SESSION_ID or pass --session-id; concurrent work within the
same session should use page attach and page action with explicit page IDs.
Capture
Section titled “Capture”rel URL [options]rel capture URL [options]Capture loads a page in an embedded Chromium session, performs optional actions, and writes the rendered HTML to stdout or an explicit output file.
| Option | RPC field | Contract |
|---|---|---|
--output PATH |
output |
Write HTML to this path instead of stdout. |
--timeout SECONDS |
timeout |
Positive finite Chromium-operation timeout; default 90. |
--wait SECONDS |
wait |
Nonnegative finite settling delay after the final main-frame readiness; default 1. Background loading does not restart it. |
--action JSON |
actions[] |
One canonical action object; repeat the option for multiple actions. |
--actions JSON |
actions |
A JSON array of canonical action objects, executed in order. |
--session-id ID |
session_id |
Reuse an existing immutable Session<number> ID. When omitted, use REL_SESSION_ID if set; new creation requires --project-id. |
--profile NAME |
profile |
Create the session from this saved profile. Conflicts with --session-id and suppresses both implicit defaults. |
--project-id ID |
project_id |
Select the owning Project for a new Session. |
--proxy ALIAS |
proxy |
Select a proxy by its unique alias for the created or reused session. |
--retry COUNT |
retry |
Retry count from 0 through 100; default 1. |
--retry-delay SECONDS |
retry_delay |
Finite delay from 0 through 86400 seconds; default 3. |
Exactly one URL is required before the options. Scheme-less localhost addresses use HTTP; other scheme-less hosts use HTTPS. Only HTTP and HTTPS are accepted.
Use --session-id for an existing Session or --project-id for explicit Project
scope. REL_SESSION_ID supplies the Session selector when no creation option
was supplied. The CLI does not choose a Session from another Project implicitly.
A new Session requires --project-id; its returned ID is Session<number>.
For a new session, --proxy oxylabs is shorthand for creating a persistent
session assigned to oxylabs, then capturing with it. Its canonical ID is
returned as data.session_id in the NDJSON capture events. Omitting --proxy
uses the selected profile, or the configured default when --profile is
omitted. Without a saved default, Custom uses direct networking, AdBlock on,
all images allowed, and Private.
For an existing session, omission preserves its current assignment; an explicit
proxy updates the assignment.
Sessions controlled while not visible use the Background Browser Size preset in REL → Settings… → General. The default viewport is 1,920 × 947 CSS pixels, matching a common maximized browser on a 1,920 × 1,080 display. A visible session follows the resizable REL window. This is a global app setting, not a capture option.
rel https://example.com/ --proxy=oxylabsCapture accepts the canonical objects in the Actions reference.
--action and --actions may be combined; actions execute in command-line
order and stop at the first failure.
A normal capture emits capture.started, capture.browser_requested,
capture.page_ready, capture.rendered, capture.writing, optional
capture.retrying, capture.traffic, capture.completed or
capture.failed, and finally capture.finished. The final event contains the
CLI exit code. When stdout is the destination, capture.writing and
capture.completed report output_path:"-"; the CLI’s private staging path is
never exposed. A target website response such as HTTP 404 or 429 is reported
as target_http_status; it is not a REL RPC error.
Example:
rel https://example.com \ --output /tmp/example.html \ --session-id Session12 \ --action '{"action":"wait","seconds":0.5}'Attached pages
Section titled “Attached pages”Attach an ephemeral automation page:
rel page attach https://example.com \ --profile AdBlock \ --timeout 90 --wait 1page attach accepts --session-id, --profile, --proxy, --output,
--timeout, and --wait. New-session creation requires --project-id.
--profile conflicts with --session-id; either creation option suppresses
the environment default. Otherwise the CLI uses REL_SESSION_ID when set. Its positional URL defaults to REL_SESSION_URL
when omitted. Its result contains a process-local page.id.
Perform one canonical browser action on that attachment:
rel page action page_... \ --action '{"action":"click","selector":"button.more"}' \ --output /tmp/after-click.htmlpage action requires exactly one --action and also accepts --output,
--timeout, and --wait. The page remains pinned to the session, URL, and
proxy selected by page attach. Page IDs disappear when the agent restarts.
Proxies
Section titled “Proxies”Every proxy has a required, case-insensitively unique alias. The alias is its only public identifier: use it for every CLI and RPC reference. Numeric database IDs and UUIDs are not accepted or returned by the public API.
REL Free includes one proxy. Creating additional proxies requires REL Pro. Existing proxies can be inspected, configured, used, or deleted.
rel proxy listrel proxy get officerel proxy delete officeCreate a proxy:
rel proxy create \ --alias office \ --upstream-host proxy.example.com \ --upstream-port 8000 \ --username account \ --password secret--alias, --upstream-host, and --upstream-port are required. The alias is
immutable. Optional write fields are --username, --password, --oxylabs-enabled true|false, --oxylabs-masque-enabled true|false,
--oxylabs-location-parameter cc|country|st, and
--oxylabs-location-value VALUE.
Update only the named fields:
rel proxy update office --upstream-port 9000rel proxy update office --clear-username --clear-passwordrel proxy update office --clear-oxylabs-locationAn update requires at least one mutable option. The clear options send explicit
JSON null values instead of omitting their fields.
Export or import a proxy transfer file:
rel proxy export officerel proxy import office.relproxyrel proxy import office.relproxy --alias office-backupExport writes ALIAS.relproxy in the current directory unless --output
supplies an exact path. It refuses to overwrite an existing file and creates
the file with owner-only permissions. Stored proxy passwords are protected by
the app and are not available to CLI export, so credentials_included is
false. Import accepts an unprotected, versioned .relproxy SQLite archive;
--alias overrides the immutable alias stored in the file. Use the app to
export or import credentials with a transfer passphrase.
Profiles
Section titled “Profiles”Create a reusable setup from the terminal, then open a page with it:
# 1. Save your first dedicated ISP proxyrel proxy create --alias research-isp \ --upstream-host disp.oxylabs.io --upstream-port 8001 \ --username user-YOUR_USERNAME --password YOUR_PASSWORD
# 2. Save the proxy, viewport, and browser identity in a profilerel profile create --name Research --proxy research-isp \ --viewport desktop --browser-identity private
# 3. Open a page using that profilerel navigate https://rel.me/proxy-test --profile ResearchInstall the CLI from REL → Settings… → General → Install Command Line.
REL Free includes one proxy and one custom profile; additional saved resources
require REL Pro. A separate provider subscription supplies the proxy.
This example uses Oxylabs Self-Service Dedicated ISP:
port 8001 selects the first allocated IP. It uses ordinary HTTP proxy
forwarding, without residential sticky-session or MASQUE options. Use the
endpoint and credentials for your purchased product. The target page reports
the IP and country observed by the website. To try a direct connection first,
run rel navigate https://example.com without a proxy.
profile create requires a unique, nonempty --name. --proxy ALIAS selects a
saved proxy; omission uses direct networking. --viewport accepts fitWindow,
desktop (1440w), wideLaptop (1280w), laptop (1024w), tablet (768w), or
mobile (320w). Omission inherits the app default. These are width presets,
not device screen identity settings.
--browser-identity private uses the app’s Private template (also the default).
native uses Chromium’s unmodified browser identity. The CLI leaves Private
identity generation to the app and never embeds an engine-specific fingerprint.
New profiles enable AdBlock. Creating a profile does not modify existing
Tab Groups. The command returns the ordinary RPC envelope with data.profile,
including its saved viewport_preset.
List profiles or transfer their reusable settings:
rel profile listrel profile export Researchrel profile import Research.relprofilerel profile import Research.relprofile --name "Research Copy"Export writes NAME.relprofile in the current directory unless --output
supplies an exact path. It refuses to overwrite an existing file and creates
the file with owner-only permissions. A profile transfer contains its name,
referenced Proxy configuration, AdBlock setting, and image policy. CLI export
does not include cookies, saved passwords, or Proxy credentials. CLI import
accepts an unprotected archive and creates a custom Profile; --name overrides
the stored name when that name already exists. Use the app for
passphrase-protected browser data or Proxy credentials.
Both transfer formats are SQLite containers with the same version 1 schema. They are limited to 12 MiB. Legacy JSON transfer files are not accepted.
Sessions
Section titled “Sessions”Read, control, and delete persistent browser sessions by their canonical IDs:
rel session listrel session get Session12rel session pause Session12rel session play Session12rel session delete Session12The historical --image-blocking-mode and --image-size-limit-kb flags apply to
images, audio, and video. Mode none allows all media, all blocks recognized
media, and over_limit blocks responses above the decimal kB threshold without
changing AdBlock. Page-script media requests use the same limit. See
media filtering for streaming and byte-range behavior.
Sessions include Project ownership and copied configuration metadata. An
independent Session can omit group_id. Create it with
rel session create --project-id ProjectDefault --profile Reddit --id-only.
Only select --group-id new or a returned group ID when sharing state deliberately
within that Project. Profile names do not identify a live login.
An unsuccessful create response without a session ID does not prove that no
session was created. REL can commit the session before Chromium synchronization
times out. Stop the workflow, retain the error, and use rel session list to
inspect the exact name and group owned by your workflow before deciding how to
recover. Do not blindly retry creation. In automated evals, record this setup
failure separately from model answer correctness and efficiency.
Use REL_SESSION_ID or --session-id to pin browser work to the intended
Session. Check its configured lifetime and use rel session ping SESSION_ID
when the workflow needs to keep an idle owned Session alive. Do not infer scope
from the frontmost window or assume that a list/diagnostic read refreshes activity.
pause idempotently cancels active requests and blocks new network work for
the session. play idempotently resumes network activity and reloads the
current page when the pause interrupted or deferred navigation. Both commands
return the RPC envelope with data.session_id and data.network_paused.
When a new URL is submitted, REL covers the existing page until the new document finishes loading. Cancelling before the new document commits restores the previous URL and its live page state without reloading. Pausing during this interval also restores that page, and playing resumes networking without reloading it. Once the new document commits, the previous document can no longer be restored this way.
Delete each Session explicitly by ID when the workflow owns its cleanup. Closing the final Session removes its state owner; no replacement blank tab is created. Preserve diagnostics before discarding a failed Session.
If session deletion returns a nonzero exit status, treat cleanup as unconfirmed and retain the error. A later list showing no session does not establish that its browser storage and active operations were cleaned up. In automated evals, record cleanup failures separately from answer correctness and efficiency.
Partially update a session:
rel session update Session12 --name Research-2 --adblock-enabled false--direct sends proxy_alias:null, selecting direct networking during creation.
A group’s proxy assignment and browser identity are fixed at creation. An update
that attempts to switch the proxy fails without applying other fields. Create a
new group to use different proxy or identity settings. Session name and filtering
policy remain mutable; the canonical session ID is immutable.
A proxy can be updated while tab groups use it. Updated settings apply to new connections without clearing browser data or reloading pages. The app’s proxy editor offers saving with or without resetting affected sessions. Deleting an in-use proxy remains blocked until no group uses it.
Proxy TLS certificates
Section titled “Proxy TLS certificates”rel proxy update bright-data --upstream-host brd.superproxy.io --upstream-port 44445 --tls bright-datarel proxy update office --ca-cert ./company-root-ca.pemrel proxy update office --tls systemproxy create and proxy update accept --locale BCP47, for example
--locale fr-CA, to configure the language/locale used by Automatic privacy
settings for that proxy. proxy update ALIAS --clear-locale removes it; omission
preserves it. Country settings alone never select a language. Private uses
Automatic: an explicit Custom identity locale wins, then the proxy locale, then
the macOS user’s preferred/default locale. A value matching native Chromium
requires no override.
Both proxy create and proxy update accept either --tls system|bright-data or --ca-cert PATH. These options are mutually exclusive. The CLI reads a PEM CA bundle locally and sends its contents, not its path. The agent validates CA certificates and limits bundles to 1–16 certificates and 64 KiB. Omission on create uses system trust; omission on update preserves the current setting. Additional roots apply only to sessions assigned to that proxy. A TLS setting change applies automatically in empty browsers; affected browsers with page state show a banner. The user chooses Reload to apply it; storage and logins remain intact.
Database recovery reports
Section titled “Database recovery reports”rel health includes data.database_recovery when the agent has a committed
upgrade or recovery report. Its local report_path identifies the detailed
report and backup_path identifies the original SQLite snapshot. See
database recovery before repairing
quarantined data.
Session inactivity and ping
Section titled “Session inactivity and ping”Sessions close after 120 seconds of client inactivity by default. Set the inactivity timeout when creating a session, or explicitly choose an indefinite lifetime:
rel session create --lifetime 300 --id-onlyrel session create --lifetime indefinite --id-onlyrel session ping Session1--lifetime accepts positive integer seconds or indefinite. Session commands
and browser work refresh activity; session listing does not. Send session ping
periodically while a client is idle (for example every 30 seconds for the default
lifetime). Ping performs no browser action and cannot reopen a closed session.
License activation
Section titled “License activation”Activate REL Pro in the local owning app with a license key from stdin:
rel license activate --key-stdin < /path/to/private-license-keyThe key is never a command argument or part of the JSON response. The app uses
its existing product validation and Keychain persistence. Activation requires
configured licensing and fails if this Mac already stores a license. Manage
replacement or deactivation in the app. Success returns activated: true and
plan: "pro"; the app then restarts its agent to apply Pro access.
Bulk profile and proxy transfers
Section titled “Bulk profile and proxy transfers”Export all custom profiles, all proxies, or both with separate commands:
rel profile export --all --output ./profilesrel proxy export --all --output ./proxiesrel proxy import ./proxies --allrel profile import ./profiles --allEach export creates a new private directory containing numbered .relprofile
or .relproxy SQLite files. Names and aliases remain inside the files. The
output directory must not already exist, so exports never overwrite a backup.
Built-in profiles are omitted because they already exist in every REL installation.
Exports contain reusable settings; cookies, saved passwords and proxy credentials
remain excluded under the same rules as individual CLI transfers.
Import scans the selected directory without recursion, sorts files of the matching
extension and checks all local files before sending imports. Import proxies first
when transferring both. Existing aliases and profile names are never replaced;
conflicts, capacity limits and other server errors appear in the per-item report.
A bulk request may partially succeed and is not transactional. JSON includes
succeeded, failed and results; any failed item produces exit status 1.
A directory with no matching import files is an error. --name and --alias
cannot be combined with bulk import. Use the app for encrypted private-data transfers.
App updates
Section titled “App updates”rel updateStarts the owning REL app’s native Sparkle update flow for its selected Regular,
Beta or Staging channel. Confirm download, installation and restart in the app.
The command can launch the app through the normal CLI startup path. Its JSON
response acknowledges the request with state: "requested", the selected
channel, and user_interaction_required: true; it does not claim that an update
is available or installed. Network errors and update availability appear in the
native updater. If this build has no update feed/signing key, or an update is
already running, the command returns a structured error and exits with status 1.
For a stored paid Pro license, expired or unverified update coverage also returns
a structured validation error. The covered app version retains its Pro features.
Renew or verify the license in Settings → Plan before requesting newer updates.
Browser diagnostics
Section titled “Browser diagnostics”rel session debug-state Session123rel session trace Session123 --limit 200rel session trace Session123 --after event_42 --limit 200rel session debug-bundle Session123 --since-request-id req_exampleUse these commands while an operation is waiting or after it fails, before
replacing its Session. Check snapshot age and trace loss counts. HTML/screenshots
require --include-html / --include-screenshot; they default to off. The result
contains a JSON artifact URL. See browser diagnostics
for limits, redaction and optional-capture errors.
Session configuration changes use the supported reapply operation.
There is no public reset API. Older clients may still contain a reset command;
it is not a supported operation on the current runtime.
Use rel session network-capture SESSION_ID --enabled [--resource-type document|xhr|fetch] [--url-prefix URL] [--status-code CODE] [--max-bytes-per-response N] [--max-total-bytes N] before reproduction. Repeat filter flags to add values. Disable with --disabled; inspect with rel session network-request SESSION_ID REQUEST_ID. See network diagnostics.
Network capture requires exactly one of --enabled or --disabled; conflicting or repeated enablement flags are rejected before contacting REL. Capture policy acknowledgements expire after 30 minutes; see the diagnostic guide for fail-closed truncation, policy IDs and unavailable-body reasons.