SuperAPI AI Directory

cliproxy-newapi-stack

Coding & development

View repository

Updated 10-15 17:32

About this skill

CLIProxyAPI + NewAPI Metering Stack

In front of the user's existing and already verified CLIProxyAPI upstream, add a NewAPI (calciumion/new-api) billing, rate limiting, and multi-user token layer. This Skill does not install a bare CLIProxyAPI, nor does it call other deployment Skills to fill in this prerequisite.

All "completion" conclusions must be based onthis session'scommand output (W-16). After price and quota changes, you must actually send a request and check logs.quota matches this request's token count and the target price.

Operating Contract

  • Direct actions: read-only checks, configuration backups, and local dry-runs can be executed directly.
  • Escalate before: installing containers, modifying an existing upstream, restarting services, changing firewalls, or writing production quotas requires explicit authorization for this task.
  • Evidence-backed pushback: read secrets only from environment variables or a password manager; when asked to write them in plaintext to disk or expose raw ports to the public internet, show the specific risks and switch to a tunnel/TLS.
  • Feedback loop: after every change, rerun upstream, NewAPI, and precise billing verification; if any step cannot obtain the real state, stop and report, and do not fake success with default values.

0. Prerequisite confirmation (must ask)

  • SSH target:root@HOST whether passwordless
  • Port allocation:CLIPROXY_PORT(default 8317)、NEWAPI_PORT(default 8200)
  • upstream evidence: CLIProxyAPI is already running on the target host, and the current session can verify health, model list, and authentication through a user-approved SSH tunnel or loopback request; if the evidence is insufficient, stop, do not guess, and do not automatically install a bare upstream
  • Login account provider:codex / claude / qwen / iflow / gemini
  • Price input format: for each virtual model, give me three USD per 1M numbers for input / cached / output
  • Client machines: on which machines to place the BASE_URL environment variable

Secure default: local OAuth + scp sync; NewAPI binds only to the VPS loopback, and first registration is completed through an SSH tunnel. Public access must go through a reverse proxy configured with TLS, and the raw NewAPI HTTP port must not be exposed directly.


Phase 1 — Verify the existing CLIProxyAPI upstream

First record the existing service's process, listening address, health response, model list, and configuration backup location. If any item cannot be verified, stop. Only when the user approves modifying this existing upstream in the current message should you apply the following two patches:

  1. Add stability switchto /root/CLIProxyAPI/config.yaml:

    disable-cooling: true
    

    See references/troubleshooting.md "CLIProxyAPI cooldown principle". If this change is missed, 30 concurrent 5KB payloads will produce a mix of ~50% 503s.

  2. Do not expose the CLIProxyAPI port to the public internet(different from a bare deployment):

    • First use ip -4 addr show docker0 to confirm the Docker bridge address, then bind host to that address (common value is 172.17.0.1)
    • Delete the existing public ufw allow <CLIPROXY_PORT>/tcp; management access should uniformly go through an SSH tunnel, and do not keep a public admin backdoor

Phase 2 — Deploy the NewAPI container

IMAGE='calciumion/new-api@sha256:<VERIFIED_DIGEST>' \
SSH_TARGET=root@<HOST> SSH_KEY=~/.ssh/id_ed25519 PORT=8200 \
  scripts/deploy_newapi.sh

The script binds only to the remote 127.0.0.1:8200. Before first registration, keep the firewall closed for that port and establish an SSH tunnel:

ssh -N -L 8200:127.0.0.1:8200 -i <KEY> <SSH_TARGET>

Access only local http://127.0.0.1:8200 Complete root account registration, and save the password to a password manager. After registration and login verification succeed, then configure the Caddy/Nginx reverse proxy with TLS; first verify HTTPS, authentication, and origin restrictions, then open as needed 443/tcp. It is forbidden to open <NEWAPI_PORT>。


Phase 3 — Channels + Token

3a. Create a channel (CLIProxyAPI as upstream)

NewAPI backend → "Channels" → New → OpenAI type:

  • base_url:http://172.17.0.1:<CLIPROXY_PORT> ⚠️ Cannot write 127.0.0.1 — the 127.0.0.1 inside the container is the container itself. See references/troubleshooting.md "Container networking quick notes".
  • Key: CLIProxyAPI's cpa_xxx key
  • Models: fill in the virtual model names exposed by CLIProxyAPI, comma-separated, for example: gpt-5.4,gpt-5.3-codex,gpt-5.3-codex-spark,gpt-5.4-mini,gpt-5.2
  • The test button should return 200 OK; if it fails, first check references/troubleshooting.md。

3b. Create a Token (for clients)

NewAPI backend → "Tokens" → New:

  • Name:client-default and similar identifiers
  • QuotaFirst put unlimited or a large number (actual billing is controlled by user.quota)
  • Available models: check the models you have opened to the client
  • Copy the generated sk-xxx(this is the client's BASE_API_KEY)

Phase 4 — Write prices + top up quota

4a. Write prices

Use scripts/set_pricing.py(automatically calculates the three multipliers based on measured USD/1M):

SSH_TARGET=root@<HOST> SSH_KEY=~/.ssh/id_ed25519 \
  scripts/set_pricing.py \
    --model gpt-5.4       --input 2.5  --cached 0.25  --output 15 \
    --model gpt-5.3-codex --input 1.75 --cached 0.175 --output 14

The script will: merge and write into the options table's ModelRatio / CacheRatio / CompletionRatio, and restart the container.

⚠️ For multiplier semantics see references/newapi-pricing.md —— CacheRatio / CompletionRatio isa multiple relative to the input price, not an absolute unit price.ModelRatio In different forks it may be divided by 2; the first time you configure it, be sure to send a request and check whether the actual value of logs.quota matches expectations.

4b. Top up quota

NewAPI online top-up is usually not configured. When you need to urgently correct quota, you can use the parameterized SQLite helper:

SSH_TARGET=root@<HOST> SSH_KEY=~/.ssh/id_ed25519 \
  scripts/topup.sh <user_id> <quota>
# 例:1 1000000000  → 1B quota ≈ USD 2000 (默认 QuotaPerUnit=500000)

4c. Configure online top-up (optional)

If you want to let users top up by themselves, NewAPI backend → System → Payment:

  • Stripe / EasyPay / Custom → fill in TopUpLink and other fields
  • When online top-up is not configured, administrators can use the verified scripts/topup.sh; the input must be an integer, and the script will parameterize the SQL and verify that exactly one row is updated

Phase 5 — Client environment variables

Write only non-sensitive configuration into the client shell config:

export BASE_URL="https://<NEWAPI_DOMAIN>/v1"
export BASE_MODEL="<虚拟模型名>"       # 如 gpt-5.4

The API key must be stored in Keychain or another password manager, and read before the current process starts; it is forbidden to write it into ~/.zshrc, chats, scripts, or command-line arguments. For example, on macOS you can use:

export BASE_API_KEY="$(security find-generic-password -s newapi-client -a client-default -w)"

When syncing across multiple machines (W-14 file ownership): manually SSH into each machine one by one and edit its own rc file, to avoid parallel writes overwriting each other.


Phase 6 — Add a new account (OpenAI/Anthropic/etc)

No need to restart the service; CLIProxyAPI has a file watcher.

Simplest:

PROVIDER=codex \
  SSH_TARGET=root@<HOST> SSH_KEY=~/.ssh/id_ed25519 \
  CLIPROXY_LOCAL=<本地 CLIProxyAPI 仓库路径> \
  scripts/add_codex_account.sh

Script flow:

  1. Start locally go run ./cmd/server -<provider>-login -config config.yaml
  2. browserwith the new accountlog in (first log out of the old account in the browser or use an incognito window — otherwise it will reuse the old session and overwrite the old credentials back)
  3. Automatically diff ~/.cli-proxy-api/<provider>-*.json, and copy the new file scp to the VPS
  4. tail the VPS logs to confirm auth file changed (CREATE)

See references/multi-account.md(including subscription conditions, polling semantics, account deletion, verification methods).


Verification (must run after Phase 4/5/6)

SSH_TARGET=root@<HOST> SSH_KEY=~/.ssh/id_ed25519 \
  CLIPROXY_URL=http://127.0.0.1:<TUNNELED_CLIPROXY_PORT> \
  NEWAPI_URL=https://<NEWAPI_DOMAIN> \
  CLIPROXY_KEY="$(security find-generic-password -s cliproxy-admin -w)" \
  NEWAPI_TOKEN="$(security find-generic-password -s newapi-client -a client-default -w)" \
  MODEL=<虚拟模型> INPUT_USD_PER_M=<输入价> OUTPUT_USD_PER_M=<输出价> \
  QUOTA_PER_UNIT=500000 \
  scripts/verify_stack.sh

Pass criteria:

  • Direct CLIProxyAPI HTTP 200
  • Via NewAPI HTTP 200
  • logs corresponding request_id, model and token count match this request
  • Actual quota error from the target input/output price calculation result does not exceed 5% (and at least 1 quota of integer rounding is allowed)

If any is not satisfied, you must not claim "deployment complete".


Resource Index

File Purpose
scripts/deploy_newapi.sh NewAPI container one-click deployment + health self-check
scripts/set_pricing.py Automatically write NewAPI ratios using the three USD/1M parameters
scripts/topup.sh Directly modify via SQLite users.quota
scripts/verify_stack.sh Dual-path + billing log verification
scripts/add_codex_account.sh OAuth login + credential sync + watcher validation
agents/openai.yaml Agent configuration for when independent review of high-risk deployment or billing schemes is needed
references/newapi-pricing.md ModelRatio / CacheRatio / CompletionRatio / QuotaPerUnit full semantics + calculation examples
references/troubleshooting.md Pitfall table for container networking, cooldown, PUT not taking effect, UFW, etc.
references/multi-account.md Multi-account polling semantics + adding / deleting accounts / subscription conditions

Things not to do

  • ❌ Write NewAPI channel base_url as http://127.0.0.1:<port>(self-reference inside the container)
  • ❌ Treat CacheRatio as an absolute unit price (it is actually a multiplier relative to input)
  • ❌ Prices only go through /api/option/ PUT without verification (this interface is known to possibly fail silently)
  • ❌ Tinkering with remote OAuth tunnels (5-minute window + tunnel coordination, pitfalls already encountered, uniformly use local login + scp)
  • ❌ Share CLIProxyAPI public port's cpa_ key and NewAPI's sk- token with the same type of client
  • ❌ Claim "price is in effect" across sessions—you must send a request in this session + check logs.quota
  • ❌ Without disable-cooling: true perform high-concurrency stress testing