Docs
Aima CLI

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/aima

uv / pipx (isolated install on your PATH):

uv tool install aimalabs-cli
# or: pipx install aimalabs-cli

pip:

pip install aimalabs-cli

Run once without installing (does not add aima to PATH):

uvx --from aimalabs-cli aima --help

Upgrade 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 walkthrough

Manual 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 --poll

Configuration

Config file: ~/.aima/config.json (mode 0600):

{
  "base_url": "https://api.aimalabs.io",
  "api_key": "api_..."
}
VariableEffect
AIMA_API_KEYOverride api_key
AIMA_BASE_URLOverride base_url (staging or self-hosted)
AIMA_CONFIGAlternate config file path
AIMA_OUTPUT=jsonForce 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 confirmation

If 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

CodeMeaning
0Success
1User error — bad flags, validation, or HTTP 4xx (detail on stderr)
2Server or network error — HTTP 5xx or transport failure
3Missing or invalid config

Commands

Setup

CommandDescription
aima initInteractive first-run wizard. Prompts for API key, optionally base_url. Validates via GET /api/cli/voices. Idempotent.
aima statusPrints config (masked key) and probes API connectivity.
aima onboardGuided walkthrough — choose voice or whatsapp. Cannot run with --json.

Config

CommandDescription
aima config showShow current config.
aima config set <base_url|api_key> <value>Update one key.
aima config clearDelete config file after confirmation.

Voices

CommandDescription
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

CommandDescription
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

CommandDescription
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:

FlagNotes
--campaign-type whatsappMessaging only; no voice dispatch.
--campaign-type hybridVoice + WhatsApp on one campaign.
--whatsapp-credentials-id IDRequired for whatsapp and hybrid.
--template-name NAMERequired for outbound WhatsApp (not with --inbound-only).
--template-language LANGBCP-47 code; default en on server.
--inbound-onlyAgent 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-only

Extraction 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

CommandDescription
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

CommandDescription
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

CommandDescription
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_idphones rentphones list shows assignment_id for release.

WhatsApp credentials

CommandDescription
aima whatsapp connect embedded|coexistence [--no-browser] [--timeout SEC]Browser connect via dashboard page (30 min session TTL; default poll timeout 1800s).
aima whatsapp listList 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:

  1. CLI creates a connect session (POST /api/cli/whatsapp/connect-sessions).
  2. Opens {DASHBOARD_URL}/connect/whatsapp/{session_id} (Meta FB JS SDK embedded signup — not a localhost OAuth redirect).
  3. Polls every ~3s until completed, failed, or timeout.
  4. embedded = new WhatsApp Business API number. coexistence = link an existing Business app.

Run aima whatsapp validate <id> before creating campaigns.

Usage

CommandDescription
aima usage viewCurrent 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

  1. Config check (init if missing).
  2. Pick a voice from a select menu.
  3. Prompt for campaign title, company name, optional system prompt and fields.
  4. Create voice campaign.
  5. Add one test lead.
  6. Confirm, then dispatch call.
  7. Poll until call ends; print transcript/summary.

WhatsApp path

  1. Pick existing credentials or start browser connect (embedded / coexistence).
  2. Validate credentials.
  3. Template table + select: outbound template, inbound-only, or fallback when no approved templates exist.
  4. Create WhatsApp campaign.
  5. Inbound-only: print display_phone_number and instruct user to message it.
  6. Outbound: add test lead → confirm leads initiate → poll latest_conversation up to 5 minutes.

For AI agents and CI

  • Set AIMA_OUTPUT=json or pass --json for parseable stdout.
  • Errors print the backend detail field to stderr with stable exit codes.
  • aima <noun> --help and aima <noun> <verb> --help document every flag.
  • Destructive or billable actions (calls dispatch, leads initiate, phones rent, large CSV) need --yes in non-interactive contexts.
  • The same API key powers the MCP server for chat-based control.
  • 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 view reflects