Examples

Reads like the API, typed by a human

Flags are the request fields, kebab-cased. Anything shells express badly gets a convenience flag.

Send
# Inline HTML
unitpost email send \
  --from "Acme <you@yourdomain.com>" \
  --to customer@acme.com \
  --subject "Welcome aboard" \
  --html "<p>Thanks for signing up!</p>"

# A file on disk, an attachment, and a saved template with variables
unitpost email send \
  --from you@yourdomain.com --to customer@acme.com \
  --subject "Your invoice" \
  --html-file ./invoice.html \
  --attach ./invoice.pdf
Pipe
# Pipe straight into jq — stdout is only ever the result document
unitpost email list --limit 100 | jq -r '.data[] | select(.status=="bounced") | .to'

# Capture an id for the next step
id=$(unitpost email send --from you@yourdomain.com --to a@acme.com \
  --subject Hi --text Hi --json | jq -r .id)

Agents

Driven by people. Built for agents.

The skill teaches the mapping. JSON and exit codes do the rest.

  • Skill-taught

    email_send becomes unitpost email send. Same scopes.

  • Parseable

    One JSON document on stdout. Stable 0 / 1 / 2 exits.

  • Preview first

    --dry-run prints the request. Nothing sends.

CLI for agents
From the skill
  • unitpost email send \
  • unitpost contacts create --email customer@example.com --first-name Ada
  • unitpost email campaigns validate cmp_123

Questions

Common questions

Do I need to install anything to use the CLI?

No. Run npx unitpost-cli@latest with Node.js 20+ for a one-off, or npm install -g unitpost-cli so unitpost is on your PATH. There are no runtime dependencies.

How does login work?

unitpost login opens your browser and completes an OAuth 2.1 authorization-code flow with PKCE against the same authorization server the MCP server uses. The token lives in your OS keychain (a 0600 file where no keychain exists) and refreshes automatically. In CI or headless shells, set UNITPOST_API_KEY instead — no login step needed.

Can AI agents drive the CLI?

Yes — that's a primary use case. The agent skill teaches the mapping (email_send becomes unitpost email send), output is exactly one JSON document on stdout when piped or passed --json, exit codes are stable (0 ok, 1 request failed, 2 usage), and --dry-run lets an agent preview a send before anything goes out. Prefer MCP for tool calls inside a chat session and the CLI for shells, scripts, and CI.

Why is there no api-keys command?

API keys can only be managed in the dashboard, because those endpoints authenticate with a session, not a Bearer token. Running unitpost api-keys explains exactly that and points at the dashboard, so the absence reads as deliberate rather than missing.

How do I know the commands match the API?

The tree is generated from the OpenAPI snapshot: one command per operation, flags from the request fields, enums and descriptions verbatim. A drift gate fails CI if the committed catalog lags the spec, so a new endpoint becomes a documented, shell-completable command with no CLI code change.

Meet your new favorite way to send

Install it, sign in once, and run the whole API from your shell.