Imported from asksyllable/syllable-cli (
.claude/skills/syllable-cli/SKILL.md). Install upstream withnpx skills add asksyllable/syllable-cli --skill syllable-cli. Copyright stays with the author.
Syllable CLI
A Go CLI for managing the Syllable AI platform. Source and releases: https://github.com/asksyllable/syllable-cli
Docs synced to CLI v2.2.0 — bump this marker whenever these docs are updated for a new release.
v2.2.0 (minor) highlights — purely additive, no breaking changes: new
sessions timeline <session-id>command returning one consolidated, time-ordered stream of transcript turns, tool calls, and latency events with offsets from session start; outbound batch create/update bodies acceptcall_rateandauto_call_rate(per-batch rate control, withauto_call_rate_baselinein responses);SipConfigurationgainscall_info_placement; sessions exposeoverride_timestamp; new Cartesia TTS provider with thesonic-3.5voice model and 18 new voices across US/MX/ES/KR/CN/VN/TH.v2.1.0 (minor) highlights — purely additive, no breaking changes: new
bridge-phrasescommand (list/get/create/update/delete) for the named, reusable hold-phrase configs, attached to an agent viabridge_phrases_id;conversation-config bridgesandbridges-updatetake optional--agent-id/--tool-nameto scope the config (omit both for the org-level default);sessions list --include-testhelp text corrected — the flag keys off the session-levelis_testflag, not channel targets.v2.0.0 (major) highlights — the breaking changes still apply: destructive
deletecommands confirm interactively and need--yeswhen non-interactive;channels deletewas removed (no such API op — usechannels targets delete);data-sources createinline takes--text(the document-body field) in place of the old, non-functional--content. Also:--outputis validated; unknown--fieldscolumns warn;--dry-runlists anymissing_required_fields;--debugredacts credentials.
Installation
Homebrew (recommended for macOS/Linux):
brew tap asksyllable/syllable-cli https://github.com/asksyllable/syllable-cli
brew install --cask syllable
Install script:
curl -fsSL https://github.com/asksyllable/syllable-cli/releases/latest/download/install.sh | sh
Setup — First Time and Any Config Changes
Any time the user needs to configure the CLI — whether it's the first time, adding a new org, adding a new environment, or updating an API key — run:
syllable setup
This opens a browser UI where the user can safely manage all orgs, API keys, and environments. Always use this command for config changes — never edit ~/.syllable/config.yaml directly or ask the user to paste API keys into the terminal.
Trigger syllable setup whenever the user says things like:
- "I need to add a new org"
- "Add a new environment"
- "Update my API key"
- "Set up credentials for [org]"
- "I'm getting auth errors" (may need a key update)
- First use — if
~/.syllable/config.yamldoesn't exist or has no orgs configured
Check if setup is needed:
test -f ~/.syllable/config.yaml && echo "configured" || echo "not configured"
IMPORTANT — Never read or display config files. The config at ~/.syllable/config.yaml contains API keys. Never cat, read, head, or otherwise output its contents. Use syllable setup for any config changes and the test -f check above to verify it exists.
Org & Environment Confirmation
Before executing any command that reads or modifies platform resources, always confirm the target org and environment with the user. Run syllable status first to see all configured orgs and environments:
syllable status
This shows each configured org, its environment(s), and whether an API key is present. Use it to:
- Resolve vague user references — e.g., "acme" → find the matching configured org name like
acme-healthoracme - Discover org naming conventions — see the exact short names configured
- Confirm the target before executing — especially for create, update, or delete operations
- Verify environment — ensure you're targeting prod vs. staging vs. dev
Always tell the user which org and environment you're about to run against and get confirmation before proceeding, particularly for write operations.
Bridge Phrases — Confirm Which Config Surface First
Two commands write bridge phrases, with separate storage. Writing the wrong one appears to succeed and changes nothing the agent actually uses.
| Command | What it writes |
|---|---|
bridge-phrases |
Named, reusable configs, attached per agent via the agent's bridge_phrases_id |
conversation-config bridges-update |
A single config in place, scoped to the org / an agent (--agent-id) / a tool (--tool-name) |
Before any bridge-phrase write, ask the user which of the two they mean. Do not guess, and do not default to one.
If the user doesn't know, ask them to check the Console: does the agent's config page let them set a bridge phrase config per agent?
- Yes → use
bridge-phrases. - No → use
conversation-config bridges-update.
conversation-config is slated for deprecation; bridge-phrases is the forward-looking surface. Until that lands, both are live and the question above is the only reliable way to tell which one an org is on — the API answers a write to either with a 200 regardless.
Reads skip only the which-surface question — the org & environment confirmation above still applies to them. When diagnosing, reading both is often the fastest way to find where an org's phrases actually live:
syllable bridge-phrases list
syllable conversation-config bridges
syllable conversation-config bridges --agent-id <id>
Full field shapes and gotchas: references/commands.md § Bridge Phrases, references/gotchas.md § Bridge Phrases — two separate surfaces.
Quick Start
syllable --help
Select an org per command:
syllable --org acme agents list
syllable --org globex sessions list
If default_org is set in ~/.syllable/config.yaml, it's used when --org is omitted.
Global Flags
| Flag | Env Var | Default | Description |
|---|---|---|---|
--org |
-- | default_org in config |
Org name to look up API key (e.g. acme, globex) |
--base-url |
-- | https://api.syllable.cloud |
API base URL (overrides --env) |
--env |
-- | -- | Named environment (e.g. prod, staging, dev) — sets base URL from config |
--output / -o |
-- | table |
Output format: table or json |
--fields |
-- | -- | Comma-separated columns to show in table output (e.g. id,name,type) |
--config |
-- | ~/.syllable/config.yaml |
Config file path |
--dry-run |
-- | false |
Preview API requests without executing them |
--debug |
-- | false |
Print HTTP request/response details to stderr |
Common List Flags
All list commands support these flags:
| Flag | Default | Description |
|---|---|---|
--page |
0 |
Page number (0-based) |
--limit |
25 |
Max items to return |
--search |
— | Search filter (field varies by resource — see table below) |
--search-field |
per-resource default below | Override which field --search filters on (free-form, passed to the API as search_fields) |
For sessions, the valid --search-field values are the SessionProperties enum — syllable schema get SessionProperties lists them (agent_name, source, target, channel_manager_sid, prompt_name, is_outbound, …). String fields filter server-side; filter boolean fields (is_test, is_outbound) client-side with jq — see references/gotchas.md.
Default search field by resource:
| Resource | --search filters on |
|---|---|
| agents | name |
| prompts | name |
| tools | name |
| channels | name |
| sessions | agent_name |
| conversations | agent_name |
| outbound batches | batch_id |
| outbound campaigns | campaign_name |
| users | |
| directory | name |
| insights workflows | name |
| insights folders | name |
| custom messages | name |
| language groups | name |
| organizations | display_name |
Resources & Verbs (summary)
Every command takes the form syllable [--org X] [--env Y] <resource> <verb> [args].
Resources: agents, prompts, tools, services, channels (+ channels targets, channels twilio, channels available-targets), sessions, conversations, outbound batches, outbound campaigns, users, directory, insights workflows, insights folders, insights tool-configs, insights tool-definitions, custom-messages, language-groups (deprecated → use voice-groups), voice-groups, data-sources, roles, incidents, pronunciations, session-labels, session-debug, takeouts, events, permissions, bridge-phrases, conversation-config (slated for deprecation → prefer bridge-phrases), dashboards, organizations (current-org get/update + sip-ip-ranges; no create/delete), schema, status.
Standard verbs (most resources):
syllable <resource> list [--page N] [--limit N] [--search TEXT]
syllable <resource> get <id>
syllable <resource> create --file body.json # or inline flags (see references/commands.md)
syllable <resource> update <id> --file body.json # PUT, full replacement — see warning below
syllable <resource> delete <id> --yes # destructive — see note below
Destructive commands confirm first.
deleteprompts for a y/N confirmation. Running non-interactively (scripts, CI, an agent driving the CLI) you must pass--yes/-yor the command refuses with an error and does nothing.--dry-runpreviews the request without deleting. (users delete-accountand the pronunciation-CSV commands keep their own--confirmflag.)
Resource-specific verbs worth knowing inline:
| Resource | Verbs |
|---|---|
prompts |
history <id>, supported-llms |
tools |
history <tool-id> (v1.7, version history); get accepts name or numeric ID (v1.7 — IDs resolved via the list endpoint) |
sessions |
transcript <id>, summary <id>, latency <id>, recording <id>, recording-stream --token <token> |
outbound batches |
results <id>, requests <id> --file …, remove-requests <id> --file … |
channels |
get <id> (v1.7, resolved client-side via list), targets list/get/create/update/delete, available-targets, twilio get/create/update/numbers-list/numbers-add/numbers-update/numbers-verify-a2p-compliance (last is v1.7). No top-level channels delete — the API has no delete-channel op; remove a target with channels targets delete <channel-id> <target-id> (v1.8) |
agents |
send-test-message <id> --test-id <id> [--session-start] --text "<msg>" (conversation test API), labels (v1.7, active agent labels), voices (available voices) |
insights workflows |
activate <id>, inactivate <id> |
insights folders |
files <id> |
users |
me (requires your email in config — fails loudly otherwise, v1.7), send-email <email> |
directory |
history <id>, restore <id>, test <id> [--timestamp …], download, upload --file … |
organizations |
get (current org incl. Console SLUG), update, sip-ip-ranges list/create/update/delete (v1.7) — no org create/delete (intentionally not exposed) |
pronunciations |
list, get-csv, metadata |
session-debug |
by-session-id <id>, by-sid <id> <sid>, tool-result <id> <tool-result-id> |
takeouts |
create --file …, get <id>, download <id> <file> |
incidents |
organizations |
bridge-phrases |
standard CRUD (v2.1) — named, reusable hold-phrase configs attached to an agent via the agent's bridge_phrases_id. update is a PUT on the collection keyed by the body id. At most one non-deleted config per suborg may be is_default. Confirm the surface before writing — see § Bridge Phrases — Confirm Which Config Surface First |
conversation-config |
bridges, bridges-update --file … — both take optional --agent-id/--tool-name to scope the config to an agent or tool (v2.1); omit for the org default. Reads/writes a single config, not named resources. Slated for deprecation in favor of bridge-phrases; confirm the surface before writing — see § Bridge Phrases — Confirm Which Config Surface First |
dashboards |
list, sessions, session-events, session-transfers, session-summary, fetch-info --name <name> |
schema |
list [--filter X], get <SchemaName> (local OpenAPI lookup, no API call; -o json is pure JSON since v1.7 — pipe straight to jq) |
status |
no verb — prints all configured orgs/envs (read-only, local config) |
<id> for sessions is the numeric Syllable session ID (e.g., 824) — not the Twilio CA<hex> call SID. Any session_id-keyed call (sessions get/transcript/summary, GET /sessions/full-summary/{session_id}, sdk.sessions.getById) returns 400 on a CA… SID; that value is the session's channel_manager_sid. To resolve one from the other: sessions list --search-field channel_manager_sid --search "CA…" -o json. See references/sessions-and-debugging.md.
For exact flag syntax, table-column listings, get-fields, inline-create flag sets, and resource-specific notes (e.g. users get/update/delete/send-email are keyed by email address, not a numeric ID), see references/commands.md.
For send-test-message conversation flow details (greeting / follow-up / silence / DTMF), see references/commands.md § Conversation Test API.
Auth
All requests use the header:
Syllable-API-Key: <api-key>
Auth is skipped for help and completion commands. HTTP client timeout is 30 seconds.
Headless / CI auth (v1.7+): the SYLLABLE_API_KEY environment variable, when set, takes priority over ~/.syllable/config.yaml — the CLI runs with no syllable setup at all (CI pipelines, scheduled routines, scripts). For interactive use keep using syllable setup; never echo, log, or hardcode a key when wiring the env var (inject it from a secret store).
Dual Input Pattern
Most create commands support two modes:
- File mode:
--file path/to/body.json— reads a full JSON body from disk - Inline flags: Individual flags like
--name,--type, etc. — builds a minimal body with default empty maps/arrays for nested fields - Stdin:
--file -— reads JSON from stdin (useful for piping)
Update commands require --file (no inline flags).
API Patterns
- Endpoints:
/api/v1/{resource}/?page=...&limit=... - Search:
&search_fields=<field>&search_field_values=<value> - Date filters:
&start_datetime=ISO8601&end_datetime=ISO8601 - Default page size: 25 items
- Table fallback: If table format parsing fails, falls back to JSON output
Update Commands Are Full Replacements (PUT, Not PATCH)
All update commands send a full PUT request — the server replaces the entire resource. Any field omitted from the update body will be set to null or its default. This means:
- Always start your update body from the full resource JSON (use
get <id> -o jsonfirst) - Include all required fields — especially large text fields like
contexton prompts, which have NOT NULL constraints and will cause a 500 error if omitted - The pattern is: get → edit → put, not just patch the fields you want to change
Positional ID is enforced (v1.7+). On the body-routed update commands (agents, prompts, custom-messages, language-groups update by id; users by email; tools by name), the positional argument is now injected into the body when missing, and a body carrying a different identifier is a hard error before any request is sent (positional argument "574" conflicts with id=575 in the request body). Pre-1.7, the positional was silently ignored and the body's id decided what got updated — make the two match.
Example for prompts:
# Get the current state first
syllable --env staging prompts get 950 -o json > prompt-update.json
# Edit the file (change tools, llm_config, etc.)
# Then update with the full body
syllable --env staging prompts update 950 --file prompt-update.json
Workflow Tips
- Use
--output jsonto get raw API responses for scripting or piping tojq - Use
--dry-runto preview what API request would be sent before executing - Use
--debugto inspect HTTP request/response details when troubleshooting - Create/update commands read a JSON body from
--file path/to/body.jsonor--file -for stdin - List commands default to 25 results per page; use
--limitand--pageto paginate - Bulk analysis with JSON list output:
prompts list -o jsonreturns full prompt text (contextfield),agent_count,llm_config,tools, and all metadata for every prompt in a single call. This is far more efficient than callingprompts geton each prompt individually. The same applies to other resources —agents list -o json,tools list -o json, etc. all return complete objects. Use--limit 100(or higher) to fetch all resources in one request for audits, bulk analysis, or scripting. - Source and releases: https://github.com/asksyllable/syllable-cli
References
Detailed reference files (loaded on demand, not every session):
references/gotchas.md— CLI/API gotchas: payload formats, validation rules, shell pitfalls, creation ordering, LLM configreferences/common-patterns.md— CLI recipes: data source wiring, cross-org cloning, tool reuse, variable config, batch testingreferences/payload-examples.md— JSON templates for tool, prompt, agent, and data source payloadsreferences/telephony-and-channels.md— Telephony config fields, channel service enums, target modes, email/Twilio config, ReDi bridge phrases, campaign voicemail detectionreferences/variables-and-messages.md— Variable syntax (3 formats with missing-value behaviors), system variables, message time-based rules, day-of-week enumsreferences/sessions-and-debugging.md— Session fields, transcript structure, tool actions, latency analysis, session-debug commands, Console URL patternsreferences/insights.md— Insights system: folders, tool definitions, tool configs, workflows (lifecycle, conditions, activation), outputsreferences/outbound-campaigns.md— Campaign lifecycle, batch statuses, request statuses, results correlation, variable scoping