OpenCode Go Usage API
August 13, 2026 · View on GitHub
Important
This project is no longer maintained (2026-08-14) and is kept only as an archive.
Why: OpenCode now provides an official JSON usage API —
GET https://opencode.ai/zen/go/v1/usage — authenticated with the regular
Authorization: Bearer <API_KEY> header (the standard Anthropic-compatible
API key); no workspace ID or auth cookie is needed. This endpoint is not
covered by the official documentation; it was discovered in
farion1231/cc-switch#6433,
which also includes a ready-to-use script for CC Switch's custom usage
template. To try it:
curl -H "Authorization: Bearer <API_KEY>" https://opencode.ai/zen/go/v1/usage
The discontinuation condition set when this project started (CC Switch natively supporting OpenCode Go usage queries, or OpenCode providing a JSON usage API) has been met, so no new features, fixes, or issue responses should be expected. Please migrate to the official endpoint.
中文文档:README.md
When accessed, this service fetches the specified OpenCode Go workspace page in real time, parses the usage data, and returns JSON. It supports configuring multiple OpenCode Go accounts in a single service, and is designed for the usage-query feature of CC Switch.
This project was discontinued on 2026-08-14: OpenCode's undocumented /v1/usage endpoint was publicized in #6433, meeting the discontinuation condition set when this project started (CC Switch officially supporting OpenCode Go usage queries, or OpenCode providing a JSON usage API). Previously tracked issues and PRs: #2260, #3606
API
Query usage
GET /usage: queries the default account specified inconfig.toml.GET /usage/{account_id}: queries a specific account, e.g./usage/backup.
Both endpoints require the Authorization: Bearer <API_TOKEN> header, and successful responses share the same format:
{
"success": true,
"reason": "",
"data": "Rolling 0% (5h) | Weekly 7% (3d16h) | Monthly 3% (29d22h)"
}
success:truewhen at least one usage group is parsed.reason: explains the cause when fetching or parsing fails.data: usage and reset countdown, customizable via the response template.
Expired credentials, fetch failures, and parse failures for known accounts still return HTTP 200, indicated by success:false. Unknown accounts return HTTP 404, and authentication failures return HTTP 401.
Health check
GET /health requires no authentication and returns {"status":"ok"}. This endpoint only checks that the service is alive; it does not fetch any account pages.
Configuration
The service always reads config.toml from the current working directory. Copy the example and restrict file permissions:
cp config.example.toml config.toml
chmod 600 config.toml
Full example:
[server]
api_token = "It's recommended to generate a strong random value with openssl rand -hex 32"
host = "0.0.0.0"
port = 18443
ssl_certfile = "certs/cert.pem"
ssl_keyfile = "certs/key.pem"
[fetch]
timeout = 10
retries = 1
locale = "zh"
user_agent = "Mozilla/5.0 ..."
[response]
data_template = "Rolling {rolling_percent}% ({rolling_reset}) | Weekly {weekly_percent}% ({weekly_reset}) | Monthly {monthly_percent}% ({monthly_reset})"
[account]
default = "main"
[accounts.main]
auth_cookie = "auth cookie value of the main account"
workspace_id = "wrk_main"
[accounts.backup]
auth_cookie = "auth cookie value of the backup account"
workspace_id = "wrk_backup"
Account IDs support 1–64 characters of uppercase/lowercase letters, digits, _, and -. The first character must be a letter or digit, and IDs are case-sensitive.
The configuration is validated at startup. After modifying the config file, the service must be restarted for changes to take effect.
Configuration options
| Option | Default | Description |
|---|---|---|
server.api_token | None | API access token, required |
server.host | 0.0.0.0 | Listen address |
server.port | 18443 | Listen port |
server.ssl_certfile / ssl_keyfile | Empty | Must both be set; HTTP is used when both are empty |
fetch.timeout | 10 | Timeout in seconds for a single fetch |
fetch.retries | 1 | Number of retries after a network error |
fetch.locale | zh | OpenCode's oc_locale cookie |
fetch.user_agent | Built-in browser UA | User-Agent for upstream requests |
response.data_template | Built-in template | Template for the data field in the response |
account.default | None | Default account ID, required |
accounts.<id>.auth_cookie | None | The raw auth cookie value of that account |
accounts.<id>.workspace_id | None | The workspace ID of that account |
- Workspace ID:
https://opencode.ai/workspace/<here>/go - Getting the cookie: open
https://opencode.ai/workspace/wrk_XXX/goin your browser and inspect it via developer tools (F12)
Customizing the data format
Template placeholders consist of a group and a field, in the format {<group>_<field>}. There are three groups:
| Group | Meaning |
|---|---|
rolling | Rolling usage |
weekly | Weekly usage |
monthly | Monthly usage |
Each group supports three fields:
| Field | Meaning |
|---|---|
percent | Percentage used |
reset | Countdown until reset |
status | Status text |
Example of a compact-style configuration:
[response]
data_template = "R {rolling_percent}% ({rolling_reset}) | W {weekly_percent}% ({weekly_reset}) | M {monthly_percent}% ({monthly_reset})"
Deployment
The following example assumes the system is Ubuntu 24.04, the project directory is /opt/opencode-go-usage-api, and uv is installed.
cd /opt
git clone https://github.com/andywang425/opencode-go-usage-api.git
cd opencode-go-usage-api
uv sync
cp config.example.toml config.toml
# Edit config.toml as needed
chmod 600 config.toml
If you need a self-signed certificate:
chmod +x gen-cert.sh
./gen-cert.sh <public IP or domain>
Then write the paths of the generated certificates into config.toml:
[server]
ssl_certfile = "certs/cert.pem"
ssl_keyfile = "certs/key.pem"
Install the systemd service:
chmod +x run.sh
cp opencode-go-usage-api.service /etc/systemd/system/
# Edit /etc/systemd/system/opencode-go-usage-api.service as needed
systemctl daemon-reload
systemctl enable --now opencode-go-usage-api
systemctl status opencode-go-usage-api
If you modify the configuration later, restart the service for changes to take effect:
systemctl restart opencode-go-usage-api
Remember to allow server.port (default 18443) in your cloud provider's security group / firewall.
Verify the service (add -k when using a self-signed certificate):
curl -k https://127.0.0.1:18443/health
curl -k -H "Authorization: Bearer <API_TOKEN>" https://127.0.0.1:18443/usage
curl -k -H "Authorization: Bearer <API_TOKEN>" https://127.0.0.1:18443/usage/backup
# View logs
journalctl -u opencode-go-usage-api -f
Nginx reverse proxy
You can run the API service in HTTP mode and serve HTTPS through an Nginx reverse proxy.
First, edit config.toml:
[server]
host = "127.0.0.1" # listen on localhost only
port = 18443
ssl_certfile = "" # leave empty: use HTTP
ssl_keyfile = "" # leave empty: use HTTP
Example Nginx configuration:
upstream opencode_go_usage {
server 127.0.0.1:18443; # must match server.port in config.toml
keepalive 16;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com; # change to your public IP or domain
# Enable both TLS 1.2 and 1.3 for compatibility with old and new CC Switch versions
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# Change to your own certificates (when using the self-signed certificates generated by gen-cert.sh, fill in the paths of cert.pem and key.pem respectively)
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
location / {
proxy_pass http://opencode_go_usage;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 15s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}
With the reverse proxy in place, you only need to allow port 443 in your security group / firewall; server.port (default 18443) does not need to be exposed publicly. The URL configured in CC Switch can also omit the port number, e.g. https://<public IP or domain>/usage/<ACCOUNT_ID>.
CC Switch integration
Click the usage-query configuration icon, select "Custom" as the preset template, and paste the following extractor code:
({
request: {
url: "https://<public IP or domain>:<PORT>/usage/<ACCOUNT_ID>",
method: "GET",
headers: {
Authorization: "Bearer <API_TOKEN>",
},
},
extractor: function (response) {
return {
isValid: response.success,
invalidMessage: response.reason,
extra: response.data,
};
},
});
If /<ACCOUNT_ID> is omitted, the usage of the default account is queried. If you use a self-signed certificate, you need to import the certificate into the trust store of the operating system where CC Switch runs.
How to install a self-signed certificate on Windows 11: download certs/cert.pem to your machine by any means, rename it to cert.crt, double-click it, choose Install Certificate → Store Location: Current User → Place all certificates in the following store → Browse → Trusted Root Certification Authorities → Next, Finish.
Local development
uv sync
cp config.example.toml config.toml
# Start after editing config.toml
uv run uvicorn opencode_go_usage_api:app --reload
Run tests:
uv run pytest