ChatterBox VOCAL CLI
vocal is the public, agent-friendly CLI for ChatterBox VOCAL, an API for outbound AI phone calls.
The CLI is designed for non-interactive automation: explicit config precedence, JSON output, deterministic exit codes, safe API-key handling, diagnostics, shell completions, and idempotency headers on mutating commands.
Install
go install github.com/TalentedCo/vocal-cli/cmd/vocal@latest
Confirm the binary is available:
vocal --help
vocal doctor --json
vocal version --check-update
Use stdin or a file when possible so API keys do not land in shell history:
printf '%s\n' "$VOCAL_API_KEY" | vocal auth save --api-key-stdin --profile default
vocal auth status --json
For one-off automation, environment variables or explicit flags are supported:
VOCAL_API_KEY=sk_live_... vocal calls list --json
vocal --api-key sk_live_... calls list --json
Stored credentials are written to ~/.config/vocal/config.json with 0600 permissions. CLI output only shows masked key fingerprints such as sk_live...abcd.
Config Precedence
Highest to lowest:
- CLI flags:
--api-key, --api-url, --profile, --config
- Environment variables:
VOCAL_API_KEY, VOCAL_API_URL, VOCAL_PROFILE
- Compatibility environment variables:
CHATTERBOX_API_KEY, CHATTERBOX_API_URL, CHATTERBOX_PROFILE
- Selected named profile in the config file
- Default profile in the config file
- Built-in default API URL:
https://chatterboxagent.com/api/v1
Agent Workflow
Run diagnostics:
vocal doctor --json
Request a provisional account/API key for a human owner to review:
vocal signup agent \
--json \
--non-interactive \
--agent-email "agent@example.com" \
--agent-name "Build Agent" \
--owner-email "owner@example.com" \
--project-name "ACME outbound test" \
--idempotency-key "owner@example.com:acme:$(date +%s)"
The command returns a constrained sk_agent_... key only on first creation when the owner email does not already have an active account. Retries with the same idempotency key return the existing request with the key masked. The human owner receives an accept/reject/revoke invite and paid or expanded usage remains locked until owner acceptance and billing setup.
Create a call with explicit non-interactive flags:
vocal calls create \
--json \
--non-interactive \
--idempotency-key "agent-run-$(date +%s)" \
--phone-number "+14155551234" \
--from-name "Sarah from ABC Corp" \
--recipient-name "John Smith" \
--call-objective "Schedule a 30-minute Zoom demo. Sarah is available Tuesday 2-5pm ET or Wednesday 10am-2pm ET. Send the invite to sarah@example.com." \
--max-retries 0 \
--webhook-url "https://example.com/webhooks/vocal" \
--webhook-header "Authorization=Bearer ${VOCAL_WEBHOOK_SECRET}"
Inspect and stream status:
vocal calls get CALL_ID --json
vocal calls stream CALL_ID --json
Receive Final Webhook Results
When --webhook-url is set, VOCAL sends a final call.completed POST after the call ends. Use repeatable --webhook-header KEY=VALUE flags to attach caller-provided auth headers to that callback:
vocal calls create \
--json \
--non-interactive \
--idempotency-key "agent-run-$(date +%s)" \
--phone-number "+14155551234" \
--from-name "Sarah from ABC Corp" \
--call-objective "Schedule a 30-minute Zoom demo. Sarah is available Tuesday 2-5pm ET or Wednesday 10am-2pm ET." \
--max-retries 0 \
--webhook-url "https://example.com/webhooks/vocal" \
--webhook-header "Authorization=Bearer ${VOCAL_WEBHOOK_SECRET}" \
--webhook-header "X-Workflow-ID=agent-run-123"
Webhook headers are sent to your receiver as provided. Keep shared secrets in environment variables or your secret store, not in shell history or checked-in scripts.
Commands
vocal auth save --api-key-stdin|--api-key-file PATH|--api-key VALUE
vocal auth status
vocal auth logout
vocal status
vocal version [--check-update]
vocal doctor [--check-api] [--check-updates]
vocal signup agent --agent-email ... --owner-email ... --idempotency-key ...
vocal calls create --phone-number ... --call-objective ... --from-name ... [--webhook-url URL] [--webhook-header KEY=VALUE]
vocal calls get CALL_ID
vocal calls list [--status STATUS] [--limit N] [--offset N]
vocal calls stream CALL_ID
vocal completion bash|zsh|fish|powershell
JSON Output
Use --json for automation. Successful commands use:
{
"ok": true,
"data": {},
"summary": "Call created"
}
Errors use:
{
"ok": false,
"error": {
"code": "auth_error",
"message": "no API key configured; run vocal auth save or set VOCAL_API_KEY"
}
}
Exit Codes
| Code |
Meaning |
0 |
Success |
1 |
General error |
2 |
Usage error |
3 |
Config error |
4 |
Auth error |
5 |
VOCAL API error |
6 |
Network error |
auth status, status, version, and doctor are safe to run in fresh environments and return structured state instead of revealing secrets. vocal version --check-update and vocal doctor --check-updates make a best-effort GitHub request and suggest:
go install github.com/TalentedCo/vocal-cli/cmd/vocal@latest
when a newer default-branch build is available. They never self-update the binary.
Idempotency
Mutating commands accept --idempotency-key and send it as the Idempotency-Key HTTP header. The CLI exposes this foundation for agent-first signup and other retry-safe workflows.
Shell Completions
vocal completion bash > /usr/local/etc/bash_completion.d/vocal
vocal completion zsh > "${fpath[1]}/_vocal"
vocal completion fish > ~/.config/fish/completions/vocal.fish
Development
go test ./...
go vet ./...