Every command
The loop is five words — create, edit, verify, push, deploy — and then you
call. kelam --help is always authoritative: the CLI ships often, and its help
text matches the version you actually have installed.
curl -fsSL https://kelam.sh | sh && kelam login
The grammar worth knowing up front
- Any
AGENTargument takes anagt_id, the agent's name, or the path of a pulled folder. Inside a pulled folder, most commands need no agent argument at all. - One scoping rule for every listing (
calls,peers,texts,costs,stats,export,search): bare is the whole workspace, an agent argument narrows to that agent, and inside a pulled folder the folder's agent is assumed —--allforces the workspace view. - Everything is JSON when piped, and
--jsonforces it. Collections come back as objects keyed by their plural noun:{"agents": [...]},{"calls": [...], "next_cursor": ...}. - Blocking flags exist so you never poll.
--waitoncallandstatusblocks until the call ends and prints the outcome. - Exit 0 on success; failures print one actionable line on stderr and exit 2.
Setup
Sign in and save your workspace credential locally — no environment variables needed after this.
Forget the saved credential on this machine.
Update the CLI to the latest release — detects however it was installed (brew / uv / pipx). Also refreshes an installed project guide.
The operating guide for AI coding agents — print it, or --install it into a project. More →
Print your workspace's MCP connector URL — paste it into claude.ai to use Kelam from Claude. More →
List your workspace's people, or add one with --add email.
Show or edit context, one command by arity — bare is the workspace lane every agent inherits, kelam context <agent> is that agent's own, kelam context <agent> <peer> is what it remembers about one caller.
The agent loop
Create an agent and pull it into ~/.kelam/agents/<name>/ — your workspace's number attaches automatically. --no-number for a browser-only agent, --buy-number for a dedicated line, --template for a preset.
Pull an agent's files into a local folder (bare, inside a pulled folder, refreshes it in place).
Lint a local agent folder — config, tools, secret and context references. Every problem comes back as a list of issues.
Push the folder back. Every push is a new version.
Assemble and cache the runtime — that version is now the one that answers.
Run the agent's test suite against its deployed version — fast text assertions and real $0 agent-to-agent voice tests. Non-zero exit on failure.
An agent's deployed versions, newest first — the set you can pin a single call to.
The agent.yaml contract as data — models, voices, every field. Narrow it: kelam schema turn.detection, kelam schema tests, kelam schema evals.
The workspace's agents. --full prints each one's generated usage guide.
Set a workspace secret, stored encrypted — the value never touches the command line.
List secret names — what secret("NAME") in a tool resolves at call time. Values are never read back out.
Show — or edit — an agent's inbound caller allowlist. The owner's number always stays allowed.
Send a known caller straight to a specific agent by their number — deterministic, ahead of any voice concierge.
Delete an agent. Destructive, so the argument is always explicit.
Calling
Place a real outbound call — to a number, or to another agent with no telephony at all. --wait streams the transcript and returns the finished record; -p steers this one call; -e extracts typed fields; --in/--at schedule it.
Open the agent's page — talk to it in the browser, audition voices, edit it with the Builder chat.
Where things stand, in one round — one call's lifecycle, or the whole workspace. --wait blocks until the call (or several) ends.
The live-calls dashboard — listen to any call as it happens, invisible to both sides.
End a call now, or after a polite goodbye with --wrap-up. Your abort handle once something has dialed.
Calls parked behind the concurrency cap, oldest first — over-placing a batch is safe.
Inspect — or re-run — the exact configuration that took a call. --to re-dials it at a phone you control or a simulator agent, never the original callee.
Mark a call as worth debugging (or clear the mark). kelam calls --flagged is the review queue.
Call data
Every call in the workspace, newest first — or one agent's. Filter by status, direction, peer, age, whether a human answered; --live for in-progress, --tree to nest calls under the call that spawned them.
One call's transcript and recording — or a number's full voice-and-text history, which is what you compose a reply from.
Find anything fast — a call, an agent, a peer, a chat, or a context fact.
Call logs plus derived metrics — turns, words, talk ratio, durations, cost — as jsonl, json, or csv (with a column per extracted field).
Aggregate counts, duration percentiles, turn totals, and per-provider cost.
What you've actually spent — real money, not an estimate.
Pull typed fields out of calls you already made — a model pass over each transcript, persisted onto the call.
Texting
Send SMS or MMS (or WhatsApp) from the agent's own number.
Browse an agent's message threads, newest first.
Recently active numbers across calls and texts — the people your agents talk to.
Experiments
Weighted variants of one agent, compared on real traffic. Assignment is sticky per caller, and no winner is named before there's enough data to mean anything.
Start an experiment: --variant name="llm.model=…" patches knobs over the deployed base, --variant name=@<ref> pins a deployed version. Set --split, --min-calls, a --primary metric and --guardrails.
Start a common experiment from a template — the turnkey path into ab create.
Variants, weights, per-arm call counts, and progress toward the minimum.
Per-arm value with a 95% interval and the probability each variant beats the others.
End it — --adopt <variant> promotes that variant to the agent's live config.
Account
Request a plan upgrade for your workspace.
List pending upgrade requests, or approve one (platform admin).
Mint a shareable signup invite link (admin).
List your invite links, or revoke one (admin).
Two patterns worth copying
Batch a list, then sweep once
$ for n in $(cat numbers.txt); do kelam call bot "$n" -p "$GOAL"; done # collect the call_ids from those acks, then ONE blocking sweep: $ kelam status <id1> <id2> <id3> --wait --progress --timeout 600
Stop everything
$ kelam queue # parked calls -> kelam hangup <call_id> each $ kelam calls --live # dialed calls -> kelam hangup <call_id> each # run both again to confirm they come back empty
Full guides live at kelam.sh/docs,
and kelam --help knows everything on this page.