The official interactive REPL for the VoiceTel REST API — provision numbers, place orders, validate e911, send messages, and manage your account, all from a single keystroke-friendly prompt on top of the VoiceTel Go SDK.
- Features
- Installation
- Quickstart
- One-shot mode (
-x) - Authentication
- Configuration
- Environment variables
- Building from source
- Command Reference
- Examples
- API Documentation
- Contributors
- Sponsors
- License
- Interactive prompt — drops you straight into a
voicetel>shell. No subcommands to memorise, no flag-soup one-liners. - Line editing powered by
github.com/chzyer/readline— Emacs-style movement, reverse-i-search, the works. - Persistent history at
~/.voicetel/historyso you can↑back into yesterday's session. - Tab autocomplete across the entire command tree — top-level resources, sub-commands, and known argument shapes.
- Pretty-printed JSON by default. Errors print in red when you're on a TTY; plain otherwise (so logs stay clean).
- Sits on top of the official
voicetel/go-sdk— every command is a one-line wrapper around a typed SDK method, so the CLI inherits the SDK's retry/backoff, structured errors, and rate-limit handling. - Persistent config at
~/.voicetel/config.toml— log in once, stay logged in. Passwords are never persisted; only the API key is. - Sends
voicetel-cli/<version>as the user-agent so requests are attributable in your logs.
- Numbers — list, get, add, remove, route, translate, CNAM, LIDB, fax, forward, SMS, messaging campaigns, port-out PIN, account moves.
- Account — profile, sub-accounts, CDRs, credits, payments, MRC, registration, password recovery.
- e911 — record provisioning, address validation, lookup, removal.
- Gateways — list, create, update, delete, view bound numbers.
- Messaging — SMS & MMS sending, message history, 10DLC brand and campaign registration, per-number messaging state.
- Lookups — CNAM and LRN dips.
- iNumbering — inventory search, coverage queries, number orders, port-in submissions, port-out availability.
- Support — ticket create / read / update / delete, threaded messages, replies.
- ACL — IP allowlist management.
- Authentication — switch between Digest, IP-only, or hybrid modes; rotate passwords.
- One binary, no runtime dependencies. Distributed via
go installand pre-built releases.
go install github.com/voicetel/cli@latestRequires Go 1.22 or later. The binary lands at $GOBIN/voicetel-cli (or $GOPATH/bin/voicetel-cli).
Grab a release from GitHub Releases — macOS (amd64/arm64), Linux (amd64/arm64/386/arm), Windows (amd64/arm64), and FreeBSD (amd64) are all built per release.
# Linux amd64 example — adjust the archive name for your platform.
curl -sL https://github.com/voicetel/cli/releases/latest/download/voicetel-cli_0.2.0_linux-amd64.tar.gz | tar xz
sudo mv voicetel-cli_0.2.0_linux-amd64/voicetel-cli /usr/local/bin/git clone https://github.com/voicetel/cli && cd cli
make build # → bin/voicetel-cli (local platform)
make install # → $GOPATH/bin/voicetel-cliSee Building from source for the full make-target list (including make release for the per-platform archives).
$ voicetel-cli
VoiceTel CLI 0.2.0 — type `help` for commands, `exit` to quit.
Endpoint: https://api.voicetel.com
No API key configured. Run `login <username> <password>` or `set api-key <key>`.
voicetel> login 1000000001 hunter2
Logged in. API key installed and saved.
voicetel> account get
{
"username": "1000000001",
"name": "Acme Co",
"email": "ops@acme.example",
"cash": 142.18,
"callerId": "2015551234",
"timezone": "America/Chicago"
}
voicetel> numbers list
{
"numbers": [
{"number": "2015551234", "route": 4, "cnam": true, "smsEnabled": true},
{"number": "2015555678", "route": 4, "cnam": false, "smsEnabled": false}
]
}
voicetel> exit
Run a single command non-interactively and exit. Useful for shell pipelines, cron jobs, and ad-hoc scripting — no REPL, no banner, no history file touched.
# Authenticate via env vars, then list numbers, then exit.
export VOICETEL_USERNAME=1000000001
export VOICETEL_PASSWORD=hunter2
voicetel-cli -x 'account numbers'
# Or use a pre-fetched API key directly:
export VOICETEL_API_KEY=abcdef0123456789abcdef0123456789
voicetel-cli -x 'numbers list'
# Pipe the JSON output into jq:
voicetel-cli -x 'account get' | jq .cashThe command string after -x is parsed the same way as a REPL line — group + subcommand + arguments (e.g. acl add 203.0.113.0/24, messaging campaigns list, lookups cnam 2155551234). Exit code is 0 on success, 1 on any error (including auth failures and rate-limit hits).
In one-shot mode, Ctrl-C cancels the in-flight request (the REPL leaves Ctrl-C to readline; one-shot mode handles it directly).
Two ways to install an API key:
-
login <username> <password>— exchanges credentials for a fresh 32-hex bearer token viaPOST /v2.2/account/api-key. The token is persisted to~/.voicetel/config.toml; the password never is.This endpoint shares the 6 req/hr/IP rate limit with the rest of
/account/*. -
set api-key <key>— installs an existing key directly. Useful if you've fetched one out of band.
voicetel> login 1000000001 hunter2
Logged in. API key installed and saved.
voicetel> whoami
{
"apiKey": "abcd...4321",
"baseURL": "https://api.voicetel.com",
"rateLimits": "account/cdr, account/mrc, account/payments, account/registration, account/api-key (login): 6 req/hr/IP"
}
Don't have credentials yet? Get them at voicetel.com/docs/api/v2.2/credentials.
The CLI reads its persistent config from ~/.voicetel/config.toml. A typical file looks like:
api_key = "abcdef0123456789abcdef0123456789"
base_url = "https://api.voicetel.com"api_key— the 32-hex bearer token. Written onloginandset api-key.base_url— override the API endpoint (mostly for staging/sandbox builds). Defaults tohttps://api.voicetel.com.
The file is written atomically (temp sibling + fsync + rename) and chmodded to 0600.
You can override either value on launch:
voicetel-cli --api-key=abcdef0123456789abcdef0123456789
voicetel-cli --base-url=https://staging.voicetel.comCommand-line flags do not persist; they win for the duration of the session only.
History lives at ~/.voicetel/history (also chmodded to 0600 by readline).
The CLI honors four environment variables. Precedence is flag > env > config.
| Variable | Purpose |
|---|---|
VOICETEL_API_KEY |
32-hex bearer token — installed directly on the client; no login round-trip. |
VOICETEL_USERNAME |
Numeric account id. Paired with VOICETEL_PASSWORD, triggers a login at startup. |
VOICETEL_PASSWORD |
Password — paired with VOICETEL_USERNAME; never persisted to config.toml. |
VOICETEL_BASE_URL |
Override the API endpoint (rare — staging / sandbox builds). |
# Headless CI script: use env vars, run a single command, exit.
export VOICETEL_USERNAME=1000000001
export VOICETEL_PASSWORD=$(vault read -field=password secret/voicetel)
voicetel-cli -x 'account info'When VOICETEL_USERNAME and VOICETEL_PASSWORD are both set and no API key is available, the CLI calls the login endpoint at startup. The exchanged key is installed on the client but not written to ~/.voicetel/config.toml (env-driven runs are intentionally ephemeral — they should not mutate user state).
The repo ships a Makefile that produces pure-Go binaries (CGO_ENABLED=0) for 9 platforms — no per-target C toolchains needed.
make build # local platform → ./bin/voicetel-cli
make build-all # all 9 platforms → ./dist/voicetel-cli_<version>_<os>-<arch>/voicetel-cli[.exe]
make release # build-all + per-platform .tar.gz / .zip archives in ./dist/
make test # go test ./...
make vet # go vet ./...
make install # CGO_ENABLED=0 go install . → $GOPATH/bin/voicetel-cli
make clean # rm -rf ./bin ./distSupported cross-compile targets:
- macOS:
darwin/amd64,darwin/arm64 - Linux:
linux/amd64,linux/arm64,linux/386,linux/arm - Windows:
windows/amd64,windows/arm64 - FreeBSD:
freebsd/amd64
To add or remove a target, edit the PLATFORMS variable at the top of the Makefile.
go test -bench=. -benchmem ./internal/repl/ ./internal/output/ exercises the parser, dispatcher tail-join, and JSON pretty-printer. Use as a baseline before perf-sensitive changes.
Hidden debug flags write runtime/pprof snapshots to disk for go tool pprof analysis:
voicetel-cli --cpu-profile=cpu.pprof --mem-profile=mem.pprof -x 'numbers list'
go tool pprof cpu.pprof
go tool pprof mem.pprofNo runtime overhead when the flags aren't set. CPU profile runs for the lifetime of the process; heap profile is captured at exit (after runtime.GC()).
help [topic] Show help for the REPL or a specific command/topic.
exit | quit Leave the REPL (Ctrl-D also works).
login <username> <password> Exchange creds for an API key (rate-limited 6/hr/IP).
set api-key <key> Install an existing 32-hex bearer.
set base-url <url> Override the API endpoint (rare; usually production).
whoami Show the current API key, base URL, and rate-limit caveats.
clear Clear the screen.
account get
account update <json> Body is parsed as JSON for the AccountPutRequest.
account add <json>
account signup <json>
account cdr [start] [end]
account credits
account recurring-charges (alias: account mrc)
account payments
account registration
account recover <json>
acl list
acl add <json>
acl remove <json>
authentication get
authentication update <json>
e911 list
e911 create <json>
e911 validate <json>
e911 get <dn>
e911 provision <dn> <json>
e911 remove <dn>
gateways list
gateways add <json>
gateways get <id>
gateways update <id> <json>
gateways remove <id>
gateways numbers <id>
inumbering search-inventory [--npa --nxx --state --rate-center --contains --ends-with --limit]
inumbering coverage [--state --rate-center]
inumbering order <json>
inumbering ports
inumbering port <id>
inumbering submit-port <json>
inumbering port-availability <number>
lookups cnam <number>
lookups lrn <number> <ani>
messaging history [--number --start --end --type]
messaging send <json>
messaging create-brand <json>
messaging campaign-status
messaging create-campaign <json>
messaging numbers-state [--numbers=2015551234,2015551235]
numbers list
numbers add <json>
numbers get <number>
numbers remove <number>
numbers move <number> <json>
numbers release <number>
numbers set-route <number> <json>
numbers set-translation <number> <json>
numbers set-cnam <number> <json>
numbers set-lidb <number> <json>
numbers get-fax <number>
numbers set-fax <number> <json>
numbers remove-fax <number>
numbers set-forward <number> <json>
numbers remove-forward <number>
numbers get-sms <number>
numbers set-sms <number> <json>
numbers remove-sms <number>
numbers get-messaging <number>
numbers patch-messaging <number> <json>
numbers assign-campaign <number> <json>
numbers unassign-campaign <number>
numbers bulk-unassign-campaign <2015551234,2015551235>
numbers set-port-out-pin <number> <json>
support list
support create <json>
support get <id>
support update <id> <json>
support delete <id>
support messages <id>
support reply <id> <json>
<json> is the rest of the line, parsed as a JSON object. Quote-aware tokenising means you can paste multi-word string values without escaping each one.
voicetel> inumbering search-inventory --npa=201 --state=NJ --limit=5
{
"numbers": [
{"number": "2015550100", "rateCenter": "Newark", "city": "Newark", "province": "NJ", "lata": "224"},
...
]
}
voicetel> inumbering order {"numbers":[{"Value":"2015550100"}]}
{
"orderId": "ord-9k2j",
"amountCharged": 1.00,
"numbersOrdered": ["2015550100"]
}
voicetel> numbers set-forward 2015550100 {"destination":2125550199}
{"number": "2015550100", "forwardTo": "2125550199"}
voicetel> messaging send {"fromNumber":"2015550100","toNumber":"2125550199","text":"hello from VoiceTel CLI"}
{
"id": "tx-abc123",
"type": "sms",
"fromNumber": "2015550100",
"toNumber": "2125550199",
"parts": 1
}
voicetel> account credits
{
"credits": [
{"date": "2026-05-15", "paid": true, "amount": 100.00},
{"date": "2026-04-15", "paid": true, "amount": 100.00}
]
}
- Reference docs: voicetel.com/docs/api/v2.2/
- Interactive playground: voicetel.com/docs/api/v2.2/playground/ — try the API in your browser without writing any code
- API credentials: voicetel.com/docs/api/v2.2/credentials/
- Go SDK: github.com/voicetel/go-sdk
- Michael Mavroudis — Lead Developer
Contributions welcome. Open an issue describing the change, or send a pull request against main.
| Sponsor | Contribution |
|---|---|
| VoiceTel Communications | Primary development and production hosting |
This project is licensed under the MIT License — see the LICENSE file for details.
