A fast, single-binary command-line client for new-api gateways. Ships as the
newapibinary.
Features • Install • Quick start • Commands • Scripting
$ newapi chat "explain Server-Sent Events in one paragraph"
Server-Sent Events (SSE) is a unidirectional streaming protocol over HTTP
where the server pushes UTF-8 text events to the client as soon as they
are ready...
(prompt=12, completion=87, total=99)Manage your gateway account, run AI inference, and pipe everything into shell scripts — without a browser, without parsing prose.
- Full new-api coverage — chat, messages, images, embeddings, models, tokens, usage, top-ups, invites, check-in, groups
- Streaming-first — incremental SSE for OpenAI and Anthropic protocols;
--no-streamfor scripting - Interactive REPL —
newapi chat -ifor a session with history and multi-line input - Multiple profiles — switch between dev/staging/prod gateways with
--profileornewapi config use - Secrets in your keychain — OS keychain by default, 0600 file fallback for headless boxes
- Pipe-friendly —
--jsonemits one JSON value; exit codes2/3/4/5/6/7for shell branching - Dynamic shell completion — bash, zsh, fish, PowerShell; tab-completes live profile/token/group/model names
brew install Xbang0222/newapi/newapiPick your platform from the releases page — darwin/linux/windows × amd64/arm64.
go install github.com/Xbang0222/new-api-cli/cmd/newapi@latestNote
Requires Go 1.25.10 or newer.
# 1. Authenticate
newapi login --endpoint https://your-newapi.example.com
# 2. Confirm the session
newapi whoami
# 3. One-shot chat
newapi chat "summarize the SOLID principles"
# 4. Pipe stdin as the prompt
git diff | newapi chat -m claude-sonnet-4-6 -s "review this diff"
# 5. Interactive session
newapi chat -i -m gpt-4o-mini
# 6. Inspect your spend
newapi usage --from 2026-05-01 --group --top 5newapi keeps a small YAML config at ~/.config/newapi/config.yaml (XDG-compliant; override with NEWAPI_CONFIG_HOME). Secrets are stored separately in the OS keychain — the config only holds references to them.
A profile is an endpoint + default model + credential pair:
newapi config create work --endpoint https://api.work.example.com --model gpt-4o-mini
newapi config list
newapi config use work
newapi --profile work chat "hi" # per-invocation override
newapi config delete work| Variable | Purpose |
|---|---|
NEWAPI_ENDPOINT |
Override the gateway URL |
NEWAPI_ACCESS_TOKEN |
Account-level token (used by /api/*) |
NEWAPI_API_KEY |
sk-xxx inference key (used by /v1/*) |
NEWAPI_PROFILE |
Override the active profile |
NEWAPI_CONFIG_HOME |
Override the config directory |
XDG_CONFIG_HOME |
Standard XDG override — newapi looks under $XDG_CONFIG_HOME/newapi |
NO_COLOR / FORCE_COLOR |
Disable / force ANSI colors |
Tip
Environment variables win over profile fields — drop a .envrc next to a repo and your CI scripts never need to touch the YAML config.
| Group | Commands |
|---|---|
| AI calls | chat, messages, images, embed, models |
| Auth | login, logout, whoami |
| Tokens | token list, token show, token create, token update, token enable, token disable, token delete, token use |
| Billing | usage, usage stat, topup list, invites, checkin, checkin status |
| Groups | group list, group models |
| Profiles | config list, config show, config use, config set, config create, config delete |
| Utilities | version, completion |
Run newapi <command> --help for full flag listing on any subcommand.
| Flag | Meaning |
|---|---|
--profile <name> |
switch profile for this invocation |
--endpoint <url> |
override the endpoint URL |
--config <path> |
override the config file path |
--json |
emit a single JSON value to stdout |
--plain |
disable colors, borders, and spinners |
--no-input |
never prompt; required flags must be passed explicitly |
--no-stream |
disable streaming for chat / messages |
--verbose / -v |
log request details to stderr |
--version / -V |
print version and exit |
chat/messages:-m/--model,-s/--system,-i/--interactiveimages:-m/--model,-n/--num,-o/--outputembed:-m/--model
newapi is designed so AI agents and shell pipelines can compose it without parsing human prose. Five contracts make this work:
--jsonreturns a single JSON value to stdout — never NDJSON, never with banners. Streaming commands buffer when--jsonis set.--no-inputdisables every interactive prompt. Required arguments missing → non-zero exit, never a hung pipeline.- Exit codes are part of the contract (table below).
2= bad input,3= bad token,5= rate limit,6= upstream,7= network. - Upstream error messages pass through verbatim so failures are debuggable from logs alone.
NO_COLOR=1,--plain, and piped stdout all drop ANSI —newapi cmd | grep ...works without flags.
MODEL=$(newapi --json group models default \
| jq -r '[.[] | select(.model_price > 0)] | min_by(.model_price) | .model_name')
newapi --no-input --no-stream chat -m "$MODEL" "summarize this README" < README.mdID=$(newapi --json token list --search agent | jq -r '.[0].id // empty')
if [ -z "$ID" ]; then
ID=$(newapi --json --no-input token create agent --groups default --models "" \
| jq -r .id)
fi
newapi token use "$ID"out=$(newapi --json --no-input chat -m gpt-4o-mini "hi" 2>&1) || rc=$?
case "${rc:-0}" in
0) echo "ok: $out" ;;
3) echo "auth failed — re-run newapi login" ;;
5) echo "rate limited — back off" ;;
6|7) echo "gateway problem — retry later" ;;
*) echo "unexpected: $out" ;;
esacnewapi --help # top-level commands
newapi <command> --help # flags + examples for any subcommand
newapi --json group list # available groups
newapi --json group models default # available models with pricing
newapi --json token list # current tokensEvery read-only /api/* command supports --json. Mutating commands return the post-mutation state when --json is set, so you can pipe create | jq .id straight into use $ID.
newapi completion zsh > "${fpath[1]}/_newapi"
newapi completion bash > /usr/local/etc/bash_completion.d/newapi
newapi completion fish > ~/.config/fish/completions/newapi.fish
newapi completion powershell | Out-String | Invoke-ExpressionCompletion goes beyond static flag names — newapi ships dynamic completion for:
--profile <Tab>and everyconfig use|delete|show|setarg → readsconfig.yamltoken show|delete|enable|disable|update|use <Tab>→ live token IDs (with names)--groups <Tab>(ontoken create/token update) → live groups--model <Tab>(onchat,messages,images,embed,usage) → live model namesgroup models <Tab>→ live groups
Note
Network-backed completions silently no-op if auth is missing, so an unconfigured shell never hangs on Tab.
| Code | Meaning |
|---|---|
0 |
success |
1 |
generic / unexpected error |
2 |
bad request (HTTP 400, or business-logic {success:false} with no auth/rate-limit hint) |
3 |
unauthorized (HTTP 401, or HTTP 200 with auth-keyword message) |
4 |
forbidden (HTTP 403) |
5 |
rate limited (HTTP 429) |
6 |
upstream server error (HTTP 5xx) |
7 |
network error (timeout, DNS, reset) |
Important
new-api occasionally returns HTTP 200 with {success:false} for business errors (invalid token, expired session, …). newapi keyword-matches the server message to choose 2/3/5 so scripts can still branch on $?.
make build # compile ./newapi with embedded version
make install # go install into $GOBIN
make test # go test -race -count=1 ./...
make lint # go vet + gofmt -l
make clean # rm binary + dist/Or iterate without building:
go run ./cmd/newapi <subcommand> [flags]Note
Architecture details, dual-track auth notes, and DTO traps live in CLAUDE.md.