norbelys CLI puts your whole Norbelys workspace in your terminal. People,
campaigns, senders, segments, deliverability, analytics — each is a command, and it stays
perfectly in step with the platform because every command is generated from the same
definitions the product itself uses. Sign in once and drive everything from the shell or a
script.
Install, sign in, and go — the CLI reads back exactly what the API returns.
The CLI works on the same Norbelys workspace as the dashboard and the API —
the same fields, the same limits, the same safety rails. Whatever you can do in the app, you
can do here, scripted.
Install
1
Run the installer
norbelys launcher in ~/.norbelys/bin,
and adds that to your PATH. The CLI runs on Bun or Node; if you have
neither, the installer sets Bun up for you. Override the location with NORBELYS_INSTALL.2
Open a new terminal
So the updated
PATH takes effect (or run the export PATH=… line the installer prints).
Verify:3
Sign in
Sign in
Two credentials work, and both authenticate the exact same way (Authorization: Bearer …).
The CLI stores them in ~/.config/norbelys/config.json, readable only by you (mode 0600).
norbelys login opens your browser once; the CLI then keeps the session fresh on its own.
norbelys whoamishows the active organization, the auth method, and the profile.norbelys logoutrevokes the session and deletes the stored credential.- Browser sessions last about 24 hours and refresh automatically — you sign in once and the CLI keeps the token fresh until you log out. API keys never expire.
How commands work
Commands mirror the API’s procedures, folded into a tree:norbelys <resource> <verb> [id] [--flags]. Nested paths become nested commands (programs senders add). --help at any
level lists what’s there, and every flag is generated from the procedure’s own schema.
-
Positional argument = path parameter —
norbelys people find <id>. -
Flags = body/query fields, named exactly as in the API (
--givenName,--status). -
Nested fields are flags too —
--<field>.<sub>, so nothing routine needs hand-written JSON:--helplists every nested flag, so the shape is never a guess. -
Open key/value fields take pairs —
--customFields "company=Acme,city=Bogotá". -
Lists are comma-separated —
--expand steps,senders(repeating a flag keeps only the last). -
--datacarries a whole body when you want one: inline'{…}',@file.json, or-for stdin. Individual flags override it per field, so you can keep a base body in a file and change one value on the command line. -
norbelys api <METHOD> <path>calls any endpoint directly, likecurlwith your auth already attached:norbelys api GET /organization.
What you can reach
Run
norbelys --help for the full grouped list, or norbelys <group> --help to drill in.
Output & scripting
Human-friendly tables by default; add--json for raw JSON on stdout. Everything non-data —
prompts, spinners, notices — goes to stderr, so pipelines stay clean.
- Exit codes are stable:
0success, non-zero on error; auth failures print a clear re-authenticate hint. --jsonsilences color, tables, and the update notice — safe to parse.
Audit a campaign before launch
programs audit is a read-only preflight. It expands the saved cadence and mailboxes, checks
that the campaign is genuinely complete, validates Liquid in the subject, preheader, and body,
and renders every saved version against a bounded sample of enrolled leads. It sends nothing.
href; the visible label can stay short, such as
getarbol.com.
Import a CSV
Bringing a lead list in from a CSV is one command. It maps common columns automatically (Email, First Name, Last Name, Phone), and --map handles headers that don’t match.
- Columns you don’t map become custom fields (keyed by the column name); pass
--skip-unmappedto drop them instead. - Add everyone to a list or campaign as they import:
--group grp_…/--campaign prog_…. - Rows without an email are skipped; large files are sent in chunks, and new addresses are verified in the background.
Multiple organizations
Each credential is scoped to one organization, so multi-org means one profile per org:--profile, commands use your default profile (or NORBELYS_PROFILE).
Staying current
--json, a CI environment, or
NORBELYS_NO_UPDATE_CHECK=1.
Troubleshooting
norbelys: command not found (right after install)
norbelys: command not found (right after install)
Open a new terminal so the updated
PATH loads, or run the export PATH="…/.norbelys/bin:$PATH"
line the installer printed. Then norbelys version.It says no_active_organization
It says no_active_organization
Your credential isn’t scoped to an organization. For an API key, create an org-scoped
key (Settings → API keys). For browser login, make sure you picked an organization on the
consent screen — that choice becomes the token’s org.
The browser didn't open on login
The browser didn't open on login
The CLI also prints the sign-in URL — open it manually. On a headless/SSH box without a
browser, use an API key instead:
norbelys login --api-key ak_… (or NORBELYS_API_KEY).Using it in CI / a container
Using it in CI / a container
Set
NORBELYS_API_KEY=ak_… in the environment — it short-circuits login entirely, so there’s
no interactive step and nothing written to disk. Add --yes to any destructive command.How it works
The CLI, the MCP server, Norbe, and the dashboard all act on one workspace through one API, with the same kind of credential. The CLI can only do what your credential can, on the organization it belongs to — nothing more. Pick whichever surface fits the task; they never disagree.Prefer AI agents?
The same API is available to Claude, Cursor, and any MCP client via the Norbelys MCP server.