Command-line interface for the Realtime API.
Important
This CLI is not yet ready for production use. To complete setup please follow the steps outlined in your workspace. Delete this section before > publishing to a package manager.
Realtime: Realtime gateway API service
curl -fsSL https://raw.githubusercontent.com/voiceflow/cli/main/scripts/install.sh | bashiwr -useb https://raw.githubusercontent.com/voiceflow/cli/main/scripts/install.ps1 | iexAlternatively, install directly via Go:
go install github.com/voiceflow/cli/cmd/vf@latestDownload pre-built binaries for your platform from the releases page.
Shell completions are available for Bash, Zsh, Fish, and PowerShell.
# Add to ~/.bashrc:
source <(vf completion bash)
# Or install permanently:
vf completion bash > /etc/bash_completion.d/vf# Add to ~/.zshrc:
source <(vf completion zsh)
# Or install permanently:
vf completion zsh > "${fpath[1]}/_vf"vf completion fish | source
# Or install permanently:
vf completion fish > ~/.config/fish/completions/vf.fishvf completion powershell | Out-String | Invoke-Expressionvf workspace list --token 'Bearer test_token'
Authentication credentials can be configured in four ways (in order of priority):
Pass credentials directly as flags to any command:
vf --token <value> <command> [arguments]Set credentials via environment variables:
| Variable | Description |
|---|---|
VF_TOKEN |
Voiceflow bearer token |
Credentials are stored securely in your operating system's keychain when you run:
vf configureSecret credentials (tokens, API keys, passwords) are automatically stored in:
- macOS: Keychain
- Linux: GNOME Keyring / KWallet (via D-Bus Secret Service)
- Windows: Windows Credential Locker
If no keychain is available (e.g., in CI environments), credentials fall back to the config file.
Run the interactive configure command to store non-secret settings:
vf configureConfiguration is stored in ~/.config/vf/config.yaml.
Available commands
list- List workspacescreate- Create workspaceget- Get workspaceupdate- Update workspacedelete- Delete workspace
list- List projectscreate- Create projectget- Get projectupdate- Update projectdelete- Delete project
list- List environmentsmerge- Merge environmentsupdate-traffic-split- Update traffic splitget- Get environmentupdate- Update environmentdelete- Delete environmentcompile- Compile environmentclone- Clone environmentpublish- Publish environment
list- List variablescreate- Create variableget- Get variableupdate- Update variabledelete- Delete variable
list- List playbookscreate- Create playbookget- Get playbookupdate- Update playbookdelete- Delete playbook
list- List API toolscreate- Create API toolget- Get API toolupdate- Update API tooldelete- Delete API tool
list- List variablescreate- Create variableget- Get variableupdate- Update variabledelete- Delete variable
list- List propertiescreate- Create propertyget- Get propertyupdate- Update propertydelete- Delete propertyset-value- Set property value
list- List functionscreate- Create functionget- Get functionupdate- Update functiondelete- Delete function
list- List variablescreate- Create variableget- Get variableupdate- Update variabledelete- Delete variable
list- List evaluationscreate- Create evaluationget- Get evaluationupdate- Update evaluationdelete- Delete evaluationrun- Run evaluation
list- List documentscreate-url- Create URL documentcreate-text- Create text documentcreate-table- Create table documentget- Get documentupdate- Update documentdelete- Delete document
list- List MCP serverscreate- Create MCP serverget- Get MCP serverupdate- Update MCP serverdelete- Delete MCP serversync- Sync MCP server
query- Query knowledge base
send- Send
get- Get stateupdate- Update statedelete- Delete stateupdate-variables- Update variables
call-count- Query call countcall-duration- Query call durationworkspace-transcript-count- Query workspace transcript countproject-transcript-count- Query project transcript countproject-transcript-cost- Query transcript costworkspace-interaction-count- Query workspace interaction countproject-interaction-count- Query project interaction countorganization-token-usage- Query organization token usageworkspace-token-usage- Query workspace token usageproject-token-usage- Query project token usagehourly-organization-token-usage- Query hourly organization token usagehourly-project-token-usage- Query hourly project token usagedaily-token-usage- Query daily token usageentity-token-usage- Query entity token usagecategory-token-usage- Query category token usageplaybook-usage- Query playbook usageworkflow-usage- Query workflow usageprompt-usage- Query prompt usageintent-usage- Query intent usagefunction-usage- Query function usageapi-tool-usage- Query API tool usagemcp-tool-usage- Query MCP tool usageknowledge-base-document-usage- Query knowledge base document usageintegration-usage- Query integration usageunique-user-count- Query unique user count
Operations that accept a request body support three input methods, with a clear priority chain:
vf <command> --name "Jane" --age 30Provide the entire request body as a JSON string:
vf <command> --body '{"name": "John", "age": 30}'Individual flags override --body values:
# Result: {name: "Jane", age: 30}
vf <command> --body '{"name": "John", "age": 30}' --name "Jane"Pipe JSON into any command that accepts a request body:
echo '{"name": "John", "age": 30}' | vf <command>Individual flags override stdin values:
# Result: {name: "Jane", age: 30}
echo '{"name": "John", "age": 30}' | vf <command> --name "Jane"This is useful for chaining commands, reading from files, or scripting:
# Read body from a file
vf <command> < request.json
# Pipe from another command
curl -s https://example.com/data.json | vf <command>When multiple input methods are used, the priority is:
| Priority | Source | Description |
|---|---|---|
| 1 (highest) | Individual flags | --name "Jane" always wins |
| 2 | --body flag |
Whole-body JSON via flag |
| 3 (lowest) | Stdin | Piped JSON input |
Use --server-url to override the server URL entirely, bypassing any named or indexed server selection:
vf --server-url https://custom-api.example.com <command> [arguments]Precedence: --server-url > --server > default
Every command supports a --output-format flag that controls how the response is rendered to stdout.
| Format | Flag | Description |
|---|---|---|
| Pretty | --output-format pretty (default) |
Aligned key-value pairs with color, nested indentation. Human-readable at a glance. |
| JSON | --output-format json |
JSON output. Passthrough when the response is already JSON (preserves original field order and numeric precision). Falls back to typed marshaling otherwise. |
| YAML | --output-format yaml |
YAML output via standard marshaling. |
| Table | --output-format table |
Tabular output for array responses. |
| TOON | --output-format toon |
Token-Oriented Object Notation — a compact, line-oriented format that typically uses 30–60% fewer tokens than JSON. Well-suited for piping responses into LLM prompts. |
# Default pretty output
vf <command>
# Machine-readable JSON
vf <command> --output-format json
# TOON for LLM-friendly compact output
vf <command> --output-format toon
# Pipe JSON to jq without using --output-format
vf <command> --output-format json | jq '.fieldName'Use --jq to filter or transform the response inline using a jq expression. This always outputs JSON and overrides --output-format:
# Extract a single field
vf <command> --jq '.name'
# Filter an array
vf <command> --jq '.items[] | select(.active == true)'Use --color to control terminal colors:
| Value | Behavior |
|---|---|
auto (default) |
Color when stdout is a TTY, plain text otherwise |
always |
Always colorize |
never |
Never colorize |
The NO_COLOR and FORCE_COLOR environment variables are also respected.
When using --all (pagination) or streaming operations, output is written incrementally as items arrive:
| Format | Streaming behavior |
|---|---|
json |
One compact JSON object per line (NDJSON) |
yaml |
YAML documents separated by --- |
toon |
One TOON-encoded object per block, separated by blank lines |
pretty (default) |
Pretty-printed items separated by blank lines |
The CLI uses standard exit codes to indicate success or failure:
| Exit Code | Meaning |
|---|---|
0 |
Success |
1 |
Error (API error, invalid input, etc.) |
On success, the response data is printed to stdout as JSON. On failure, error details are printed to stderr.
# Capture output and handle errors
vf ... > output.json 2> error.log
if [ $? -ne 0 ]; then
echo "Error occurred, see error.log"
fiThe CLI includes two diagnostic flags available on all commands:
Preview what would be sent without making any network calls:
vf <command> --dry-runOutput goes to stderr and includes:
- HTTP method and URL
- Request headers (sensitive values redacted)
- Request body preview (sensitive fields redacted)
The command exits successfully without contacting the API. This is useful for verifying request construction before executing.
Log request and response diagnostics while running normally:
vf <command> --debugDebug output goes to stderr and includes:
- Request method, URL, headers, and body preview
- Response status, headers, and body preview
- Transport errors (if any)
The command still executes normally and produces its regular output on stdout.
If both --dry-run and --debug are set, --dry-run takes precedence and no network calls are made.
Sensitive information is automatically redacted in diagnostic output:
- Headers:
Authorization,Cookie,Set-Cookie,X-API-Key, and other security headers show[REDACTED] - Body: JSON fields named
password,secret,token,api_key,client_secret, etc. show[REDACTED]
Diagnostic output should still be treated as potentially sensitive operational data.
This CLI is in beta, and there may be breaking changes between versions without a major version update. Therefore, we recommend pinning usage to a specific package version. This way, you can install the same version each time without breaking changes unless you are intentionally looking for the latest version.
While we value open-source contributions to this CLI, this library is generated programmatically. Any manual changes added to internal files will be overwritten on the next generation. We look forward to hearing your feedback. Feel free to open a PR or an issue with a proof of concept and we'll do our best to include it in a future release.