CLI
Every part of the API from a terminal, with no install.
npx carlyemail signup
It asks for your email, offers an inbox name, and saves the key to
~/.carlyemail/config.json. Scripting it? Pass --human-email and --username;
with no terminal it fails rather than waiting on a prompt.
Confirm the emailed code and it can send:
npx carlyemail verify 123456
npx carlyemail send --from my-agent@agents.carlyemail.com \
--to someone@example.com --subject "Hello" --text "Sent by an agent."
Install it if you reach for it often. The same package carries the SDK.
npm install -g carlyemail
Node 18 or newer. No dependencies.
Commands
signup |
Create an account and an inbox |
verify <code> |
Confirm the owner email |
whoami |
Identity and scope of the current key |
inboxes |
List inboxes |
create --username <u> |
Create an inbox |
delete <inbox> --yes |
Delete an inbox and its mail (--force if it is still in use) |
send --from <i> --to <a> --subject <s> --text <t> |
Send an email (also --cc, --bcc, --reply-to, --attach <file>) |
messages <inbox> |
List messages |
read <inbox> <id> |
Read one message in full |
search <inbox> <text> |
Search messages |
threads <inbox> |
List conversations |
reply <inbox> <id\|--last> --text <t> |
Reply to the sender (--all to copy everyone) |
drafts <inbox> |
List drafts |
draft <inbox> --to <a> --text <t> |
Write a draft without sending |
send-draft <inbox> <id> |
Send a draft written earlier |
webhook <url> --events <e,e> |
Create a webhook endpoint |
webhooks |
List webhook endpoints |
domains |
List custom domains, with their DNS records |
plan |
Current plan and usage against every limit |
upgrade <plan> |
A Stripe checkout link |
billing |
Invoices, card changes, cancellation |
mcp |
The MCP endpoint, for Claude and other clients |
Checking your headroom
Usage against every limit in one view, so you see what is about to run out before a request is refused:
carlyemail plan
free $0/mo
inboxes 3 / 3
domains 0 / 1
pods 1 / 2
webhooks 0 / 2
storage 0.0 GB / 3.0 GB
email 3000 a month
Scripting
--json prints the API response untouched — the same shape the
API reference documents.
carlyemail inboxes --json | jq -r '.inboxes[].email'
carlyemail plan --json | jq '.organization.storage_bytes'
Failures exit 1 under --json too, and the error is still printed, so set -e
behaves.
Configuration
The key is saved to ~/.carlyemail/config.json, written 0600.
Two environment variables override it, and the environment always wins:
CARLYEMAIL_API_KEY |
Use this key instead of the saved one |
CARLYEMAIL_API_URL |
Point at a different deployment |
So running as a different account is a prefix, not a login:
CARLYEMAIL_API_KEY=ce_us_... carlyemail whoami
Things worth knowing
An owner email is not a login. Running sign-up again for an existing address
returns account_exists and leaves every key untouched. Recover access with an
emailed code in the console; use create from
an authenticated CLI session to add another inbox.
delete requires --yes. It removes the inbox and every message in it, and
there is no undo. An inbox that sent mail or whose key was used in the last 30
days is refused until you add --force.
reply goes to the sender only. --all is opt-in.
reply --last skips the id. It answers the newest message the inbox did not
itself send. messages prints every id if you want to pick one.
Errors carry their fix.
✗ Inbox limit reached (3 on the free plan).
Upgrade the plan, or delete an inbox you no longer need.
https://docs.carlyemail.com/inboxes