Aima CLI
Install and use the aima command-line tool to drive voice and WhatsApp campaigns from your terminal, CI, or coding agents.
The Aima CLI (aima) is an AWS-CLI-shaped command-line client for AIMA Labs. It drives the /api/cli REST API — the same surface exposed as MCP tools for Claude, Cursor, and Codex.
Grammar: aima <noun> <verb>. Most commands are thin wrappers over a single API endpoint. A few composites (init, status, onboard) orchestrate multiple calls client-side.
Install
The PyPI package is aimalabs-cli; the installed command is aima.
Homebrew (macOS/Linux):
brew install stepacool/tap/aimauv / pipx (isolated install on your PATH):
uv tool install aimalabs-cli
# or: pipx install aimalabs-clipip:
pip install aimalabs-cliRun once without installing (does not add aima to PATH):
uvx --from aimalabs-cli aima --helpUpgrade with uv tool upgrade aimalabs-cli, pipx upgrade aimalabs-cli, or brew upgrade aima.
Quick start
aima init # API key wizard → ~/.aima/config.json
aima status # verify config and connectivity
aima voices list # browse voices
aima onboard # guided voice or WhatsApp walkthroughManual flow:
aima campaigns create \
--title "Q2 outbound" \
--company-name "Acme Corp" \
--voice-id 42 \
--field "budget:string:Ask their monthly budget."
aima leads add-test --campaign-id 17 --lead "Jane Doe:+15551234567"
aima calls dispatch 501 --yes
aima calls status 501 --pollConfiguration
Config file: ~/.aima/config.json (mode 0600):
{
"base_url": "https://api.aimalabs.io",
"api_key": "api_..."
}| Variable | Effect |
|---|---|
AIMA_API_KEY | Override api_key |
AIMA_BASE_URL | Override base_url (staging or self-hosted) |
AIMA_CONFIG | Alternate config file path |
AIMA_OUTPUT=json | Force JSON output (same as --json) |
Get an API key from Settings → Organization → Developers → API keys in the dashboard.
aima config show # api_key masked as api_…<last4>
aima config set base_url https://staging.aimalabs.io
aima config clear # deletes config after confirmationIf no API key is configured, every command except aima init, aima config …, and aima --help exits with code 3.
Output modes
- Human (default): Rich tables and key/value blocks. List picks use arrow-key menus.
--json: Raw API response body to stdout only. Status and errors go to stderr.- Auto-JSON: When stdout is not a TTY, JSON is emitted automatically. Override with
--no-json.
aima campaigns list --json | jq '.[].campaign_id'Exit codes
| Code | Meaning |
|---|---|
0 | Success |
1 | User error — bad flags, validation, or HTTP 4xx (detail on stderr) |
2 | Server or network error — HTTP 5xx or transport failure |
3 | Missing or invalid config |
Commands
Setup
| Command | Description |
|---|---|
aima init | Interactive first-run wizard. Prompts for API key, optionally base_url. Validates via GET /api/cli/voices. Idempotent. |
aima status | Prints config (masked key) and probes API connectivity. |
aima onboard | Guided walkthrough — choose voice or whatsapp. Cannot run with --json. |
Config
| Command | Description |
|---|---|
aima config show | Show current config. |
aima config set <base_url|api_key> <value> | Update one key. |
aima config clear | Delete config file after confirmation. |
Voices
| Command | Description |
|---|---|
aima voices list [--language LANG] [--provider P] [--voice-type T] [--no-active] | List voices. Active only by default; --no-active sends is_active=false. |
Agents
| Command | Description |
|---|---|
aima agents list [--limit N] | List agents, newest first (max 200). |
aima agents get <agent_id> | One agent including system prompt. |
aima agents create --name N --company-name C [--language] [--system-prompt] [--voice-id] | Create a reusable agent persona. |
aima agents update <agent_id> [--name] [--company-name] [--language] [--system-prompt] [--voice-id] | Partial update — only passed flags change. |
--system-prompt accepts a literal string or @path/to/file.
Campaigns
| Command | Description |
|---|---|
aima campaigns list [--active|--inactive] [--limit N] | List campaigns. --active and --inactive are mutually exclusive. |
aima campaigns create … | Create campaign + agent + extraction fields in one request. |
aima campaigns update <campaign_id> [--title] [--agent-id] [--extra-context] [--active|--inactive] | Retitle, reassign agent, or pause/resume. |
Create flags (voice):
aima campaigns create \
--title "Q2 outbound" \
--company-name "Acme Corp" \
--voice-id 42 \
--agent-name "Stefan" \
--language en \
--system-prompt @prompts/agent.txt \
--extra-context "Mention the summer promo." \
--field "budget:string:Ask their monthly budget." \
--field "tier:enum:Which tier?:values=bronze,silver,gold"WhatsApp / hybrid flags:
| Flag | Notes |
|---|---|
--campaign-type whatsapp | Messaging only; no voice dispatch. |
--campaign-type hybrid | Voice + WhatsApp on one campaign. |
--whatsapp-credentials-id ID | Required for whatsapp and hybrid. |
--template-name NAME | Required for outbound WhatsApp (not with --inbound-only). |
--template-language LANG | BCP-47 code; default en on server. |
--inbound-only | Agent replies only when the lead messages first. Mutually exclusive with --template-name. |
# Outbound WhatsApp
aima campaigns create \
--title "WA demo invites" \
--company-name "Acme Corp" \
--campaign-type whatsapp \
--whatsapp-credentials-id 12 \
--template-name hello_world \
--template-language en
# Inbound-only WhatsApp
aima campaigns create \
--title "WA support line" \
--company-name "Acme Corp" \
--campaign-type whatsapp \
--whatsapp-credentials-id 12 \
--inbound-onlyExtraction fields: repeat --field title:type:description. Types: string, integer, float, boolean, date, datetime, enum, json, array, calendar_appointment, file. For enum, append :values=a,b,c.
YAML body: --from-yaml body.yaml supplies the full request JSON shape; explicit flags override YAML values.
Leads
| Command | Description |
|---|---|
aima leads add-test --campaign-id ID --lead NAME:E164 [--lead …] | Add test leads without dispatching. |
aima leads initiate <lead_id> [--yes] | Send campaign WhatsApp template to one lead. Confirms unless --yes. |
aima leads upload-csv --campaign-id ID --file PATH --name-col COL --phone-col COL [--map FIELD=COL …] | Bulk import. Use --file - for stdin. Confirms when >50 rows. |
leads initiate requires an outbound WhatsApp campaign (template_name set, not --inbound-only). Consumes WhatsApp lead quota.
Calls
| Command | Description |
|---|---|
aima calls dispatch <lead_id> [--yes] | Place a real outbound voice call. Confirms unless --yes. |
aima calls status <lead_id> [--poll] [--poll-interval 20] [--poll-timeout 300] | Lead status with latest call and conversation. |
Polling: voice terminates when latest_call.ended_at is set. WhatsApp terminates when latest_conversation.latest_message_status is sent or delivered, or conversation status advances past not_started / failed_to_start.
Phone numbers
| Command | Description |
|---|---|
aima phones list [--limit N] | Numbers rented by your account. |
aima phones available [--limit N] | Platform inventory available to rent. |
aima phones rent <phone_number_id> [--yes] | Rent a number. |
aima phones release <assignment_id> [--yes] | Release a rented number. |
Flow: phones available → note phone_number_id → phones rent → phones list shows assignment_id for release.
WhatsApp credentials
| Command | Description |
|---|---|
aima whatsapp connect embedded|coexistence [--no-browser] [--timeout SEC] | Browser connect via dashboard page (30 min session TTL; default poll timeout 1800s). |
aima whatsapp list | List credentials on the account. |
aima whatsapp templates <credentials_id> | APPROVED templates only. |
aima whatsapp validate <credentials_id> | Live Meta API probes. |
aima whatsapp delete <credentials_id> [--yes] | Remove credentials. |
Connect flow:
- CLI creates a connect session (
POST /api/cli/whatsapp/connect-sessions). - Opens
{DASHBOARD_URL}/connect/whatsapp/{session_id}(Meta FB JS SDK embedded signup — not a localhost OAuth redirect). - Polls every ~3s until
completed,failed, or timeout. embedded= new WhatsApp Business API number.coexistence= link an existing Business app.
Run aima whatsapp validate <id> before creating campaigns.
Usage
| Command | Description |
|---|---|
aima usage view | Current UTC month: voice_minutes and whatsapp_leads as used / total. |
Onboard walkthrough
aima onboard is interactive only (no --json). It applies a minimal-confirmation policy: only prompts before calls dispatch, leads initiate, and large CSV uploads.
Voice path
- Config check (
initif missing). - Pick a voice from a select menu.
- Prompt for campaign title, company name, optional system prompt and fields.
- Create voice campaign.
- Add one test lead.
- Confirm, then dispatch call.
- Poll until call ends; print transcript/summary.
WhatsApp path
- Pick existing credentials or start browser connect (
embedded/coexistence). - Validate credentials.
- Template table + select: outbound template, inbound-only, or fallback when no approved templates exist.
- Create WhatsApp campaign.
- Inbound-only: print
display_phone_numberand instruct user to message it. - Outbound: add test lead → confirm
leads initiate→ polllatest_conversationup to 5 minutes.
For AI agents and CI
- Set
AIMA_OUTPUT=jsonor pass--jsonfor parseable stdout. - Errors print the backend
detailfield to stderr with stable exit codes. aima <noun> --helpandaima <noun> <verb> --helpdocument every flag.- Destructive or billable actions (
calls dispatch,leads initiate,phones rent, large CSV) need--yesin non-interactive contexts. - The same API key powers the MCP server for chat-based control.
Related
- Aima MCP — use the same API from Claude, Cursor, or Codex
- Campaigns — dashboard campaign setup
- Integrations — Google Calendar and agent MCP bindings
- Billing — plan limits that
aima usage viewreflects