Send mail, verify domains, read inboxes, and tail events from your shell, CI, and coding agents.
Send mail, verify domains, read inboxes, and tail events from your terminal. The Dairo CLI is built for scripts, CI pipelines, and coding agents. It uses the same API key as the SDKs and keeps complaint safety on by default.
Install
The package installs the native binary for your platform: macOS (arm64/x64), Linux (arm64/x64), or Windows (arm64/x64).
Authenticate
Sign in with your browser, or set a key directly. Either way the credential is the same one the SDKs use — see Authentication.
The CLI checks DAIRO_API_KEY first, then a local config file.
Without --json the CLI prints for people: lists as tables (a further page is
announced as More results: --cursor <cursor>), everything else as key: value
lines. Add --json to any command to print the API response exactly as
returned — the object itself, or the list envelope with data and
pagination — ready to pipe into jq or parse in a script or agent.
Send your first email
A send that is blocked because a recipient reported your mail as spam returns an
error; pass --ignore-complaints only to override it deliberately. See
Land in the inbox.
Command reference
Account and usage
dairo whoami identifies your key and project and returns the plan, limits,
usage, billing period, storage, and the key's allowedIps (an IP allowlist,
or [] for any IP). Check it before a large send to see your headroom.
Domains
dairo domain recheck re-reads your DNS records and reports whether the domain is
verified. A domain that still has inboxes is only deleted with --cascade, which
deletes those inboxes and their messages too.
Inboxes
Sending
Name the sending inbox with --inbox-id, or by address with --from. At least
one --to and exactly one body (--text, --text-file, --html, --html-file,
or --react-source) are required. Add --attachment ./file.pdf (repeatable);
attachments travel inline in the email, 8 MiB in total. Use --ignore-complaints
only to deliberately override complaint suppression.
--send-at takes an RFC 3339 timestamp with an explicit timezone offset (for
example 2026-07-01T09:00:00Z or 2026-07-01T11:00:00+02:00) or a natural-language
time such as "in 1 hour" or "tomorrow at 9am"; the time must be in the future
and at most 30 days out. A scheduled send returns status: scheduled with a
scheduledAt timestamp; cancel it with dairo messages cancel <messageId>.
Track delivery
Each email carries a status (including scheduled and canceled) plus
scheduledAt and canceledAt timestamps when set. dairo messages get returns
the email with its delivery events inline; dairo messages events lists only the
events. dairo messages cancel works only while the email is still scheduled —
once it is no longer scheduled (already sent, queued, or canceled) it returns a
409 conflict, and an id your key cannot see returns 404. See Track delivery.
Physical mail (letters)
Fairo turns a PDF into a real, posted letter. Reads use
letters:read; sending and canceling use letters:send. Cancel works only while
the letter has not been dispatched yet. Without --confirm, dairo letter send
creates a draft instead of posting it. --delivery is economy (the default),
priority, or registered.
Messages, threads, attachments
Webhooks
dairo webhook verify checks a delivery offline, without an API call, using the
same rules as the verification snippets:
the v2 signature over the timestamp, event id, and body, any entry of a rotation
header, and a timestamp no older than 5 minutes. It exits non-zero when the
delivery does not verify.
API keys
Pass --scope once per scope. Add --allowed-ip (repeatable, up to 50) to lock a
key to specific source IPs or ranges; omit it to allow any IP. A correct secret
presented from an unlisted IP is rejected with 403. The allowlist shows up in
dairo api-key list, dairo whoami, and the create output.
Audiences
dairo audiences add adds or updates members; dairo audiences import-csv
bulk-imports from a CSV with the member's email address in the first column and an
optional name in the second (an optional handle,name header row is allowed; any
other first row is refused with its line number). dairo audiences send runs the same outbound pipeline as
dairo send, fanning out to every member of the list with complaint suppression
applied automatically. A broadcast always sends now, one email per member, so it
takes no --to, --send-at, or --channel. Listing and reading use audiences:read; creating a list
and adding members use audiences:write; dairo audiences send requires
messages:send.
Contacts
dairo contacts list prints one page (--limit 1–100, default 50); pass the
returned pagination.nextCursor as --cursor while pagination.hasMore is
true. Reads use contacts:read; changes use contacts:write. See
Contacts.
Templates
Author versioned React-email templates (scopes templates:read and
templates:write), then send with one by passing a template reference
({ id, version?, variables }) instead of an inline body.
Wait for one-time codes
Give an inbox a schema so incoming mail arrives as clean fields, or register a wait
that resolves with the extracted result the moment a matching email lands. See
Wait for one-time codes.
The event stream
Pull, tail, and replay your event stream. Reading uses events:read; replay uses
events:write. See The event stream.
Agents, reputation, budgets
Signed agent identities, fleet send-health, and per-agent send ceilings. Reads use
agents:read and budgets:read; changes use the matching :write scope;
provenance verification is public. --max-spend-per-day-cents caps the account's
paid holds (calls, letters, AI generations) over the last 24 hours and applies to
the account budget only.
Compliance
Erasure jobs use compliance:read and compliance:write; residency and audit-log
reads use account:read.
MCP install
--client auto configures every installed client (Claude Code, Codex, Cursor,
Hermes). The entries are written to the clients' config files in your home
directory — Claude Code's is ~/.claude.json — never into the current project,
because they hold your API key. See the MCP server.
Scripting example
A CI script that waits for a domain to verify, then sends a build notification:
Next steps
Build reliable mail agents with the patterns in Why Dairo is agent-native. For the same surface as copy-paste agent tool calls, see MCP recipes.