CLI

The Reply command line — sign in once, then every v3 API request runs as you, from your terminal or your scripts. Install with npm i -g reply-cli. It handles authentication, profiles and teams, reaches the whole v3 API through reply api, installs the Reply agent skills into your AI assistants, and keeps itself up to date.

Status: Available (v0.5.1)

reply ships four things today:

  • Authentication and identity — OAuth or API-key login, multi-account profiles, and team selection, so one machine can act as several users across several workspaces.
  • reply api — an authenticated passthrough that reaches every documented endpoint of the Reply.io v3 API.
  • reply skills — installs the Reply agent skills into every AI assistant on the machine, dependencies resolved.
  • reply install — updates the CLI itself, so nobody has to remember an npm command.

There are no dedicated commands for sequences, contacts, the inbox, or reporting yet — see Where the command surface is going for why that is a deliberate wait rather than a backlog. reply api /v3/... reaches all of it today. The CLI is pre-1.0 — see Versioning & stability.

Source: github.com/reply-team/reply-cli · Package: npmjs.com/package/reply-cli · Docs: docs.reply.io/cli/overview.

Install

npm install -g reply-cli      # installs the `reply` command (Node 20+)
reply --version

Staying current

One command, and you never type an npm invocation again:

reply install                 # update to the newest release, or say you are already on it
reply install --dry-run       # check without changing anything — usable as a CI gate

It looks up the newest release and updates the copy it can safely update. Where the copy is not the CLI’s to change — installed inside a project, run through npx, built from a checkout — it prints the command that fits your setup and touches nothing. reply --version mentions a newer release when one exists; that check reads the public GitHub releases, is cached for a day, times out after a second and a half, and stays silent when it fails. It never runs with --json, when output is piped, in CI, or with REPLY_NO_UPDATE_CHECK=1 set.

Authentication

Sign in once; every request then runs as you.

reply auth login              # browser OAuth
reply auth login --with-token # store an API key, read from stdin (never hits shell history)
reply auth status             # who you're signed in as, and how — no secrets shown
reply auth whoami             # verify the stored credential against the API
reply auth logout             # remove the stored credential

Create an API key in Reply → Settings → API Keys. For a single command, pass --api-key or set REPLY_API_KEY; both take precedence over a stored login and are never written to disk. Resolution order: --api-keyREPLY_API_KEY → stored login.

Command map

Run reply <command> --help for flags and examples on any command — the installed help always matches your version; add --json for machine-readable output. The canonical command reference, including every global flag, is docs.reply.io/cli/overview.

CommandWhat it does
reply auth login|status|whoami|logoutSign in (OAuth or --with-token), inspect, verify, or clear the credential
reply profile add|use|list|current|show|set|rename|unset|deleteKeep multiple accounts signed in; each profile stores its own credential
reply team list|current|use|clearSee the teams you can act in and pin one (sent as X-TEAM-ID)
reply api <path>Authenticated passthrough to any v3 endpoint — the agent/CI escape hatch
reply skills install|list|update|removePut the Reply agent skills into the AI assistants on this machine, or take them out
reply installUpdate the CLI itself (reply update is the same command)

Raw API access

reply api is a raw, authenticated passthrough to any v3 endpoint. Use the path exactly as it appears in the API reference (starting with /v3); the query string goes in the path. A --body switches the method to POST (it also accepts @file or - for stdin).

reply api /v3/whoami                          # your identity + team
reply api /v3/sequences                       # list sequences
reply api /v3/contacts --pretty               # list contacts, indented
reply api /v3/sequences/12345                 # one sequence by id
reply api /v3/contacts --body @contact.json   # create a contact (POST; body schema per the docs)
echo '<json>' | reply api /v3/contacts --body -   # body from stdin
reply api /v3/whoami --verbose                # full request/response on stderr

It prints { "code": <status>, "data": <body> } and exits non-zero on HTTP >= 400. --verbose adds a full request/response trace on stderr with credentials redacted; stdout stays plain JSON, so pipes keep working.

Installing the agent skills

The Reply agent skills are the reasoning layer — they teach an agent how outbound actually works and how to compose the API calls this CLI executes. The CLI installs them: it detects the AI assistants on the machine and puts the packs into each one, resolving dependencies so reply-adapter pulls ai-sdr-core with it.

reply skills install                   # every pack, every detected assistant
reply skills install core              # aliases: core · adapter · runtime
reply skills install adapter runtime
reply skills install --agent codex     # only this assistant
reply skills install --project         # into this repository, not your home directory
✓ detected Claude Code, Codex
✓ Claude Code · ai-sdr-core, reply-adapter, agentic-runtime installed
✓ Codex       · ai-sdr-core, reply-adapter, agentic-runtime installed
Start a new session in each assistant so the skills load.

Then manage them:

reply skills list             # what is installed where, and what has an update available
reply skills update           # bring installed packs to the latest version
reply skills remove runtime   # remove one pack; `reply skills remove` removes all of them

--json gives a machine-readable report and --dry-run shows the plan without changing anything. On Claude Code and Codex the packs go in through the assistant’s own plugin mechanism, so they keep updating through it; other SKILL.md hosts receive the skills as files.

Claude Code and Codex are the two hosts this is verified against. For Cursor, Windsurf, Gemini CLI and GitHub Copilot the installer writes to each host’s documented skills directory, but that those hosts read from it has not been confirmed — the command labels them (paths not yet verified) in its output and marks them "verified": false in --json.

Installing skills is not the same as connecting Reply: the reply-adapter pack needs a login (reply auth login) before it can do anything.

Profiles & teams

A profile is a signed-in account; a team is the workspace a request acts in. Most people never touch either — the built-in default profile is used until you create another. They matter when an agent has to act as more than one Reply.io user, or across more than one workspace, without re-authenticating between calls.

Profiles

Each profile stores its own credential. Name them however you like; account emails work well:

reply profile add alice@reply.io           # --team-id optionally pins a team at creation
reply profile use alice@reply.io           # make it the active profile
reply auth login                           # signs in alice@reply.io
reply profile list                         # '*' marks the active profile
reply profile current                      # just the active profile name
reply --profile bob@reply.io auth whoami   # override for a single command

The active profile resolves as --profileREPLY_PROFILE → the profile set with profile use → the built-in default.

Manage them after creation:

reply profile show                              # active profile: team + which authorization would be used
reply profile show alice@reply.io               # a specific one
reply profile set alice@reply.io --team-id 1045 # pin a team on a profile
reply profile unset alice@reply.io team-id      # clear a field (authority|api_base|team-id)
reply profile rename alice@reply.io ally        # also moves the stored credential
reply profile delete ally                       # removes it and its stored credential (-y skips the prompt)

profile show prints the backend URLs, the pinned team, and which authorization would be used — in priority order --api-keyREPLY_API_KEY → stored credential. It never prints tokens or keys, and neither does any other command, --verbose included.

Where credentials live. JSON in the config directory (~/.config/reply, or %APPDATA%\reply on Windows), written 0600 inside a 0700 directory — the same plaintext-file model as gh, aws, and az. Records are keyed by profile name, so two accounts on the same backend never collide. An OAuth record refreshes its access token automatically; if the refresh fails the record is cleared and you’re asked to log in again.

Teams

A profile can pin a team (workspace). The pin is sent as the X-TEAM-ID header on every request, with precedence --team-idREPLY_TEAM_ID → the profile’s team. The team command reads and writes the active profile’s team:

reply team list                          # teams you can act in ('*' marks the profile's team)
reply team current                       # the pinned team, plus the effective team from whoami
reply team use 1045                      # verify 1045 is one of your teams, then pin it
reply team clear                         # remove the pin
reply --team-id 1045 api /v3/sequences   # or scope a single call, no pin

If a call needs a team and your credential spans several, the API answers TEAM_REQUIRED listing your teams, and the CLI adds a one-line fix-it hint on stderr. Pin one with reply team use <id>, or pass --team-id for that command only.

With an organization API key you can also name the acting user per call — --user-id <id> or --user-email <email> (the email form requires a team id). Both are ignored by ordinary personal keys.

Built for agents

  • Sign in once, run as you — OAuth or API key; subsequent calls carry your identity with no per-request auth code.
  • JSON everywhere — add --json for machine-readable output; reply api emits { "code", "data" }, safe to pipe into jq or agent logic.
  • Full API reach todayreply api /v3/... covers every documented endpoint before the ergonomic wrappers land, and the skills tell the agent which call to compose.
  • Multi-account — profiles and team pinning let one agent act across workspaces without re-authing.
  • It installs its own reasoning layerreply skills install puts the outbound expertise into the assistant, so procedure and execution arrive together rather than being wired up by hand.
  • A stable machine contract — data on stdout, status and errors on stderr; exit 0 success, 1 API or runtime failure, 2 usage error; 429/5xx retried internally (honoring Retry-After), so don’t wrap your own retry loop around writes. Full contract: docs.reply.io/cli/agents.
# reach the whole v3 API through the passthrough available today
reply api /v3/sequences | jq '.data'

Environment variables

VariableDescription
REPLY_API_KEYAPI key used as the credential for the current invocation
REPLY_PROFILEProfile to use (same as --profile)
REPLY_TEAM_IDTeam/workspace id sent as X-TEAM-ID (same as --team-id)
REPLY_CONFIG_DIRConfig directory (default ~/.config/reply; %APPDATA%\reply on Windows)
REPLY_NO_UPDATE_CHECKSet to 1 to never check whether a newer release exists

Where the command surface is going

There are no dedicated commands for sequences, contacts, the inbox, or reporting yet, and the gap is deliberate rather than a backlog nobody got to.

A command surface is a promise: once reply sequence start exists, its name, flags and output shape are a contract, and a wrong shape is expensive to unpick after people script against it. So rather than translating the endpoint list into commands one for one, the commands will follow the SDR operation contract — the vendor-neutral set of business operations already written down in sdr-operations, where each operation carries what it means, whether it is reversible, and whether it needs a human’s approval before it runs. Commands that mirror that contract stay stable as the API grows. Commands that mirror today’s endpoint list do not. No date is published for them, and this page does not imply one.

Nothing is blocked in the meantime. reply api /v3/... reaches every documented endpoint, and the agent skills exist precisely so an agent does not have to guess which call to make: they carry the operation-to-endpoint mapping, the order to call things in, the scopes each one needs, and where to stop for human approval. An agent with the skills installed composes correct reply api calls today — the ergonomic commands will shorten what it types, not unlock something it cannot currently do.

Where a shell is the wrong fit, use the surface that is: REST for your own integration, MCP for a tool surface inside an LLM client.

Versioning & stability

reply-cli follows semantic versioning, with the version derived automatically from Conventional Commit messages (fix: → patch, feat: → minor). It is pre-1.0: while the version is 0.x, a minor release (0.x.0) may contain breaking changes, per semver’s own 0.x rule — pin an exact version if you need stability before 1.0.0. 1.0.0 is cut once the command surface and the --json output shape are declared stable.

From 1.0.0 on, a major bump is required to remove or rename a command, flag, or argument; change the meaning of an exit code; change the --json / --pretty output shape; change the config format or a REPLY_* environment variable; or raise the minimum Node.js version. Anything on that list is deprecated first — it keeps working and warns on stderr (never stdout, so --json stays clean) for at least one minor release before it is removed.

Contributing

The CLI is developed in the open, and anyone can clone it, build it, and open a pull request — contributions and bug reports are welcome. Merging is restricted: only Reply employees approve and merge, so open a PR from a branch or a fork and a maintainer reviews it.

git clone https://github.com/reply-team/reply-cli && cd reply-cli
npm install
npm run build   # compile TypeScript to dist/
npm test        # vitest; the suite is fully offline — no test touches Reply.io
npm link        # put your build's `reply` binary on your PATH

The house rules are the same contract your scripts depend on, so they’re worth knowing either way:

  • stdout is data, stderr is everything else — status and error messages never pollute a pipe.
  • --json is compact, --pretty is indented; on either, an error is one machine-readable line: {"error":{"status":…,"code":…,"title":…,"detail":…,"hint":…}}.
  • Exit codes0 success, 1 API or runtime failure, 2 usage error.
  • Secrets are never printed — token and key fields are redacted in every code path.
  • Conventional Commits are enforced by commitlint (a local commit-msg hook and a PR check), because the release version is derived from them. While the CLI is on 0.x, don’t use ! or BREAKING CHANGE: — a breaking change rides in an ordinary feat:.

Build layout, the test approach, credential-store internals, and the release process are documented in CONTRIBUTING.md.

Source and issues: github.com/reply-team/reply-cli · Package: npmjs.com/package/reply-cli · Docs: docs.reply.io/cli/overview

Frequently asked questions

Does the CLI exist today?

Yes. Install it with `npm i -g reply-cli` (Node 20+). The current version covers authentication (OAuth and API key), multi-account profiles, team selection, `reply api` — a raw authenticated passthrough to the full v3 API — plus `reply skills` to install the agent skills into your AI assistants and `reply install` to keep the CLI itself current. Dedicated commands for sequences, contacts and the inbox are not there yet; use `reply api /v3/...` for those today. The canonical API reference is at docs.reply.io.

Why a CLI when there's already REST and MCP?

Coding agents are exceptionally good at running shell commands. The CLI signs in once and carries your identity into every call, so an agent reaches the whole v3 API through `reply api` without writing HTTP client or auth code — and humans get a scriptable surface for one-off operations.

How does it relate to the agent skills?

The skills (see /skills) are the reasoning layer — they teach an agent what an outbound operation is, which one this situation calls for, and where it must stop and ask a human. The CLI is the execution layer that carries it out. The CLI also installs them: `reply skills install` puts the packs into every AI assistant it finds. Today a skill composes `reply api /v3/...` calls, using the endpoint mapping it carries; as the higher-level commands land, it will shell out to those instead, and the procedure it follows will not change.

Can I contribute to the CLI?

Yes — it’s developed in the open. Clone the repo, run `npm install && npm run build && npm test` (the test suite is fully offline), and open a pull request from a branch or a fork. Only Reply employees can approve and merge, so a maintainer reviews every PR. Commit messages follow Conventional Commits because the release version is derived from them. Full guide: CONTRIBUTING.md in github.com/reply-team/reply-cli.

How stable is it?

Pre-1.0. While `reply-cli` is on 0.x, a minor release may contain breaking changes — pin an exact version if you need stability. From 1.0.0 on, anything in the compatibility surface (commands, flags, exit codes, `--json` shape, config format, `REPLY_*` variables, minimum Node version) needs a major bump, and is deprecated with a stderr warning for at least one minor release first.