Rheo documentation
Developer Guide

CLI

Install and use the Rheo CLI for workspace dashboard APIs and local flow import with a workspace API key.

Purpose

The Rheo CLI (@getrheo/cli) is a terminal client for workspace members. Use it to fetch and mutate product content from scripts, CI, or agents without opening the dashboard, and to run local flow-import tools via rheo import (Rheo agent skill).

It authenticates with a workspace API key (rheo_wk_…), not a publishable SDK key (ob_pk_…). Writes use the same capability checks as the dashboard for the key creator's current role. rheo auth login validates the key against the API before saving it.

AreaFrom the terminal
AppsList, get, create, update, branding, delete, SDK key list
FlowsDraft, versions, save, publish, archive, duplicate, comments, Rheo Agent stream
BannersList, draft, publish, archive, duplicate, Rheo Agent stream
CustomersOverview, list, profile, variables
ChannelsHistory, create, assign, archive
ExperimentsVariants, stats, stop, promote
AnalyticsApp overview, flow metrics, and product analytics (default last 7 UTC days)
RolloutsPolicy, submit, approve, reject, comments
MediaList, upload, rename, archive, usage
EngageFull dashboard surface including content blocks and streaming composers
WorkspaceMembers, workspace API keys, notifications, onboarding, self-serve, billing status
Importrheo import validate|scaffold|audit… (local; no API)

Not in the CLI: platform admin, Clerk browser login, Stripe checkout/portal/downgrade, visual builder preview, or the device SDK protocol (/v1/sdk/*).

Run rheo analytics product help, rheo engage help, rheo banners help, and rheo import help for command lists.

Install

Package version tracks PLATFORM_SDK_VERSION in scripts/publish-package-registry.mjs (currently 3.0.0), same coordinated release as the other @getrheo/* npm packages.

npm install -g @getrheo/cli
rheo --help

Or run without a global install:

npx @getrheo/cli --help

Requires Node.js 20+.

Create a workspace API key

  1. Sign in to the Rheo dashboard (any role: owner, admin, editor, or viewer).
  2. Open Account → Personal.
  3. Under CLI API keys, create a named key and copy the secret once.

Each key is bound to your user and one workspace. Mutations follow your live role; viewers can read but most product writes return 403.

Revoke unused keys from the same page. Rotating a key means create a new one, update login / RHEO_API_KEY, then revoke the old key.

Auth

rheo auth login --api-key rheo_wk_…
rheo auth status
rheo auth logout
rheo version

Login calls GET /v1/dashboard/workspace and fails if the key is rejected. Credentials are stored under ~/.config/rheo/config.json (or $XDG_CONFIG_HOME/rheo/config.json). Use --profile <name> for multiple profiles.

Aliases: rheo login / rheo logout (same as auth login / auth logout).

CI / env

export RHEO_API_KEY=rheo_wk_…
export RHEO_API_URL=https://api.getrheo.io   # optional; default production
rheo apps list                               # JSON when stdout is not a TTY
rheo apps list --table                       # force human table in CI
VariablePurpose
RHEO_API_KEYOverrides the saved profile key
RHEO_API_URLOverrides API base URL (local API: http://127.0.0.1:4000)
RHEO_CONFIG_PATHCustom path for the config file

Default API base URL: https://api.getrheo.io. Override per command with --api-url. The CLI does not send x-dev-* headers; use a workspace key minted against that API.

Role → product writes

RoleTypical product writes
OwnerApps, flows, channels, experiments, media, Engage (including send), rollout policy, approve/reject
AdminApps, flows, channels, experiments, media, Engage (including send), approve/reject (when designated)
EditorFlows, channels, experiments, media, Engage manage (send actions return 403), submit rollout requests
ViewerReads, including Engage (product writes return 403)

Run rheo whoami to see your workspace, role, plan, and which write capabilities the key currently has.

Global flags

FlagDescription
--jsonForce machine-readable output
--tableForce human tables when stdout is not a TTY
--dry-runPrint mutating HTTP method, URL, and body without calling the API
--body <json>Inline JSON request body for writes
--file <path>JSON request body from a file (writes); for media upload, the local file to upload
--out <path>Write a flow draft, flow version, or Engage broadcast CSV to disk
--env live|testSDK environment for analytics, experiments stats, and Engage
--start / --endUTC range for analytics and Engage overview (omit both for the last 7 UTC days)
--confirm-name <name>Required for destructive app/channel delete or archive
--profile <name>Config profile
--api-url <url>Override API base URL
-h, --helpShow help

Lists default to JSON when stdout is not a TTY. Prefer --file for large payloads (flow drafts, experiment configs, Engage templates and automation graphs).

Command reference

Auth and identity

rheo auth login --api-key <key> [--profile <name>] [--api-url <url>]
rheo auth logout [--profile <name>]
rheo auth status [--profile <name>]
rheo version
rheo whoami
rheo workspace show   # alias of whoami
rheo workspace update --body|--file
rheo workspace mau-sidebar

Apps

rheo apps list
rheo apps get <appId>
rheo apps create --body|--file
rheo apps update <appId> --body|--file
rheo apps branding <appId> --body|--file
rheo apps delete <appId> --confirm-name <name>
rheo apps keys list <appId>
rheo apps attribution-signal <appId>

apps update accepts the same JSON as the dashboard app PATCH. Revenue fields are revenueSourceAppStore, revenueSourcePlayStore, and revenueSourceWeb (none, revenuecat, or superwall; web may also be stripe), plus revenueCatWebhookAuthorization and superwallWebhookSecret. apps get --json returns those sources and the webhook URLs. The table view prints id, name, and archived only. SDK publishable keys are list-only (apps keys list); rotate keys in the dashboard until a revoke API exists.

Customers

rheo customers overview <appId> [--env] [--start] [--end]
rheo customers list <appId> [--env] [--start] [--end] [--q] [--limit] [--offset]
rheo customers get <appId> <appUserId> [--env] [--start] [--end]
rheo customers variables <appId> <appUserId> [--env]

Requires customers:read. Date defaults match analytics (last 7 UTC days when --start/--end are omitted).

Flows

rheo flows list <appId> [--include-archived]
rheo flows get <flowId>
rheo flows draft <flowId> [--out <file>]
rheo flows versions <flowId>
rheo flows version <flowId> <versionId> [--out <file>]
rheo flows create <appId> --body|--file
rheo flows update <flowId> --body|--file
rheo flows save-draft <flowId> --body|--file
rheo flows publish <flowId> [--body|--file]
rheo flows archive|unarchive <flowId>
rheo flows duplicate <flowId> [--body|--file]
rheo flows comments list|get|create|reply|archive|restore <flowId> …
rheo flows rheo-agent <flowId> --body|--file

Use --out on draft / version to write the manifest JSON to disk. rheo-agent streams NDJSON lines to stdout.

Banners

rheo banners help
rheo banners list <appId> [--include-archived]
rheo banners create <appId> --body|--file
rheo banners get|update|draft|save-draft|publish|versions|archive|duplicate <bannerId> …
rheo banners rheo-agent <bannerId> --body|--file

Keys, members, billing

rheo keys workspace list
rheo keys workspace create --body|--file
rheo keys workspace revoke <id>
rheo members list
rheo members invite --body|--file
rheo members update|remove <userId> …
rheo members transfer-ownership --body|--file
rheo billing status

Checkout, portal, and downgrade stay in the dashboard.

Local import (Rheo agent skill)

rheo import help
rheo import validate <manifest.json> [--offline-profile]
rheo import scaffold <flow-spec.json>
rheo import audit --entry <file|dir>

These commands run on disk via @getrheo/rheo-skill and do not call the Rheo API. Skill script wrappers remain available for offline agent packs; prefer rheo import when the CLI is installed. See Rheo Agent Skill.

Channels

rheo channels list <appId> [--include-archived]
rheo channels history <appId> <channelId> [--limit N] [--offset N]
rheo channels create <appId> --body|--file
rheo channels update <appId> <channelId> --body|--file
rheo channels archive <appId> <channelId> --confirm-name <name>
rheo channels unarchive <appId> <channelId>
rheo channels assign <appId> <channelId> --body|--file
rheo channels unassign <appId> <channelId>

Experiments

rheo experiments list <appId> [--include-archived]
rheo experiments get <experimentId>
rheo experiments stats <experimentId> [--start] [--end] [--cohorts] …
rheo experiments stats-timeseries <experimentId> …
rheo experiments cohort-keys <experimentId> …
rheo experiments cohort-values <experimentId> --dimension <dim> …
rheo experiments create <appId> --body|--file
rheo experiments update|delete <experimentId> …
rheo experiments add-variant|reorder-variants <experimentId> --body|--file
rheo experiments update-variant|delete-variant <experimentId> <variantId> …
rheo experiments status|extend|stop|promote <experimentId> --body|--file

Stats commands accept optional --start / --end (UTC dates), plus cohort filters (--cohorts, --cohort-dimension, --cohort-key, --custom-key) where applicable. --dimension is required for cohort-values.

Analytics

Default environment is live. If you omit --start / --end, the CLI uses the last 7 UTC days.

rheo analytics app-overview <appId> [--env live|test] [--flow-id <id>] [--start] [--end]
rheo analytics <kind> <flowId> [--env live|test] [--version-id <id>] [--start] [--end]
rheo analytics product <view> <appId>

Flow analytics kinds: overview, funnel, dropoff, timeseries, timeseries-cohorts, cvr-heatmap, step-duration, cohorts, cohort-keys, purchases, responses.

For cohorts and timeseries-cohorts, pass --dimension. When --dimension=custom_property, also pass --custom-key.

Product analytics reads the same app-level views as the dashboard analytics screens. Run rheo analytics product help for the full list. Every view accepts --env live|test, --platform all|web|mobile (default all), and --segment-id. Dated views use the last 7 UTC days when --start and --end are omitted. live ignores the date range and returns people active in the last 5 minutes.

rheo analytics product live <appId>
rheo analytics product summary|overview|screens|visitors <appId>
rheo analytics product series <appId> [--grain day|week|month]
rheo analytics product attribution <appId> --dimension <acquisitionChannel|referrer|source|campaign|medium|content|term|adset|creative>
rheo analytics product attribution-series <appId> --dimension <dim> [--grain]
rheo analytics product technology <appId> --dimension <browsers|operatingSystems|devices>
rheo analytics product technology-series <appId> --dimension <dim> [--grain]
rheo analytics product demographic <appId> --dimension <country|region|city>
rheo analytics product demographic-series <appId> --dimension <dim> [--grain]
rheo analytics product engagement <appId> --dimension <page|entry|exit>
rheo analytics product engagement-series <appId> --dimension <dim> [--grain]
rheo analytics product events <appId>
rheo analytics product events-series <appId> [--grain]
rheo analytics product recent <appId> --name <event>
rheo analytics product retention|retention-curve <appId>
rheo analytics product retention-series|retention-cohorts <appId> [--grain] [--dimension <dim> --value <value>]

Breakdown views take the same column filters as the dashboard tables: attribution (--source, --campaign, --medium, --content, --term, --adset, --creative), technology (--browsers, --operating-systems, --devices), demographic (--country, --region, --city), and engagement (--page, --entry, --exit).

Shared cross filters repeat, or take commas. Values in one dimension match with OR:

--xf-acquisition-channel, --xf-referrer, --xf-source, --xf-campaign, --xf-medium, --xf-country, --xf-region, --xf-browser, --xf-os, --xf-device, --xf-page, --xf-event, --xf-entry, --xf-exit.

One operator per dimension, set with --xf-op-<dimension>: is, is_not, contains, or does_not_contain. A missing operator means is. contains and does_not_contain apply to campaign, page, event, entry, and exit.

Responses print JSON. Product analytics reads need analytics:read. Field definitions and the matching dashboard screens are in Product analytics.

ViewInformation
summaryVisitors, sessions, views, events, bounce rate, average session time
seriesThose totals bucketed by --grain
overviewOnline count plus acquisition, location, engagement, and technology lists
livePeople and places active in the last 5 minutes
attribution, attribution-seriesOne acquisition column, and that column over time
engagement, engagement-seriesPages or screens, including entry and exit
screensPage and screen name totals
events, events-seriesEvent names, and those names over time
recentLatest rows for --name
retentionNew, returning, and first-touch breakdowns
retention-seriesNew and returning visitors over time
retention-cohortsCohort table. Optional --dimension and --value drill in
retention-curveShare of new users active on each later day
demographic, demographic-seriesCountry, region, or city
technology, technology-seriesBrowser, operating system, or device
visitorsPeople in the range. revenueUsd is net ledger gross for that person in the window, including renewals and refunds

Rollouts

rheo rollouts policy
rheo rollouts policy-set --body|--file
rheo rollouts list
rheo rollouts get <id>
rheo rollouts channel-list <appId> <channelId>
rheo rollouts submit --body|--file
rheo rollouts approve <id> [--body|--file]
rheo rollouts reject <id> [--body|--file]
rheo rollouts comment <id> --body|--file

Media

rheo media list
rheo media sign-upload --body|--file
rheo media confirm --body|--file
rheo media upload --file <path> [--type] [--content-type] [--name]
rheo media rename <assetId> --name-stem <stem>
rheo media archive <assetId>
rheo media usage <assetId>

media upload signs, uploads bytes, and confirms in one step. Omit --type / --content-type to infer from the filename.

Notifications, account, and FTUE

rheo notifications list [--unread]
rheo notifications read <notificationId>
rheo notifications read-all
rheo me email-preferences [get]
rheo me email-preferences update --body|--file
rheo me signup-attribution --body|--file
rheo onboarding get
rheo onboarding verify|complete <taskId>
rheo onboarding dismiss
rheo self-serve status
rheo self-serve accept-terms|complete-profile-name|complete-workspace-name|tour-dismiss …
rheo store-listing-lookup --body|--file
rheo ai brand-colors <appId> --body|--file
rheo ai translate-chunk --body|--file

store-listing-lookup takes { "url": "https://apps.apple.com/app/id123" } or a website URL and returns the public name and icon.

Engage

rheo engage calls the same Engage API as the dashboard: email provider setup, push credentials, settings, contacts, templates, content blocks, segments, broadcasts, automations, marketing topics, preference-center preview, attested consent, and streaming Rheo Agent composers. Broadcasts and automation steps can target email, webhook, and push. Product behavior is described in Rheo Engage. Run rheo engage help for the full list.

Reads need engage:read. Creating and editing templates, segments, broadcasts, automations, topics, and settings needs engage:manage. Connecting or disconnecting a provider, test-send, broadcast send, deliverability resume, and attested consent need engage:send (owners and admins). Editors can draft and schedule; send actions return 403.

Template AI compose/edit and natural-language segments also need ai:brand_extract.

deliverability resume accepts --note <text> or a JSON body. broadcasts export writes CSV (--out saves a file; optional --status). contacts list accepts --q, --limit, and --offset. Broadcast and automation lists accept --env, and broadcasts also accept --cursor and --limit.

rheo engage overview <appId> [--env live|test] [--start] [--end]
rheo engage health <appId>
rheo engage settings get <appId>
rheo engage settings update <appId> --body|--file
rheo engage provider get|set|refresh|rotate-webhook|disconnect <appId> …
rheo engage push-provider get|set <appId> [--body|--file]
rheo engage deliverability resume <appId> (--note <text> | --body|--file)
rheo engage test-send <appId> --body|--file
rheo engage preview-merge-tags <appId> --body|--file
rheo engage audience-estimate <appId> --body|--file
rheo engage contacts list <appId> [--limit N] [--offset N] [--q <search>]
rheo engage contacts upsert|import <appId> --body|--file
rheo engage contacts delete <appId> <contactId>
rheo engage templates list|get|create|update|delete <appId> …
rheo engage templates ai-compose|ai-edit <appId> --body|--file
rheo engage segments list <appId> [--env live|test]
rheo engage segments readiness <appId>
rheo engage segments get <appId> <segmentId> [--days N]
rheo engage segments estimate|create|nl|import <appId> --body|--file
rheo engage segments update|delete|members <appId> <segmentId> …
rheo engage attribute-keys <appId>
rheo engage event-names <appId> [--env live|test]
rheo engage broadcasts list <appId> [--env] [--cursor] [--limit]
rheo engage broadcasts create <appId> --body|--file
rheo engage broadcasts update|send|schedule|cancel|pause|resume|analytics|sends|export <appId> <broadcastId> …
rheo engage content-blocks list|create <appId> …
rheo engage content-blocks get|update|archive|duplicate|delete <appId> <contentBlockId> …
rheo engage automations list <appId> [--env] [--include-archived]
rheo engage automations get|create|update|publish|duplicate|archive|activate|pause|resume|enroll|versions|analytics …
rheo engage automations nl|rheo-agent <appId> … --body|--file
rheo engage automations update-node <appId> <automationId> <nodeId> --body|--file
rheo engage automations restore <appId> <automationId> <version>
rheo engage email-composer rheo-agent <appId> --body|--file
rheo engage push-composer rheo-agent <appId> --body|--file
rheo engage topics list|upsert|update …
rheo engage preference-preview <appId>
rheo engage consent grant <appId> <customerId> --body|--file

Lists print a table unless --json. Detail reads and mutations print JSON. broadcasts export writes CSV (--out saves a file; optional --status). Overview uses the last 7 UTC days when --start and --end are omitted.

The deprecated /engage/campaigns HTTP routes are the same resource as broadcasts. The CLI uses broadcasts.

Broadcast create and update accept optional pacePerHour (integer 1 to 100,000, or null). That is how many emails the delivery worker submits per UTC hour. Omit it for unlimited. broadcasts pause and broadcasts resume hold and continue an in-flight broadcast. broadcasts cancel still skips anyone who has not gone out.

Examples

List apps as JSON, then fetch a flow draft:

rheo apps list --json
rheo flows draft <flowId> --out draft.json

Publish a flow after editing a draft file:

rheo flows save-draft <flowId> --file draft.json
rheo flows publish <flowId>

Upload an image asset:

rheo media upload --file ./hero.png --name hero

Pull last-week funnel analytics for a flow (live):

rheo analytics funnel <flowId> --env live

Pull product analytics for an app, including a shared country filter:

rheo analytics product summary <appId> --env live --platform web
rheo analytics product attribution <appId> --dimension source --xf-country US,CA

List live broadcasts, then export recipient rows:

rheo engage broadcasts list <appId> --env live --json
rheo engage broadcasts export <appId> <broadcastId> --out sends.csv

Exit codes

CodeMeaning
0Success
1Usage error, validation failure, or non-auth HTTP error
2Unauthorized or forbidden (401 / 403)