bland-cli
v0.4.2
Published
The official Bland AI command-line interface
Downloads
651
Readme
Bland CLI
The command-line interface for Bland AI. Build, test, and deploy conversational AI agents from your terminal.
Install
npm install -g bland-cliOr run without installing:
npx bland-cliRequires Node.js 18+.
Quick Start
1. Authenticate
bland auth login --key YOUR_API_KEYOr set the environment variable:
export BLAND_API_KEY=your_key_here2. Check your account
bland auth whoami3. Make a call
bland call send +15551234567 --task "Ask if they're interested in a demo" --voice nat --wait4. Build a pathway
# Scaffold a new project
bland pathway init ./my-pathway --name "Customer Support"
# Edit the YAML file in your editor
# Then push it to Bland
bland pathway push ./my-pathway
# Test it interactively
bland pathway chat <pathway_id> --verboseDev Terminal
An interactive AI-powered development REPL for building phone agents. Powered by Claude — streams responses, executes tools, edits pathways, and pushes to production without leaving your terminal. Launches into a dedicated dark terminal environment.
bland dev # Launch the dev terminal
-m, --model <model> # Claude model (default: claude-opus-4-6)
-t, --max-tokens <n> # Max output tokens per response
-k, --key <key> # Claude API key
--no-banner # Skip ASCII bannerSlash Commands
| Command | Description |
|---------|-------------|
| /help | Show available commands |
| /status | Show session status |
| /model | List models or switch (/model claude-sonnet-4-6) |
| /tokens | View or set max output tokens (/tokens 64000 or /tokens max) |
| /key | Update Claude API key |
| /clear | Clear conversation history |
| /exit | Exit |
Available Models
| Model | Max Output | Context |
|-------|-----------|---------|
| claude-opus-4-6 | 128k | 1M |
| claude-sonnet-4-6 | 64k | 1M |
| claude-haiku-4-5-20251001 | 64k | 200k |
| claude-opus-4-20250514 | 32k | 200k |
| claude-sonnet-4-20250514 | 64k | 200k |
The dev terminal has access to all MCP tools plus local pathway operations (read, write, diff, push, pull). Type / then Tab to autocomplete commands, or just type naturally.
Commands
Authentication
bland auth login # Log in with API key
bland auth login --key sk-... # Log in non-interactively
bland auth logout # Clear credentials
bland auth whoami # Show account info and balance
bland auth switch # Switch between profiles
bland auth profiles # List all saved profilesThe CLI stores profiles in ~/.config/bland-cli/config.json. You can have multiple profiles for different orgs or environments.
Calls
bland call send <number> # Make an outbound call
--task <prompt> # What the AI should do
--pathway <id> # Use a pathway instead of a task
--voice <voice> # Voice selection (nat, josh, etc.)
--from <number> # Caller ID
--first-sentence <text> # Opening line
--model <base|turbo> # Model selection
--max-duration <mins> # Max call length
--wait # Wait and stream live transcript
--record # Enable recording
--transfer <number> # Transfer number
--request-data <json> # Variables to inject
--webhook <url> # Post-call webhook
bland call list # List recent calls
--limit <n> # Max results (default 20)
--status <s> # Filter: completed, active, failed
--from <date> # Start date
--to <date> # End date
--inbound # Only inbound calls
--batch <id> # Filter by batch
bland call get <call_id> # Full call details + transcript
bland call stop <call_id> # End an active call
bland call events <call_id> # View call events
bland call recording <call_id> # Get recording URL
--download # Save to local file
bland call analyze <call_id> # Run post-call analysisPathways
The pathway workflow lets you define conversational flows as YAML files and sync them with the Bland API.
YAML Format
name: "Customer Support"
description: "Handles inbound support calls"
version: draft
global:
voice: nat
model: base
nodes:
greeting:
type: default
prompt: |
Greet the customer warmly. Ask how you can help them today.
tag: { name: "intake", color: "#60A5FA" } # visual grouping in dashboard
dialogue_examples: # few-shot prompt examples
- user: "yo"
agent: "Hey, thanks for calling. What's up?"
- user: "Hi I have a problem"
agent: "Sorry to hear that. What's going on?"
edges:
- target: identify_issue
label: "Customer describes their problem"
- target: transfer_human
label: "Customer asks for a human"
identify_issue:
type: default
prompt: |
Listen to the customer's issue and categorize it.
tag: { name: "triage", color: "#F59E0B" }
extract_variables:
- name: issue_type
type: string
description: "billing, technical, or general"
extract_var_settings:
ignore_previous: false # consider full history
use_audio: false
pathway_examples: # few-shots for routing
- user: "I was overcharged"
target: billing_help
- user: "My internet is down"
target: tech_help
edges:
- target: billing_help
label: "Issue is about billing"
- target: tech_help
label: "Issue is technical"
billing_help:
type: default
prompt: "Help with billing questions."
edges:
- target: goodbye
tech_help:
type: default
prompt: "Help with technical issues."
edges:
- target: goodbye
transfer_human:
type: transfer
number: "+15551234567"
goodbye:
type: end_call
prompt: "Thank the customer and end the call."Pathway Commands
# Project setup
bland pathway init [dir] # Scaffold a new pathway project
--name <name> # Pathway name
# Sync with Bland
bland pathway pull <id> [dir] # Download pathway as YAML
bland pathway push [dir] # Upload YAML to Bland
--create # Create new if no ID linked
bland pathway diff [dir] # Compare local vs remote
bland pathway validate [dir] # Validate YAML locally
bland pathway watch [dir] # Auto-push on file changes
# CRUD
bland pathway list # List all pathways
bland pathway get <id> # Show pathway details
bland pathway create [name] # Create a new pathway
--from-file <path> # Create from YAML file
bland pathway delete <id> # Delete a pathway
bland pathway duplicate <id> # Duplicate a pathway
# Interactive testing
bland pathway chat <id> # Chat with a pathway in your terminal
--start-node <name> # Start at a specific node
--variables <json> # Inject variables (or @file.json)
--verbose # Show node transitions and variables
# Scripted chat (Claude Code / CI — non-interactive)
bland pathway chat <id> \
--message "I need to book a checkup" \
--json # one-shot, prints structured response, exits
bland pathway chat <id> \
--script ./turns.txt \
--json # multi-turn from file, prints transcript with current_node per turn
bland pathway chat <id> \
--chat-id <existing> # resume an existing chat session
--message "and another thing"
# Automated testing
bland pathway test <id> # Run YAML test cases
--file <test.yaml> # Test case file
--parallel <n> # Concurrent test runs
bland pathway simulate <id> # Run AI simulation
--scenario <text> # Scenario description
--count <n> # Number of simulations
# Node-level testing
bland pathway node test <pid> <nid> # Test a single node
--permutations <n> # Number of variations
# Versioning
bland pathway versions <id> # List versions
bland pathway promote <id> # Promote draft to production
# Code nodes
bland pathway code test <pid> <nid> # Test a custom code node
--input <json> # Test input data
# AI generation
bland pathway generate # Generate pathway from description
--description <text>
# Editing
bland pathway edit <id> # Edit a node prompt in $EDITOR
# Folders
bland pathway folder list
bland pathway folder create <name>Test Cases Format
pathway: "Customer Support"
tests:
- name: billing_inquiry
scenario: "Customer calls about a wrong charge on their bill."
expected_path: [greeting, identify_issue, billing_help, goodbye]
expected_variables:
issue_type: "billing"
- name: transfer_request
scenario: "Customer immediately asks to speak to a human."
expected_path: [greeting, transfer_human]Personas
bland persona list # List all personas
bland persona get <id> # Show persona details
bland persona create # Create interactively
bland persona update <id> # Update persona
bland persona delete <id> # Delete persona
bland persona promote <id> # Promote draft to production
bland persona reset-draft <id> # Reset draft to production
bland persona gaps <id> # View knowledge gapsPhone Numbers
bland number list # List owned numbers
bland number buy # Purchase a new number
--area-code <code> # Preferred area code
--country <code> # Country code (default: US)
--count <n> # Buy multiple
bland number release <number> # Release a number
bland number update <number> # Update number config
--pathway <id> # Set inbound pathway
--persona <id> # Set persona
--webhook <url> # Set webhook
--prompt <text> # Set prompt
--voice <voice> # Set voice
bland number configure <number> # Interactive configurationVoices
bland voice list # List available voices
--language <code> # Filter by language
--custom # Show only custom voices
bland voice speak <text> # Generate TTS audio
--voice <voice> # Voice to use (default: nat)
-o, --output <file> # Save to fileTools
bland tool list # List all tools
bland tool get <id> # Show tool details
bland tool create # Create interactively
bland tool update <id> # Update tool
bland tool delete <id> # Delete tool
bland tool test <id> # Test with sample input
--input <json> # Test input data
--verbose # Show full request/response
bland tool types # List tool typesKnowledge Bases
bland knowledge list # List knowledge bases (alias: bland kb list)
bland knowledge create <name> # Create knowledge base
bland knowledge scrape <name> # Scrape URLs into KB
--urls <url1,url2> # Comma-separated URLs
--file <urls.txt> # File with URLs (one per line)
bland knowledge delete <id> # Delete knowledge base
bland knowledge status <id> # Check processing statusTesting: Scenarios & Agent-to-Agent
bland scenario — reusable, assertable regression tests for pathways/personas. New in 0.3.0.
# Seed from built-in templates (Angry Caller, Happy Path, etc.)
bland scenario templates # list templates
bland scenario clone <template_id> --pathway-id <pathway_id> # clone onto your pathway
# Create from scratch
bland scenario create --name 'Interruption recovery' \
--pathway-id <id> \
--tester-prompt 'You are a caller who interrupts mid-sentence...' \
--assertions '[{"type":"LLM_JUDGE","config":{"prompt":"Did the agent recover gracefully?"}}]'
# Turn a real call into a regression test
bland scenario generate --call-id <call_id> --pathway-id <id>
# Run
bland scenario run <scenario_id> # one scenario
bland scenario batch-run --scenario-ids '["id1","id2"]' # many in parallel (CI)
bland scenario flake --scenario-ids '[...]' --iterations 10 # flakiness detection
# Debug a failure
bland scenario run-get <run_id> # transcript + assertions
bland scenario analyze <run_id> # AI root-cause + fix suggestions
# Analytics
bland scenario analytics <pathway_id> # basic: pass rate
bland scenario analytics <pathway_id> --enhanced # node failure heatmap, weakest link
# Tornado — iterative auto-fix (modifies your pathway!)
bland scenario tornado start --pathway-id <id> --scenario-ids '[failing...]'
bland scenario tornado status <tornado_id>
bland scenario tornado cancel <tornado_id>bland simulate — ad-hoc agent-to-agent: spin up 1–5 AI caller profiles in parallel.
bland simulate --pathway-id <id> \
--profile 'Rushed Exec::book an appt ASAP' \
--profile 'Confused Elder::ask the same question 3 times'
# Returns simulation_id + per-profile call_ids — inspect via `bland call get <call_id>`Run bland guide get testing or bland guide get scenarios for the full testing decision tree.
Batch Campaigns
bland batch create # Create batch campaign
--file <contacts.csv> # Contacts CSV file
--pathway <id> # Pathway to use
--from <number> # From number
bland batch list # List batches
bland batch get <id> # Batch details + stats
bland batch stop <id> # Stop a running batchSMS
bland sms send <number> # Send SMS
--from <number> # From number
--message <text> # Message text
--pathway <id> # Use pathway for conversation
bland sms conversations # List SMS conversations
bland sms get <id> # Get conversation threadOther Commands
# Web agents
bland agent list | get | create | update | delete
# Guard rails
bland guard list | create | delete
# Monitoring
bland alarm list | create | delete
# Secrets
bland secret list | set | delete
# Releases
bland release list | create | promote
# Widgets
bland widget list | create | delete
# Evaluations
bland eval run | list | get
# Audio
bland audio generate <text> --voice <voice> -o <file>
bland audio analyze <file>
# SIP
bland sip discover <host>
# Local development
bland listen # Forward webhooks to localhost
--forward-to <url> # Your local server URL
--port <n> # Listen port (default: 4242)
--events <types> # Filter event typesProfiles
The CLI supports multiple profiles for managing different API keys or organizations.
# Add a second profile
bland auth login --key sk-staging-xxx
# Switch between profiles
bland auth switch
# List profiles
bland auth profilesProfiles are stored at ~/.config/bland-cli/config.json. You can also override the API key per-command with BLAND_API_KEY:
BLAND_API_KEY=sk-staging-xxx bland pathway listPathway Workflow
The typical development cycle for pathways:
1. bland pathway init ./my-bot # Scaffold project
2. Edit bland-pathway.yaml # Write your flow
3. bland pathway validate # Check for errors
4. bland pathway push --create # Upload to Bland
5. bland pathway chat <id> --verbose # Test interactively
6. bland pathway test <id> # Run automated tests
7. bland pathway promote <id> # Ship to production
8. bland pathway watch # Auto-push on saveMCP Server
The CLI includes an MCP (Model Context Protocol) server that lets AI coding tools like Claude Code and Cursor interact with your Bland account.
# Start the MCP server
bland mcp
# Or with SSE transport
bland mcp --transport sse --port 3100Claude Code Setup
Add to your Claude Code config:
{
"mcpServers": {
"bland": {
"command": "npx",
"args": ["bland-cli", "mcp"]
}
}
}Available MCP Tools
82 tools across all resource types:
Guides
| Tool | What it does |
|------|-------------|
| bland_guide_list | List all available guides (start here) |
| bland_guide_get | Read a specific guide by slug |
Calls
| Tool | What it does |
|------|-------------|
| bland_call_send | Make a phone call |
| bland_call_list | List recent calls |
| bland_call_get | Get call details and transcript |
Pathways
| Tool | What it does |
|------|-------------|
| bland_pathway_list | List pathways |
| bland_pathway_get | Get pathway details |
| bland_pathway_create | Create a pathway from nodes/edges |
| bland_pathway_chat | Chat with a pathway |
| bland_pathway_node_test | Test a single node |
| bland_pathway_simulate | Persona-based simulation (resumable) |
| bland_pathway_simulation_get | Get simulation status |
| bland_pathway_simulation_continue | Continue a paused simulation |
Testing Scenarios (new in 0.3.0)
| Tool | What it does |
|------|-------------|
| bland_scenario_list / _get / _create / _update / _delete | Scenario CRUD |
| bland_scenario_generate | AI-generate a scenario from a historical call |
| bland_scenario_run / _runs_list / _run_get | Run a scenario, inspect past runs |
| bland_scenario_run_analyze | AI root-cause analysis of a failed run |
| bland_scenario_batch_run / _batch_get | Run many scenarios in parallel (CI-style) |
| bland_scenario_simulation_create / _simulation_get | Flakiness detection (run N× each) |
| bland_scenario_analytics / _analytics_enhanced | Pass rate, node heatmap, weakest link |
| bland_scenario_templates_list / _template_clone | Seed from built-in templates |
| bland_scenario_tornado_* | Iterative auto-fix loop (4 tools) |
| bland_simulate_calls | Ad-hoc agent-to-agent: 1–5 AI callers in parallel |
Personas
| Tool | What it does |
|------|-------------|
| bland_persona_list | List personas |
| bland_persona_get | Get persona details |
| bland_persona_create | Create a new persona |
| bland_persona_update | Update persona config |
| bland_persona_delete | Delete a persona |
| bland_persona_versions_list | List persona versions |
| bland_persona_draft_get | Get draft version |
| bland_persona_production_get | Get production version |
| bland_persona_promote | Promote draft to production |
| bland_persona_reset_draft | Reset draft to production |
| bland_persona_inbound_attach | Attach phone numbers |
| bland_persona_inbound_detach | Detach phone numbers |
| bland_persona_memory_update | Update persona memory |
| bland_persona_gaps_list | List knowledge gaps |
| bland_persona_gap_resolve | Resolve a knowledge gap |
Knowledge Bases
| Tool | What it does |
|------|-------------|
| bland_knowledge_list | List knowledge bases |
| bland_knowledge_get | Get KB details |
| bland_knowledge_create_text | Create KB from text |
| bland_knowledge_create_web | Create KB by scraping URLs |
| bland_knowledge_update | Update KB name/description |
| bland_knowledge_delete | Delete a KB |
| bland_knowledge_query | Query KB with RAG |
| bland_knowledge_chat | Multi-turn chat with KB |
| bland_knowledge_crawl | Discover sitemap URLs |
| bland_knowledge_content_get | Get KB content |
| bland_knowledge_content_update | Update KB text content |
| bland_knowledge_versions_list | List KB versions |
| bland_knowledge_version_restore | Restore a KB version |
| bland_knowledge_replace_urls | Replace web-scrape URLs |
| bland_knowledge_gaps_list | List knowledge gaps |
| bland_knowledge_gap_resolve | Resolve a gap |
| bland_knowledge_analytics | Get KB analytics |
Other
| Tool | What it does |
|------|-------------|
| bland_number_list | List phone numbers |
| bland_number_buy | Buy a phone number |
| bland_voice_list | List available voices |
| bland_tool_test | Test a custom tool |
| bland_audio_generate | Generate TTS audio |
For LLMs
The CLI ships with a built-in guide system designed to give LLMs (Claude, Cursor, GPT, etc.) the context they need to build good pathways — not just call the API, but actually understand how phone conversations work.
How it works
When an LLM connects via MCP, it receives:
instructions— a condensed overview of the Bland platform, pathway architecture, common mistakes, and recommended workflow. This loads automatically on connect.bland_guide_list/bland_guide_get— tools to pull long-form guides on demand for deeper context.
The guides are also available to humans via the CLI:
bland guide # List all guides
bland guide phone-tone # Writing natural phone prompts
bland guide pathways # Node/edge architecture and execution model
bland guide tools # Webhook and custom tools on nodes
bland guide testing # Chat, simulate, node tests
bland guide variables # Extracting and using caller dataWhat the guides cover
| Guide | What it teaches |
|-------|----------------|
| phone-tone | How to write prompts that sound like a real person on the phone — not a chatbot. Covers back-channeling, brevity, empathy, and topic transitions. |
| pathways | How the conversation graph works: nodes, edges, global nodes, variables, the global prompt, and the execution model. |
| tools | Attaching webhook and custom tools to nodes for real-time data (check availability, look up orders). Covers speech, behavior, and response_data. |
| testing | The full testing workflow: pathway chat for interactive testing, simulate for end-to-end AI personas, node-test for stress-testing individual nodes. |
| variables | Extracting structured data from natural conversation with extract_variables, using {{curly_braces}} in prompts, and spelling_precision for names/emails. |
Why this matters
LLMs building pathways make predictable mistakes:
- Writing edge labels as boolean conditions (
if intent == "booking") instead of natural language (Caller wants to book an appointment) - Making prompts too verbose and chat-like instead of concise and phone-natural
- Forgetting global nodes for edge cases callers will absolutely hit
- Not setting a global prompt for tone, so every node sounds different
- Building without testing — the guides teach
pathway chat --verbosefirst, real calls second
The guide system fixes this by giving the LLM opinionated, Bland-specific knowledge before it starts writing. It's the difference between an LLM that can call the API and one that actually builds good phone agents.
Default phone tone
When you scaffold a new pathway with bland pathway init, the global prompt comes pre-loaded with phone-tone instructions:
global:
prompt: |
Sound natural and midwestern. Everything you say is spoken aloud on a phone call.
Play this game silently for every reply: what is the most accurate response,
then how can I reduce it to the fewest words without sounding rude?
Never recontextualize — no 'just to confirm', 'you said', 'got it'.
Use 'gotcha', 'yup', 'cool'.
Back-channel freely: 'mhmm', 'uh huh', 'right'.
Acknowledge emotions in stride.
Topic transitions are natural breaks — slightly more formal.
Within a topic, keep it tight.
After collecting one field, move immediately: 'And last?' not
'Could you also provide your last name?'This sets the baseline voice for every node. LLMs using the MCP tools will also receive this guidance through the phone-tone guide.
Local Webhook Development
Forward Bland webhooks to your local dev server without ngrok:
# Terminal 1: your app
node server.js
# Terminal 2: bland webhook forwarder
bland listen --forward-to http://localhost:3000/webhookThe CLI creates a webhook endpoint and forwards incoming events to your local URL, logging each event with timestamps and response codes.
JSON Output
Every list and get command supports --json for piping to jq or scripts:
# Get all pathway IDs
bland pathway list --json | jq '.[].id'
# Get a call transcript as JSON
bland call get <id> --json | jq '.transcripts'
# Count active numbers
bland number list --json | jq 'length'Environment Variables
| Variable | Purpose |
|----------|---------|
| BLAND_API_KEY | API key (overrides stored profile) |
| BLAND_BASE_URL | API base URL (default: https://api.bland.ai) |
Project Files
When you run bland pathway init, it creates:
my-pathway/
bland-pathway.yaml # Pathway definition
tests/
test-cases.yaml # Test cases
.blandrc # Project config (pathway ID, file paths)The .blandrc file links your local project to a remote pathway:
pathway_id: pw_abc123
pathway_file: bland-pathway.yaml
test_file: tests/test-cases.yamlLicense
MIT
