Customer.io CLI on the Builder plan: from signup to a live send, step by step
MIT's Compatible Time-Sharing System had a problem nobody had needed to solve before. Several people sat at several terminals, sharing one machine, and each of them had private files. BRG's ThinkSet dates the first recorded use of computer passwords to that system in 1961 (BRG). Fernando Corbató, who led the project, later told Wired that a password per user "seemed like a very straightforward solution" (Gizmodo).
Within a few years the lock was picked, and not at the terminal. Allan Scherr, a PhD researcher allotted four hours a week on the machine, worked out that he could submit a request to print the master password file. He collected the printout, shared copies with other users so the trail would not lead to him alone, and only confessed at the 25th anniversary of CTSS (BRG). The login worked. The file behind it was the weak point.
The Customer.io CLI is a terminal tool too, and it keeps its credential in a file in your home directory. Keep that in mind as we go from nothing to a live send on the Builder plan.
TL;DR: The Customer.io CLI (cio, version 0.0.31, published 14 October 2026) is the only one of Customer.io's AI tools that can create an account. Two commands, cio auth signup start and cio auth signup verify, create a Builder account with a sandbox workspace and store the token for you. From there the CLI sets a from address on the starter domain, verifies up to 10 test recipients, sends the first sandbox email, adds your real sending domain and calls go-live. Open the dashboard for the one step the CLI cannot do, adding funds, and to check what it built. MCP can write as well, but it needs an existing account with MCP switched on by an admin, so it comes after setup, not before. Settle your event names before an agent creates them for you.
What the Customer.io CLI is
The Customer.io CLI is a single binary, cio, written in Go and published on npm as @customerio/cli. Its README calls it "An agent-first CLI for Customer.io APIs" and says it covers 800+ Journeys routes and 100+ CDP Pipelines routes through one command, cio api <path>. Every command returns JSON to stdout, and every error returns JSON to stderr.
The CLI reference describes three steps an agent takes, in this order (CLI reference).
- Skills.
cio skills listandcio skills read <skill>fetch Customer.io's own instructions for a task, served from Customer.io rather than copied to your disk. - Schema.
cio schemalists resources and endpoints, andcio schema campaigns.listshows one endpoint in full. - API.
cio apimakes the call. It defaults to GET, switches to POST when you pass--json, and takes--dry-runto print a request without sending it.
A Builder setup also leans on four purpose-built commands: cio auth, cio domains, cio send and cio transactional. The repository shows 35 releases, and npm lists version 0.0.31, published 14 October 2026, so expect it to keep moving. Learn the exit codes early: 3 is authentication, 4 is authorisation and 5 is an API error on Customer.io's side.
If you are still choosing between the CLI and MCP, start with our CLI vs MCP decision guide.
Which plans it works on
The CLI works on any Customer.io account. It authenticates with service account tokens, which you create under Account Settings, and a user token inherits your own role and workspaces. Nothing in the CLI docs limits it to one plan.
The Builder flow is different, because the CLI can create the account itself. The README explains the two token types: production tokens start sa_live_, and "Builder sandbox signup can temporarily return sa_sandbox_... until go-live" (README). The onboarding, sandbox, test-recipient and go-live skills that drive this flow are each labelled Builder-plan accounts only (CLI skills). On Essentials or Premium you log in with a token and use the rest of the CLI as normal.
One caveat on pricing. Customer.io's Builder plan docs page did not load when we checked on 16 October 2026, so this post quotes no Builder prices. Our Builder plan breakdown covers what the plan includes; confirm the current rate under Billing before you top up.
Settle the event plan before you script anything
An agent with a CLI will create whatever you ask for, event names included. If your app sends signup, your backend sends user_signed_up and a test script sends Signed Up, Customer.io now holds three events for one moment, and every automation you build later has to pick one.
We push every client through this step first. When we moved AIRE Health from an internal email system to Customer.io, the data plan came first. It set one naming schema across existing and new events. Their campaign conversion rate went from 7.0% to 17.8%, a 154% increase. The schema alone did not do that, but the segmentation behind it needs clean events.
For Builder, the plan can be short: the events your app will send, their exact names and their properties. Our event schema guide has a template. Hand it to your agent with the setup prompt.
Step 1: install the CLI and the skill
Install it from npm or Go (get started).
# With npm
npm install -g @customerio/cli
# With Go
go install github.com/customerio/cli@latest
Then install the bootstrap skill, which teaches your coding agent to drive the CLI.
cio skills install
Only a small routing file lands on disk. Every other skill is fetched when needed (README). The bootstrap skill's own first instruction is to run cio prime, which prints the full CLI reference for the agent (SKILL.md).
Most people ask Claude Code, Cursor or Codex to run the steps below. The onboarding skill makes the agent ask before each step that changes anything, such as an install, a send or a billing action (CLI skills).
Step 2: create the Builder account
This is the step MCP and the Claude Code plugin cannot do, because both need an existing account. Signup is two commands (auth.go). The first emails a 6-digit code:
cio auth signup start --json '{"email":"[email protected]"}'
The second confirms the code and creates the account:
cio auth signup verify --json '{
"email": "[email protected]",
"code": "123456",
"company_name": "Acme",
"first_name": "Ada",
"last_name": "Lovelace",
"data_center": "us"
}'
Pick data_center with care: it sets the US or EU region.
On success the CLI saves your credentials and you are logged in. This is the only time the CLI creates a token, and it is an admin token with full permissions (service accounts). Later tokens come from the UI.
That admin token is the CTSS password file of this setup. It sits in ~/.cio/config.json. Customer.io's guidance is to keep sa_live_ tokens out of shell config files such as ~/.zshrc, and to use your CI provider's secret store for pipelines (service accounts). Never paste one into an agent conversation.
Already signed up in the browser? Log in instead. The --from-clipboard --wait form starts the command first and picks the token up the moment you copy it from the token page:
cio auth login --from-clipboard --wait
Check the result with cio auth status.
Step 3: the sandbox and the starter domain
A new Builder account starts in sandbox mode with a Customer.io-hosted starter domain, so you can send test email before you own any DNS. The sandbox skill says to spot it by the starter: true field, not its name (CLI skills). List the domains, then add a from address (domains.go):
cio domains --env-id 456 list
cio domains --env-id 456 from_addresses add --name "Support" --email [email protected]
Swap 456 for your workspace ID and the address for one on your starter domain.
Know what the sandbox will not prove. Per the sandbox skill, push and in-app are generally blocked or incomplete there, and webhooks and full-audience sends need go-live.
Step 4: test recipients
Sandbox email only reaches verified test people, up to 10 of them (CLI skills). The account creator is normally verified already, which is why the first test send should go to the signup address, not to whichever work address your agent finds in context.
To add someone else, the agent creates or updates their profile, then calls the profile's double opt-in endpoint. Customer.io emails them a confirmation link. Until they click it, sends to them come back undeliverable. The skill is explicit that the agent should not set the reserved test-user attributes through normal profile updates, because the double opt-in endpoint is the supported route.
On paid plans the usual pattern is a separate Customer.io test workspace; the Builder sandbox builds that idea into one workspace.
Step 5: wire the app with the right credential
Three kinds of credential are in play, and the bootstrap skill sets the rule for each (SKILL.md).
| Job | Credential | Where it lives |
|---|---|---|
| Running the CLI, account management | Service account token (sa_live_ or sa_sandbox_) |
Your machine or your CI secrets, never app code |
| SDK identify, track, page and screen calls | CDP source write key | Browser, mobile or backend SDK config |
| Backend transactional sends | Workspace-scoped App API key | Backend secrets only |
Customer.io's skill puts it plainly: "Do not embed service account tokens in customer application code."
The proof of a working integration is events arriving, not a package installed. The onboarding skill asks for one identify, one page or screen event and one action event in the CDP source's events list before moving on (CLI skills). Those action events are where the event plan from earlier pays off.
Step 6: the first transactional email
The quickest proof needs no app code. cio send email sends a one-off email through the Track API (send.go):
cio send email --environment-id 123 \
--to [email protected] \
--from "Acme <[email protected]>" \
--subject "Hello World" \
--body "<h1>Hi there</h1>"
In sandbox, --to must be a verified test recipient and --from an address on the starter domain. Add the --watch flag and the CLI polls delivery status after queuing and prints the result.
For real sends (password resets, receipts, welcome emails), the content moves into a transactional message that your backend sends with an App API key. The CLI can send that stored message too (transactional.go):
cio transactional send email --environment-id 123 \
--transactional-message-id 1 \
--to [email protected] \
--message-data '{"name":"Alice"}'
Two Builder details from the transactional skill matter. Builder workspaces can only author stored email in Design Studio. And the agent should ask whether the content lives in Customer.io or in your code; the skill recommends Customer.io, so you can edit without a deploy. We agree, and our post on content as code covers when the other answer is right.
Once it works, read how to add upsells to transactional emails before you call it finished.
Step 7: go live
Going live is three things: your own sending domain, funds or a saved card, and activation. The CLI handles the first and third. Domains first (domains.go):
cio domains --env-id 456 add example.com
cio domains --env-id 456 configure example.com
cio domains --env-id 456 verify example.com
DNS can take a while to verify, and the go-live skill says not to block on it.
Funds are added under Billing in the UI. When you are signed in, cio auth login prints a link that opens Customer.io in your browser (auth.go).
Activation is a call to the account's go-live endpoint. A dry run only checks the request shape; it never reaches Customer.io. The real call either puts the account live or, if something is outstanding, returns a 422 whose missing list names it, such as payment or domain (CLI skills). Activation turns the same workspace live in place. The go-live skill says your CDP write keys and App API keys carry over unchanged. The sandbox skill says go-live creates new production keys. Check the keys in your app config after activation. You do not create a live CLI token yourself: the CLI swaps its sandbox token for a live one on a later command. The one exception is a backend that used the sandbox service account token to send: that token is revoked, so replace it with an App API key.
What the dashboard is for
Beyond funds, the dashboard shows a guided setup checklist on the Builder home screen. The onboarding skill maps each step to the CLI (CLI skills). Two details save confusion.
- The "Generate API key" step is tracked in the browser only, so CLI work never ticks it. Ignore it.
- If the CLI created a domain first, the dashboard wizard can error with "already exists". That means the step is done, not broken.
When the dashboard and the CLI disagree, the skill says to trust the API read-back over the wizard.
Where MCP fits
MCP is not a read-only tool. Customer.io's MCP server has write, write:live and configure scopes, so it can create automations, send messages and change settings (MCP get started).
What MCP cannot do is the first step. It needs an existing Customer.io account, and an account admin has to switch MCP on in AI settings before anyone can connect. By default a connection only gets the read scope. And for terminal agents, Customer.io's own MCP page says the CLI "is usually a better fit than MCP".
So on Builder it is CLI first, MCP later. Once the work shifts from building to asking (how did the welcome email do?), MCP in a chat tool is the lighter option. Our MCP server enablement playbook covers the scopes and settings to agree before you switch it on.
Customer.io's Claude Code plugin adds the MCP connector and also needs MCP enabled, so it does not replace CLI signup.
The whole path in one table
| Step | Command or place | What proves it worked |
|---|---|---|
| Install | npm install -g @customerio/cli, cio skills install |
cio --help runs |
| Account | cio auth signup start, then verify |
cio auth status shows the account |
| Sender | cio domains ... from_addresses add |
From address on the starter: true domain |
| Test recipients | Profile plus double opt-in | Recipient clicked the confirmation email |
| App wiring | SDK with a CDP write key | Identify, page or screen, and an action event in the source |
| First send | cio send email |
Delivered to a verified test recipient |
| Own domain | cio domains ... add, configure, verify |
Domain listed with starter: false |
| Funds | Dashboard, Billing | The go-live call's 422 missing list no longer names payment |
| Go live | Go-live endpoint | Account no longer in sandbox |
When not to use the CLI
- Nobody on the team works in a terminal. A marketer working alone in a browser will get further with the dashboard and, later, MCP in a chat tool.
- You need automations and segments from day one. Builder is for transactional and low-volume sending. If you need behavioural automations, segments and custom objects, read what Builder leaves out compared with Essentials and start on Essentials instead. The CLI still works there; the sandbox flow does not apply.
- You cannot keep a token safe. The signup token has full admin permissions. Set up a secrets store before it lands in a shared shell profile or a chat log.
- Your app is push or in-app only. The sandbox cannot fully test either.
Frequently asked questions
What is the Customer.io CLI?
The Customer.io CLI is a command-line tool called cio that gives AI agents and scripts access to Customer.io's Journeys and CDP Pipelines APIs. One command, cio api, reaches every endpoint, and every command returns JSON (get started).
Can I sign up for Customer.io from the command line?
Yes, on the Builder plan. cio auth signup start emails a 6-digit code, and cio auth signup verify confirms it and creates the account (auth.go). Customer.io's onboarding skill says that account is a Builder account with a sandbox workspace (CLI skills).
How do I add test recipients in the Customer.io Builder sandbox?
Create the person's profile, then trigger double opt-in, and they can receive sandbox sends once they click the confirmation email. The sandbox allows up to 10 verified test people (CLI skills).
Does the Customer.io CLI work on Essentials and Premium?
Yes. The CLI authenticates with service account tokens on any account. The Builder-specific steps (signup, sandbox, test recipients, go-live) are the only parts limited to Builder.
Should I use the Customer.io CLI or MCP to set up a new workspace?
Use the CLI. It is the only one that can create the account, and MCP needs an existing account with MCP switched on by an admin. Bring in MCP afterwards for questions and changes from a chat tool (MCP get started).
Where does the Customer.io CLI store my token?
cio auth login stores it in ~/.cio/config.json. The CLI checks a --token flag first, then the CIO_TOKEN environment variable, then that file (get started).
Can the Customer.io CLI add funds to a Builder account?
No. Funds are added under Billing in the Customer.io UI. The go-live call then confirms it: while payment is missing, the call returns a 422 whose missing list names it.
Getting help
If you want your team to run this setup themselves, with an event plan they understand, our Customer.io and email marketing training covers it hands-on. If you would rather we wired it for you, send us an enquiry and David will reply within 48 hours.
Sources
- Customer.io, Get started with the Customer.io CLI, updated 1 September 2026.
- Customer.io, Customer.io CLI reference, updated 1 September 2026.
- Customer.io, Service accounts, read 16 October 2026.
- Customer.io, Get started with the Customer.io MCP server, updated 14 September 2026.
- Customer.io, Customer.io plugin for Claude Code, read 16 October 2026.
- Customer.io on GitHub, customerio/cli README, read 16 October 2026.
- Customer.io on GitHub, skills/cio/SKILL.md, read 16 October 2026.
- Customer.io on GitHub, cmd/auth.go, read 16 October 2026.
- Customer.io on GitHub, cmd/send.go, read 16 October 2026.
- Customer.io on GitHub, cmd/domains.go, read 16 October 2026.
- Customer.io on GitHub, cmd/transactional.go, read 16 October 2026.
- Customer.io, CLI skills (the onboarding, sandbox, test-recipient, transactional and go-live skills served to
cio skills read cio), read 16 October 2026. - npm, @customerio/cli, read 16 October 2026.
- BRG ThinkSet, The case of the purloined password, read 16 October 2026.
- Gizmodo, The world's first computer password? It was useless too, read 16 October 2026.
- NerveCentral, AIRE Health case study.
Want this working in your Customer.io workspace?
It's what we do all day for SMBs—strategy, automations, deliverability and hands-on execution.
See how we work as a Customer.io agency →
