Skip to content

CLI

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:

Terminal window
cargo install --git https://github.com/rel-me/rel-tools \
--tag v0.1.1 \
--package rel-cli

The 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.

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:

Terminal window
REL_APP_PATH="/Volumes/Apps/REL.app" rel navigate https://example.com
rel health
rel status
rel 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 JSON
rel proxy list
rel proxy get ALIAS
rel proxy create --alias ALIAS --upstream-host HOST --upstream-port PORT [options]
rel proxy update ALIAS [options]
rel proxy delete ALIAS
rel proxy rotate ALIAS
rel proxy export ALIAS [--output PATH]
rel proxy import FILE [--alias ALIAS]
rel profile list
rel 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 list
rel session get SESSION_ID
rel session create [options]
rel session update SESSION_ID [options]
rel session pause SESSION_ID
rel session play SESSION_ID
rel session delete SESSION_ID
rel session close --group GROUP
rel-mcp
rel --help | -h
rel --version

rel --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 one persistent Session, one custom Profile, and one Proxy. 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 remains the default URL-first command: rel URL [options]. The explicit rel capture URL [options] form is equivalent. Argument-free rel capture instead captures the current shorthand page selected by rel navigate. The removed ping, logs, and --rotate-proxy-session interfaces have no compatibility aliases; use status, the app’s Logs view, and proxy rotate, respectively.

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:

Terminal window
rel observe --mode=semantic
rel 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:

Terminal window
rel read https://example.com/docs --query="installation" --max-chars=6000
rel 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, including offscreen semantic content; the command does not scroll a feed until every item has loaded.

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.

Give REL a URL to load it in embedded Chromium and write the rendered HTML to standard output:

Terminal window
rel https://rel.me

It 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:

Terminal window
rel https://rel.me > rel.html 2> capture.ndjson
Section titled “Navigate, perform, and capture in one session”

Create a session, then let later CLI calls select that newest session for the complete stateful workflow:

Terminal window
rel session create --name Research --id-only
# Session12
rel navigate https://rel.me
rel perform '[{"action":"wait","seconds":0.5}]'
rel capture > rel.html

The final argument-free rel capture reads the page selected by rel navigate after rel perform finishes. Each CLI process asks REL for the newest existing session, so this sequence needs no shell variable or CLI state file.

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:

Terminal window
session_id="$(rel session create --name Research --id-only)"
export REL_SESSION_ID="$session_id"
export REL_SESSION_URL="https://example.com"
rel navigate
rel perform '[{"action":"wait","seconds":0.5}]'
rel capture > example.html

An explicit --session-id takes precedence over REL_SESSION_ID, which takes precedence over the newest existing session. 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.

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:

Terminal window
rel https://example.com > example.html 2> capture.ndjson

The 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.

Terminal window
/Applications/REL.app/Contents/Resources/rel-mcp

The 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 exactly fourteen tools: rel_status, rel_notifications, rel_capture, rel_page_attach, rel_navigate, rel_read, rel_page_action, rel_take_screenshot, rel_observe, rel_find, rel_action, rel_list_sessions, rel_close_session_group, and rel_list_proxies.

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.

Terminal window
rel health
rel status

health 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.

For sequential automation that does not need to manage page or session IDs:

Terminal window
rel navigate https://example.com
rel perform '[{"action":"wait-for","selector":"button.more"},{"action":"click","selector":"button.more"},{"action":"wait","seconds":0.5}]'
rel capture > final.html

navigate calls POST /v1/navigate, navigates the current shorthand page, and prints the ordinary JSON response envelope. Its first call reuses the newest existing session unless --session-id or REL_SESSION_ID supplies one, creating a session only when none exists. Later calls without a session ID resolve the newest session again and reuse its current page. Supplying --profile NAME intentionally creates a new session from that profile and conflicts with --session-id. It also accepts --proxy, --output, --timeout, and --wait. 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.

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 as soon as Chromium commits that response instead of waiting for all background loading to stop. By default, REL first detects Cloudflare Turnstile and managed challenge pages and gives them up to 15 seconds to continue. A successful redirect completes normally; otherwise the original target error is returned. 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.

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, then the newest existing session. 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.

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, then the newest existing session. Create a persistent session only when none exists.
--profile NAME profile Create the session from this saved profile. Conflicts with --session-id and suppresses both implicit defaults.
--group GROUP group Label a newly created URL-capture session. Conflicts with --session-id and suppresses both implicit defaults.
--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.

When --session-id, --profile, and --group are omitted, the CLI uses REL_SESSION_ID if it is set, then the newest existing session. The environment variable is exported automatically by each embedded session terminal. An explicit option always wins. If neither the environment variable nor an existing session is present, capture creates a persistent browser session. Its default label is Session<ID> and its immutable identifier is:

Session<ID>

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.

Terminal window
rel https://example.com/ --proxy=oxylabs

Capture 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:

Terminal window
rel https://example.com \
--output /tmp/example.html \
--session-id Session12 \
--action '{"action":"wait","seconds":0.5}'

Attach an ephemeral automation page:

Terminal window
rel page attach https://example.com \
--profile AdBlock \
--timeout 90 --wait 1

page attach accepts --session-id, --profile, --proxy, --output, --timeout, and --wait. It also accepts --group when creating a session. --profile conflicts with --session-id; either creation option suppresses both implicit defaults. Otherwise the CLI uses REL_SESSION_ID when set, then the newest existing session. 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:

Terminal window
rel page action page_... \
--action '{"action":"click","selector":"button.more"}' \
--output /tmp/after-click.html

page 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.

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.

Terminal window
rel proxy list
rel proxy get office
rel proxy delete office

Create a proxy:

Terminal window
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:

Terminal window
rel proxy update office --upstream-port 9000
rel proxy update office --clear-username --clear-password
rel proxy update office --clear-oxylabs-location

An update requires at least one mutable option. The clear options send explicit JSON null values instead of omitting their fields.

Rotate the generated sticky session for an Oxylabs-enabled proxy:

Terminal window
rel proxy rotate office

Export or import a proxy transfer file:

Terminal window
rel proxy export office
rel proxy import office.relproxy
rel proxy import office.relproxy --alias office-backup

Export 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.

Create a reusable setup from the terminal, then open a page with it:

Terminal window
# 1. Save your first dedicated ISP proxy
rel 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 profile
rel profile create --name Research --proxy research-isp \
--viewport desktop --browser-identity private
# 3. Open a page using that profile
rel navigate https://rel.me/proxy-test --profile Research

Install 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:

Terminal window
rel profile list
rel profile export Research
rel profile import Research.relprofile
rel 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.

Read, control, and delete persistent browser sessions by their canonical IDs:

Terminal window
rel session list
rel session get Session12
rel session pause Session12
rel session play Session12
rel session delete Session12

Create a session:

Terminal window
rel session create \
--name Research \
--group pgm \
--profile BandwidthSaver \
--proxy office \
--adblock-enabled true \
--image-blocking-mode over_limit \
--image-size-limit-kb 100

Session creation opens a new page tab in the oldest compatible existing tab group. Compatibility includes the selected profile and browser-data source, proxy, fingerprint configuration, image/ad blocking, model, and viewport settings. The existing group’s identity, storage, fingerprint seed, and lifetime are preserved. An explicit name or group label must match to reuse a group; an explicit lifetime must also match. If no compatible group exists, REL creates one. The response’s session ID identifies the reused group, so repeated creation can return the same ID. reused_group reports whether a group was reused. Use rel session create --new-group to force a separate group.

When a new group is needed and --name is omitted, sessions created from a saved profile use its name followed by the global session number, for example Reddit123. Custom sessions use Session123. The canonical session ID remains Session123; duplicate visible names receive (2), (3), and so on.

Every create option is optional. --profile accepts the unique name shown in REL → Settings… → Profiles; omission uses the configured default (Custom when unset). Omitted proxy and filtering options use the selected profile. Use --direct to override it with a direct connection. --image-blocking-mode is none, all, or over_limit; none allows every image without changing AdBlock. --group labels the new session without changing its unique name or canonical ID. Group matching is case-insensitive. --id-only changes successful output to the new canonical session ID and a trailing newline instead of the JSON response envelope. Errors remain on standard error with the ordinary nonzero exit status.

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.

After a successful create, that session is the newest session and therefore the default for later CLI commands. Creating or deleting sessions in another shell can change this default; use REL_SESSION_ID or --session-id to pin concurrent workflows.

New sessions close after 120 seconds of client inactivity by default. Use --lifetime at creation to select another timeout or indefinite, and rel session ping SESSION_ID to keep an idle session alive.

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.

Close every session in a group. Repeating the command after the group is empty succeeds and returns an empty data.deleted_ids array:

Terminal window
rel session close --group pgm

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:

Terminal window
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 used by a tab group cannot be updated or deleted. Create another proxy for different settings, or delete every group that uses it first.

Terminal window
rel proxy update bright-data --upstream-host brd.superproxy.io --upstream-port 44445 --tls bright-data
rel proxy update office --ca-cert ./company-root-ca.pem
rel proxy update office --tls system

proxy 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.

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.

Sessions close after 120 seconds of client inactivity by default. Set the inactivity timeout when creating a session, or explicitly choose an indefinite lifetime:

Terminal window
rel session create --lifetime 300 --id-only
rel session create --lifetime indefinite --id-only
rel 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.

Activate REL Pro in the local owning app with a license key from stdin:

Terminal window
rel license activate --key-stdin < /path/to/private-license-key

The 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.

Export all custom profiles, all proxies, or both with separate commands:

Terminal window
rel profile export --all --output ./profiles
rel proxy export --all --output ./proxies
rel proxy import ./proxies --all
rel profile import ./profiles --all

Each 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.

Terminal window
rel update

Starts 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.