CPA proxy deployment guide: CLIProxyAPI + NewAPI account-pool gateway
A practical CPA proxy deployment guide for developers and site operators: CLIProxyAPI, NewAPI, account pools, deployment, client setup, security checks, and troubleshooting.
Short Version
When you build a CPA proxy, the hard part is usually not “which panel should I install?” The real problem is how to turn Codex, Claude Code, Gemini CLI, Grok Build, or an OpenAI-compatible upstream into a stable API that can be managed, routed, and handed to NewAPI, team users, or coding agents.
A common CPA proxy architecture looks like this:
This setup is most useful for developers, small teams, and site operators who want a controllable account-pool API gateway. You can use it privately, distribute it inside a team, test different upstreams, or study how proxy supply chains work. If you plan to expose it publicly, think through abuse control, credential isolation, access control, and policy boundaries before you put users on it.
What Is a CPA Proxy?
CPA is commonly used as shorthand for CLIProxyAPI. The project describes CLIProxyAPI as a proxy server that provides OpenAI-, Gemini-, Claude-, Codex-, and Grok-compatible API endpoints for CLI tools. It supports OAuth login, multi-account rotation, streaming responses, function calling, multimodal input, and OpenAI-compatible upstream providers.
In a CPA + NewAPI architecture, the roles are usually:
| Layer | Responsibility |
|---|---|
| Account layer | Codex, Claude Code, Gemini CLI, Grok Build, AI Studio, OpenAI-compatible upstreams |
| CPA layer | Turns accounts, OAuth sessions, or upstream keys into a unified API |
| NewAPI layer | Manages channels, users, tokens, quotas, model pricing, and the public endpoint |
| Client layer | Claude Code, Codex, Cursor, OpenCode, Cherry Studio, SDKs |
A complete CPA proxy usually has two layers. CPA answers “how do accounts become an API?” NewAPI answers “how do I distribute that API to users?” If you only need private use, start with CPA alone. If multiple people need access, add a distribution layer.
When to Use CPA + NewAPI
Do not make the system heavy on day one. CPA + NewAPI can solve team distribution, but it also adds configuration, security, and debugging cost.
| Goal | Suggested setup |
|---|---|
| Convert one account into an API for yourself | Deploy CPA only |
| Issue one unified key to a 2-10 person team | CPA + NewAPI, or CPA + a lightweight panel |
| Combine Codex, Claude Code, Gemini CLI, and other sources | CPA + NewAPI is a better fit |
| Run registration, top-ups, quotas, and pricing | A distribution layer such as NewAPI is usually required |
| Resell subscription-account capacity publicly | Avoid this until you understand platform terms, risk control, and credential isolation |
For a first deployment, build a local or private version that only you can access. Use one account, one model, and one client. After CPA calls work, NewAPI channel tests pass, and your client can use the endpoint reliably, then add a domain, Cloudflare, billing, and user management.
Before Deployment
Prepare:
- A Linux server, preferably Ubuntu 22.04 or newer, with at least 2 vCPU and 2 GB RAM.
- Docker and Docker Compose v2.
- A domain for the later NewAPI or public API endpoint.
- Upstream accounts or API keys that you are allowed to use.
- A low-risk test API key. Do not start with a high-limit main account key.
Recommended ports:
| Service | Common port | Recommendation |
|---|---|---|
| CPA / CLIProxyAPI | 8317 | Only expose it to NewAPI or trusted IPs |
| NewAPI | 3000 | Put HTTPS and a domain in front of it |
| Nginx / Caddy | 80 / 443 | Handle TLS and reverse proxying |
If CPA and NewAPI run on the same server, prefer binding CPA to localhost or a private network. The public entry point should usually be NewAPI, not the CPA management interface.
Step 1: Deploy CLIProxyAPI, the CPA Layer
The official project supports macOS, Linux, Windows, Docker, and Docker Compose. For site-operator use, Docker Compose is often the clearest option because configuration, auth files, and backups are easier to reason about.
The minimal Docker command is similar to:
docker run --rm \
-p 8317:8317 \
-v /path/to/your/config.yaml:/CLIProxyAPI/config.yaml \
-v /path/to/your/auth-dir:/root/.cli-proxy-api \
eceasy/cli-proxy-api:latest
With Docker Compose, the usual flow is to clone the repository, copy config.example.yaml to config.yaml, and start the service:
git clone https://github.com/router-for-me/CLIProxyAPI.git
cd CLIProxyAPI
cp config.example.yaml config.yaml
docker compose up -d
Check logs first:
docker compose logs -f
Do not connect NewAPI immediately. First confirm CPA itself starts correctly, then handle account login and upstream configuration.
Step 2: Configure Basic CPA Security
CPA handles request authentication, configuration, and account credentials. Treat it more seriously than a normal blog admin panel.
In config.yaml, check these fields first:
host: "127.0.0.1"
port: 8317
remote-management:
allow-remote: false
secret-key: "replace-with-a-strong-random-admin-secret"
auth-dir: "~/.cli-proxy-api"
api-keys:
- "replace-with-a-strong-random-key-for-newapi"
debug: false
logging-to-file: true
usage-statistics-enabled: true
The point is not to copy the block blindly. Understand the boundary:
- If
hostis127.0.0.1, CPA only accepts local traffic, which is a good fit when NewAPI runs on the same machine. - Do not casually enable
remote-management.allow-remote; the management API can modify runtime configuration and auth files. - Use a strong random
secret-key. Do not useadmin,123456, or the project name. api-keysis the CPA service authentication layer. NewAPI will use one of these keys when calling CPA.auth-dirstores credentials. Back it up carefully and keep permissions tight.
If NewAPI and CPA are on different servers, do not expose port 8317 to the whole internet. At minimum, use firewall allowlists, reverse proxy authentication, strong keys, and log auditing.
Step 3: Log In or Add Upstream Accounts
CPA supports several upstream types. The most common site-operator targets are Codex, Claude Code, Gemini CLI, and OpenAI-compatible providers.
For Docker Compose deployments, the official login commands include:
# OpenAI Codex
docker compose exec cli-proxy-api /CLIProxyAPI/CLIProxyAPI -no-browser --codex-login
# Claude Code
docker compose exec cli-proxy-api /CLIProxyAPI/CLIProxyAPI -no-browser --claude-login
# Gemini CLI
docker compose exec cli-proxy-api /CLIProxyAPI/CLIProxyAPI -no-browser --login
-no-browser prints a login URL, which is useful on a server. After login, the auth files are written into your mounted auth-dir. That directory is the core asset of the account pool.
If you use an OpenAI-compatible upstream such as OpenRouter or another compatible Base URL, add the provider configuration with its base-url, api-key, model list, and aliases.
Step 4: Test CPA Before Adding NewAPI
Before connecting NewAPI, make the smallest possible CPA request. Assume CPA is available on local port 8317 and you configured CPA_API_KEY:
export CPA_BASE_URL="http://127.0.0.1:8317/v1"
export CPA_API_KEY="the api key from config.yaml"
curl -sS "$CPA_BASE_URL/chat/completions" \
-H "Authorization: Bearer $CPA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5-codex",
"messages": [
{
"role": "user",
"content": "Reply with exactly: cpa-ok"
}
],
"stream": false
}'
If this fails, do not adjust NewAPI yet. Debug CPA first:
| Error | Check first |
|---|---|
| 401 | Whether the CPA API key matches config.yaml |
| 404 | Whether the Base URL should include /v1, and whether the model name exists |
| 429 | Whether the upstream account is rate-limited or out of quota |
| 502 / 503 | Upstream login session, proxy, network, and account health |
| HTML response | The request probably hit the wrong reverse proxy address or panel port |
Step 5: Connect CPA to NewAPI
NewAPI turns CPA into a manageable channel. The common flow is:
- Log in to the NewAPI admin panel.
- Open channel management and add a new channel.
- Choose an OpenAI-compatible channel type, or the closest compatible type.
- Set Base URL to the CPA address, for example
http://127.0.0.1:8317/v1. - Set the key to one of CPA’s
api-keys. - Add the model list you want NewAPI to expose.
- Save and run a channel test.
- Create a NewAPI token, then give users the NewAPI Base URL and token.
When both services run on the same server, NewAPI can reach CPA through 127.0.0.1 or a Docker network service name. Public users should not receive the CPA key directly. They should receive NewAPI-issued user tokens.
CPA, NewAPI, and Client Fields
Base URL and API key mix-ups are the most common source of failure. Align them first:
| Location | Base URL | API key | Used by |
|---|---|---|---|
| CPA local test | http://127.0.0.1:8317/v1 | CPA api-keys from config.yaml | Admin self-test |
| NewAPI channel | CPA private/local address, for example http://127.0.0.1:8317/v1 | CPA api-keys | NewAPI calling CPA |
| End-user client | Public NewAPI address, for example https://api.example.com/v1 | NewAPI-issued user token | Codex, Claude Code, Cursor, SDKs |
| Avoid | Publicly exposed CPA address | CPA low-level key | End users |
One sentence summary: give the CPA key to NewAPI, not to end users; end users should use the NewAPI Base URL and token.
Step 6: Use It from Developer Clients
The point of a CPA proxy is to make developer tools connect reliably. Each client has its own protocol details.
Codex
The official Codex client configuration usually involves ~/.codex/config.toml and ~/.codex/auth.json. If you connect directly to CPA, base_url commonly looks like:
model_provider = "cliproxyapi"
model = "gpt-5.5"
model_reasoning_effort = "high"
[model_providers.cliproxyapi]
name = "cliproxyapi"
base_url = "http://127.0.0.1:8317/v1"
wire_api = "responses"
auth.json:
{
"OPENAI_API_KEY": "sk-dummy"
}
If users go through NewAPI, replace base_url with the public NewAPI address and replace the key with the NewAPI token.
If you use OAuth login mode, official examples may also involve fields such as experimental_bearer_token, requires_openai_auth, and supports_websockets. Do not mix every option at once. Pick one mode, verify it, then tune models and reasoning levels.
Claude Code
Claude Code commonly uses environment variables like:
export ANTHROPIC_BASE_URL="http://127.0.0.1:8317"
export ANTHROPIC_AUTH_TOKEN="your working key"
export ANTHROPIC_DEFAULT_OPUS_MODEL="gpt-5-codex(high)"
export ANTHROPIC_DEFAULT_SONNET_MODEL="gpt-5-codex(medium)"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="gpt-5-codex(low)"
Important: a normal OpenAI chat request working does not prove Claude Code works. Claude Code is more sensitive to model names, streaming behavior, and Anthropic-compatible behavior. Test it separately.
CC Switch
If you frequently switch between official APIs, NewAPI, CPA, and local models, put the verified Base URL and key into CC Switch. The order matters: verify manually first, then hand the configuration to a profile manager.
Common CPA Proxy Architectures
Private Architecture
Best for private developer use. It is simple and has fewer failure points.
Small-Team Architecture
Best for 2-20 people. NewAPI issues keys, limits quota, and tracks usage. CPA manages the account pool.
Public Distribution Architecture
If you distribute publicly, the hard part is no longer just deploying CPA. You also need to handle payments, abuse, logs, backups, account failures, and support.
Pre-Launch Checklist
| Item | Passing standard |
|---|---|
| CPA management API | Not exposed publicly, strong secret, preferably localhost or allowlisted access only |
| CPA API key | Strong random key, separate from the management secret |
| Auth directory | Backed up, permission-controlled, never committed to a public repository |
| NewAPI channel | Channel test passes; model list and pricing are not guessed |
| Client tests | Minimal requests pass in curl, Codex, and Claude Code |
| Logs | Failures are visible, but plaintext user keys are not logged |
| Abuse control | Per-user quota, rate limits, and abnormal-request handling exist |
| Domain and certificate | Only HTTPS is exposed publicly |
Common Pitfalls
1. Mixing Up CPA and NewAPI Base URLs
The CPA panel address, CPA API address, and public NewAPI address are not the same thing.
| Address | Purpose |
|---|---|
http://127.0.0.1:8317 | CPA service or management panel |
http://127.0.0.1:8317/v1 | Common OpenAI-compatible CPA API address |
https://api.example.com/v1 | Public NewAPI endpoint for users |
When the client uses the wrong address, symptoms often include 404, HTML responses, or missing models.
2. Giving CPA Keys Directly to Users
If you are operating a site, do not give the low-level CPA key to end users. Users should receive NewAPI tokens. If a CPA key leaks, someone may bypass your user, quota, and billing layer.
3. Only Testing Whether It Replies
If the proxy can answer one simple message, you have only proven the smallest chat request. Developers also need to test:
- Whether streaming is stable.
- Whether Codex Responses API behavior works.
- Whether Claude Code Anthropic-compatible variables take effect.
- Whether long context gets truncated.
- Whether NewAPI usage and billing roughly match returned usage.
4. Enabling Remote Management Too Early
CLIProxyAPI’s management API can manage runtime configuration and auth files. The official docs also state that management API requests require the management secret. Remote management is not forbidden, but opening it naked to the internet is reckless.
5. Treating an Account Pool as an SLA
Multi-account rotation can reduce single-account rate limits, but it is not the same as reliability. Upstream rule changes, account risk control, OAuth expiry, and model removals can still break a CPA proxy suddenly.
Troubleshooting Common Errors
| Symptom | Check first |
|---|---|
| 401 Unauthorized | Wrong key, or a NewAPI user key was used in a direct CPA test |
| 404 Not Found | Wrong Base URL level, often missing /v1 or hitting the panel address |
| 429 Too Many Requests | Upstream account is rate-limited, out of quota, or the client retries too aggressively |
| 502 / 503 | CPA upstream login expired, proxy/network problem, or account unavailable |
| HTML response | Request hit the NewAPI panel, Nginx default page, or wrong domain |
| Model not found | CPA model name, NewAPI model mapping, and client model name are not aligned |
| curl works, Claude Code / Codex fails | Protocol, streaming, Responses API, or Anthropic-compatible behavior mismatch |
Debugging Order
When something fails, debug this chain instead of repeatedly changing fields in the NewAPI panel:
- Upstream account health: login session, quota, bans, region, proxy.
- CPA health: logs, config, model names, API key, auth directory.
- CPA minimal curl: test CPA before NewAPI.
- NewAPI channel: Base URL, key, model mapping, channel status.
- Client behavior: Codex, Claude Code, Cursor protocol and environment variables.
- Reverse proxy: Nginx, Cloudflare, HTTPS, headers, timeouts.
This order saves time. Many “model unavailable” failures look like client configuration bugs, but the real cause is often CPA login state, Base URL, or upstream account health.
Recommended Final Setups
| Use case | Recommended setup | Boundary |
|---|---|---|
| Private developer use | CPA alone + local client direct connection | Simplest way to verify accounts, models, and clients |
| Small team | CPA + NewAPI + internal tokens + allowlisted access | Good for shared Base URL, tokens, and quota management |
| Small public distribution | Private CPA + public NewAPI + HTTPS + quota limits + log auditing | Possible for controlled trials, but keep scale and upstream risk under control |
| Avoid | Public CPA + weak management secret + direct CPA keys for users + no abuse control | Bypasses user, quota, and access control layers; not suitable for real operation |
References
- CLIProxyAPI GitHub
- CLIProxyAPI docs, Chinese: What is CLIProxyAPI?
- CLIProxyAPI docs, Chinese: Quick start
- CLIProxyAPI docs, Chinese: Docker Compose
- CLIProxyAPI docs, Chinese: Codex client configuration
- CLIProxyAPI docs, Chinese: Claude Code client configuration
- CLIProxyAPI docs, Chinese: Management API