Hermes Agent
One key, every model, pay as you go, no subscription. A providers entry in config.yaml, the key in .env, one model id.
At the end you have Hermes Agent on one providers entry in ~/.hermes/config.yaml, pointed at https://api.uplinkswitch.com/v1 with one key from the console. Every chat model on the Models page is then a custom:uplinkswitch:<model-id> ref, Claude included, and each request bills per token from your prepaid balance. The live table below is what one agent turn costs on each model today.
What you need
Hermes Agent is Nous Research's open-source agent: a terminal interface, a learning loop, scheduled automations and subagents, with Telegram, Discord and Slack front ends. It takes any OpenAI-compatible endpoint, which is what this page configures. Install it with the one-line script, then reload your shell:
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bashYou also need an account on the console with credit on it and one key created there. Create the key for Hermes alone, so its requests sit apart from any other tool on the Usage page. The base URL is https://api.uplinkswitch.com/v1. Nothing is installed on the UplinkSwitch side: the base URL and the key are the whole configuration.
Where the settings are
Settings live in ~/.hermes/config.yaml; secrets live in ~/.hermes/.env. Hermes reads CLI flags first, then config.yaml, then .env, then its defaults. Values in config.yaml can reference a variable as ${VAR_NAME}, and a providers entry can name one with key_env, which is the form below.
Put the key in the env file, one line:
UPLINKSWITCH_API_KEY=sk-uplink-live-...The provider block
Add UplinkSwitch under providers and point model.provider at it as custom:uplinkswitch. transport is chat_completions: every id on the Models page answers that format here, Claude included. extra_headers is a mapping of header name to value sent on every request; the two below let the console attribute the traffic to Hermes on the Usage page.
model:
default: claude-sonnet-5-5
provider: custom:uplinkswitch
providers:
uplinkswitch:
base_url: https://api.uplinkswitch.com/v1
key_env: UPLINKSWITCH_API_KEY
transport: chat_completions
default_model: claude-sonnet-5-5
extra_headers:
HTTP-Referer: https://uplinkswitch.ai
X-Title: Hermes Agent
models:
claude-sonnet-5-5: {}
claude-opus-5-5: {}
gpt-6.1-sol: {}
gemini-3.1-pro-preview: {}
deepseek-v4-pro-0813: {}
kimi-k3: {}
hermes-4-405b: {}models is a mapping keyed by model id; an empty value takes the defaults, and context_length under an id overrides what Hermes detects when that comes out wrong. The seven ids above are a starting list. Any id on the Models page goes in the same mapping; each model page, such as Claude Sonnet 5.5, shows its price, context window and input types.
The same block, line by line, from the shell. Dotted paths go to config.yaml; the UPPER_SNAKE key goes to .env:
hermes config set UPLINKSWITCH_API_KEY sk-uplink-live-...
hermes config set providers.uplinkswitch.base_url https://api.uplinkswitch.com/v1
hermes config set providers.uplinkswitch.key_env UPLINKSWITCH_API_KEY
hermes config set providers.uplinkswitch.transport chat_completions
hermes config set model.provider custom:uplinkswitch
hermes config set model.default claude-sonnet-5-5hermes model does the same through a wizard: choose Custom endpoint, enter the base URL, the key and a model id, and it writes the endpoint to config.yaml. For a single run with nothing written to disk:
hermes chat --provider custom --base-url https://api.uplinkswitch.com/v1 --api-key sk-uplink-live-... --model claude-sonnet-5-5Which model to pick
Any chat id on the Models page. Tool calling works on every chat model here, and Hermes needs it for every file read, shell command and subagent, so no id on the list is a dead end. The Claude ids go in the same mapping as gpt-6.1-sol or deepseek-v4-pro-0813, with no second provider entry. Hermes 4 405B, Nous Research's own model, is on the same key at $1.20 in and $4.80 out per million tokens.
Input price decides the session cost, because Hermes sends the conversation and every tool result back on each turn; pick by the input column in the table below. Switch inside a session with /model, and add --global to keep the choice:
/model custom:uplinkswitch:gpt-6.1-sol
/model custom:uplinkswitch:claude-opus-5-5 --globalWhat a turn costs
One agent turn at 30,000 input tokens and 1,000 output tokens, which is a session that has read a few files and run a command or two. Input dominates because the conversation and tool results travel up again on every turn. Nothing is counted at the cached rate.
| Model | Input / 1M | Output / 1M | List input | List output | Under list | One turn, 30,000 in + 1,000 out |
|---|---|---|---|---|---|---|
| Claude Sonnet 5.5 | $1.20 | $3.00 | $2.00 | $10.00 | 40% on input | $0.039 |
| Claude Opus 5.5 | $2.80 | $10.00 | $4.00 | $20.00 | 30% on input | $0.094 |
| GPT-6.1 Sol | $0.60 | $3.00 | $2.00 | $10.00 | 70% on input | $0.021 |
| Gemini 3.1 Pro Preview | $1.20 | $7.20 | $2.00 | $12.00 | 40% on input | $0.0432 |
| DeepSeek V4 Pro 0813 | $0.792 | $1.188 | $1.32 | $3.96 | 40% on input | $0.0249 |
| Kimi K3 | $0.90 | $4.50 | $3.00 | $15.00 | 70% on input | $0.0315 |
| Hermes 4 405B | $1.20 | $4.80 | — | — | — | $0.0408 |
USD per million tokens, live from GET /v1/catalog. List: the developer’s own published price. The last column is the turn above at this base URL, nothing at the cached rate.
Claude Sonnet 5.5 is $0.039 for that turn, so a thirty-turn session is $1.17. GPT-6.1 Sol has the lowest input price in the table, so the same thirty turns are $0.63 there. When a response reports cached input tokens, they bill at the model's cache-read rate where the model has one, which the Models page shows next to the input rate. The whole list is 337 chat models on the one key, and the Claude Code pricing post works a day and a month of agent turns at these rates.
Check it
hermes status shows the model, the active provider and which providers have a credential. From the same shell, the key should list the models:
hermes status
curl https://api.uplinkswitch.com/v1/models -H "Authorization: Bearer $UPLINKSWITCH_API_KEY"Then send one request the way Hermes does. -i prints the headers: x-uplink-request-id names the request, and on a non-streamed answer x-uplink-charge is what it cost in USD.
curl -i https://api.uplinkswitch.com/v1/chat/completions \
-H "Authorization: Bearer $UPLINKSWITCH_API_KEY" \
-H "content-type: application/json" \
-H "X-Title: Hermes Agent" \
-d '{"model": "claude-sonnet-5-5", "max_tokens": 16, "messages": [{"role": "user", "content": "Say ok."}]}'Then run hermes and send a message. The request shows on the console Usage page within seconds, with its tokens, the charge and Hermes Agent as the client, from the X-Title header.
Errors you will see
401 invalid_api_key: the key is wrong, revoked or not reaching the request. Check~/.hermes/.envfor the line, confirmkey_envnames the same variable, and copy the key again from the console.402 insufficient_balance: the balance does not cover the request. Top up in the console.402 monthly_limit_reached: the key hit the monthly spend limit you set on it. Raise it in the console, or wait for the first of the month.404 model_not_found: the id inmodel.defaultis not on the Models page at this base URL. A dot, a dash or a date suffix out of place is enough. Copy the id from the page and set it withhermes config set model.default <id>.403 scope_denied: the key carries a model allowlist and this id is not on it. Pick an allowed id or use a key without the limit.429 rate_limited: the key hit its requests-per-minute or concurrency limit. The response carriesretry-afterin seconds. Wait that long and/retry.- A 400 on the first run: Hermes' own FAQ puts this down to a model name mismatch. Run
hermes config showand comparemodel.defaultagainst the Models page.
Good to know
hermes doctorchecks the config, and warns when a legacycustom_providerslist is still in use; theprovidersmapping on this page is the current form.extra_bodyon the same entry merges fields into every chat completions request to that endpoint; nothing is needed here.- Hermes treats
extra_headersvalues as secrets and never logs them; the two on this page carry no secret. - The same key runs Claude Code, OpenCode, OpenClaw and Cline on one balance. A key per tool keeps the spend apart on the Usage page.
Questions
Get a key in the console: prepaid credit, no subscription, 30-day price lock. Hermes Agent's own provider docs are at hermes-agent.nousresearch.com.