Why we built a CLI for cold email
Most cold-email platforms are pure dashboards with no command line at all. Here's the actual case for shipping one anyway, and exactly who it benefits.
By Norbelys Chirinos, Co-founder
Founder-reviewed ·How we research and correct articles
Open the marketing site of almost any cold-email tool and you’ll find the same pitch: a dashboard, some screenshots of a sequence builder, maybe a Chrome extension. What you won’t find, on nearly any of them, is a command line. That’s not an oversight on their part — it’s a fairly reasonable consequence of how those products are built. It’s also exactly the gap Norbelys’s CLI sits in, and it’s worth explaining why that gap exists before explaining what we did about it.
This isn’t the install-and-run walkthrough — that’s a separate, practical piece. This is the case for why a CLI belongs in a cold-email platform’s surface at all.
The work is more repetitive than the marketing admits
Cold email, once you’re past the first campaign, is operations work. Import a list, verify it, cut a segment, check which mailboxes are healthy enough to add to a program, launch, watch bounce rate for the first hour, repeat next week with a new list and mostly the same senders. None of that is creative work. It’s the kind of work that, in almost any other part of a technical team’s stack, would already be a script — a cron job, a CI step, a pre-deploy check — rather than a person clicking through the same six screens on a schedule.
The dashboard is the right interface for the parts that need judgment: writing the actual copy, deciding whether a subject line lands, reading a reply thread. It’s the wrong interface for the parts that don’t — checking whether a sender’s authentication is still passing before you add it to a new program, or re-running the same list-cleanup step every Monday. Those are exactly the tasks a CLI is built for: repeatable, scriptable, and boring in a good way.
Why most cold-email platforms don’t have one
A CLI isn’t hard to bolt onto a product in the abstract — plenty of SaaS tools ship one. It’s specifically hard to bolt onto a product that was built UI-first, because a CLI is only as good as the API underneath it, and a UI-first product’s API is usually an implementation detail rather than a first-class surface. Building a real CLI on top of that means either exposing a second, thinner API just for the CLI (which then needs its own maintenance, and drifts from the real one within a few releases), or giving up and shipping a CLI that only covers a handful of actions before the team runs out of appetite to keep it current.
That’s the honest reason most cold-email tools stop at a dashboard: a CLI that isn’t generated from the real API is a second product with its own bug list, and most teams correctly decide that isn’t worth carrying. The fix isn’t willpower, it’s architecture — build the API as the actual product surface first, and the CLI (and the SDKs, and the MCP tools) fall out of it almost for free. One contract, four surfaces is the fuller version of that argument.
What you actually get from a terminal that a dashboard doesn’t give you
Three concrete things fall out of having a real command line:
- Composability. Piping
norbelysoutput intojq,grep, or another script means the CLI slots into whatever tooling your team already uses, instead of requiring you to build inside its walls. A dashboard can’t be piped into anything. - Repeatability without a person. A scripted check either runs the same way every time or it fails loudly. A person clicking through a dashboard on a schedule eventually skips a step, especially the boring verification ones that never seem urgent until the week they were.
- A record of what happened. Command history and CI logs are an audit trail for free. “Why did this sender get paused” has an answer in a log file instead of a memory of who clicked what.
Who this is actually for
Not everyone running cold email wants a terminal, and that’s fine — the dashboard isn’t going anywhere. The CLI earns its keep for a specific set of people:
Technical founders and solo operators running their own outbound without a growth team behind them. If you’re already comfortable in a shell, scripting the repetitive 80% of campaign management is strictly faster than context-switching into a browser tab for each step. This is its own piece, because the persona deserves more than a bullet point.
Ops-minded teams who’ve already automated everything else — the CRM
sync, the deploy pipeline, the on-call rotation — and want cold-email
operations to fit the same pattern instead of being the one manual process
left. norbelys login --api-key ak_live_... and a config file at
~/.config/norbelys/config.json behave exactly like every other CLI tool
already in their ~/.config directory.
Teams that want CI-driven config checks. A pipeline step that runs
norbelys domains find <domain> before a DNS change ships, or one that
checks suppression-list integrity before a new segment goes live, turns
“someone should really verify this” into a gate that actually blocks a bad
deploy. That’s a different category of safety than a dashboard warning
banner, because it runs whether or not a human remembers to look.
The escape hatch matters as much as the coverage
One detail worth calling out because it’s a good signal of how the CLI is
actually built: alongside the generated resource commands, there’s an
api escape hatch that lets you call any endpoint directly, by path,
without waiting for a dedicated command to exist for it. That’s a small
thing, but it says something about the design philosophy. A hand-rolled
CLI that only covers what someone remembered to wrap eventually has gaps —
an endpoint the API added that the CLI never got around to exposing as its
own subcommand. Because the whole command tree here is generated from the
contract, that gap mostly doesn’t happen; the escape hatch exists for the
rare case where you want raw control anyway, not to paper over missing
coverage.
Authentication follows the same “no separate system” pattern as the rest
of the platform. norbelys login --api-key ak_live_... works today for
scripts and CI, and browser-based OAuth (Authorization Code with PKCE,
looping back to 127.0.0.1) is the same flow an interactive human would
use signing into any modern CLI tool — gh, vercel, stripe — so
there’s nothing platform-specific to learn if you’ve authenticated a
terminal tool before. Config lives in one file,
~/.config/norbelys/config.json, one profile per organization, so
switching between a personal workspace and a client’s is a flag, not a
re-login.
Two more concrete scripts worth naming
Beyond the sender-health and bounce-rate checks above, two patterns come up often enough to name directly, because “you can script it” is abstract until it’s a specific script with an input and output.
A weekly list-hygiene job: pull every segment that hasn’t had new contacts added in the last 30 days, flag which ones still have unverified addresses sitting in them, and post the count somewhere your team already looks — instead of discovering six months of dead weight in a segment the week a campaign underperforms and someone finally goes looking for why.
A pre-launch gate in CI, distinct from the DNS check above: before a
new program goes live, run a script that checks every attached sender’s
status is healthy and every contact in the target segment has passed
verification, and fail the pipeline step if either isn’t true. That turns
“we should really double-check before we send” from a habit someone might
skip on a busy Friday into something that can’t be skipped, because the
pipeline won’t let a broken launch through.
What it isn’t
Worth stating plainly: the CLI is not trying to replace the dashboard’s analytics views, and it shouldn’t. Reading a funnel chart or scanning a reply thread is genuinely easier with a mouse and a screen. The CLI is for the operational spine underneath that — the checks, imports, and launches that happen the same way every time and don’t need a human’s eyes on a chart to execute correctly. If your workflow is mostly reading and deciding, stay in the dashboard. If it’s mostly repeating and verifying, the terminal is faster, and now it’s an option instead of a workaround.
For the practical side — installing the CLI and running your first command — see the install guide. For the architecture that makes a generated CLI possible at all, one contract, four surfaces goes deeper. And if you’re evaluating whether Norbelys fits a script-first workflow in the first place, the developer portal and pricing are the two pages worth opening next.