# Hermes Credential Pools

> Use when adding multiple API keys per provider to Hermes.

- Skill: `wcpaka-lgtm/hermes-credential-pools` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add wcpaka-lgtm/hermes-credential-pools`
- Raw SKILL.md: https://api.skillmd.com/api/skills/wcpaka-lgtm/hermes-credential-pools/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- License: MIT
- Author: wcpaka-lgtm (https://skillmd.com/u/wcpaka-lgtm)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/wcpaka-lgtm/hermes-credential-pools

---


# Hermes Credential Pools (Multi-Key Failover & Free-Tier Stacking)

Hermes can hold **multiple API keys for the same provider** and automatically rotate to the next healthy key when one hits a rate limit or quota. This is the mechanism behind "use N accounts, switch when one hits its cap". It is distinct from **fallback providers** (cross-provider failover, `hermes fallback`) — pools are tried first; only when all pool keys are exhausted does the fallback chain activate.

## When to Use

- User wants rate-limit resilience on a paid provider (several OpenRouter/Anthropic keys).
- User wants to stack multiple free-tier accounts on one provider (e.g. OpenCode Zen free models).
- Diagnosing why rotation is/isn't happening, or why a key is stuck in cooldown.

> Note: the bundled `hermes-agent` skill's `references/providers-and-models.md` mentions pools in one line only. This skill is the operational deep-dive — prefer this one for pool questions.

## Key Commands

```bash
hermes auth add <provider> --api-key <KEY>      # add a key to the pool (repeatable)
hermes auth add <provider>                      # interactive wizard (asks api-key vs oauth)
hermes auth list                                # all pools; ← marks the selected credential
hermes auth list <provider>                     # one provider's pool
hermes auth remove <provider> <index>           # 1-based index
hermes auth reset <provider>                    # clear all cooldowns/exhaustion flags
hermes auth                                     # interactive wizard (add/remove/reset/strategy)
```

No cap on the number of keys per pool. Env-var keys (`OPENROUTER_API_KEY` etc.) are auto-seeded as pool entries and auto-pruned if the env var disappears; keys added via `hermes auth add` are persisted in `auth.json` under `credential_pool` and never auto-pruned.

## Rotation Behavior (verified against agent/credential_pool.py + official docs)

| Error | Behavior | Cooldown |
|---|---|---|
| 429 rate limit | Retry same key once (transient); second consecutive 429 rotates to next key | 1 hour |
| 402 billing/quota | Rotate immediately | 24 hours |
| Plan/usage limit message (e.g. "usage limit reached") | Rotate immediately — no retry, the cap won't clear | — |
| 401 auth expired | Try OAuth token refresh first; rotate only if refresh fails | — |
| All keys exhausted | Fall through to `fallback_providers` chain if configured | — |

Rotation strategies (set via interactive `hermes auth` wizard or `credential_pool_strategies:` in config.yaml):

| Strategy | Behavior |
|---|---|
| `fill_first` (default) | Use first healthy key until exhausted, then next — the natural "one account at a time" mode |
| `round_robin` | Cycle evenly after each selection |
| `least_used` | Lowest request count wins |
| `random` | Random among healthy keys |

For "use account 1 until it caps, then account 2", the **default `fill_first` is exactly right — no config change needed**.

Delegation: `delegate_task` children automatically share the parent's pool (same provider) with per-task credential leasing — subagents get the same rate-limit resilience for free.

## Pitfalls

1. **Rotation resets the provider-side prompt cache.** Caches are scoped per account/key, so after rotating, the next request re-reads the whole conversation at undiscounted input price. On long sessions with frequent rotation this is real money. **Exception: free models** — when input/output/cached-read are all $0 (e.g. OpenCode Zen free tier), rotation costs nothing. Always check the model's pricing table before promising "costless rotation".
2. **Pool rotation vs provider fallback semantics**: provider-level fallback is turn-scoped (primary restored each user message; fallback fires at most once per turn). Pool rotation is NOT turn-scoped — an exhausted key stays in cooldown (1h/24h) and the pool keeps using the next key until cooldown clears or `hermes auth reset` is run.
3. Don't tell users to put pool config in `.env` — strategies belong in `config.yaml` (`credential_pool_strategies:`), keys are added via `hermes auth add` (manual entries persist in `auth.json`).
4. OpenCode Go uses a **weekly** usage-limit scheme ("Resets in Xh Ym" format is handled in the pool source) — cooldown expectations differ from daily-reset providers.
5. Free-tier stacking math: the per-account cap multiplies with account count (10 accounts ≈ 10× daily cap), but agent work burns many requests per user turn (each tool call = ~1 request), so realistic throughput is dozens of agent tasks/day, not hundreds of chats. Set expectations with real numbers.
6. Free models are usually **time-limited promotions** — verify the model still exists in the provider's current model list before promising a durable setup.

## Provider Quota Knowledge Bank

Provider-specific free-tier/limit mechanics verified in sessions live in `references/`:

- `references/opencode-zen-free-tier.md` — OpenCode Zen free models: IDs, endpoints, per-account request cap, rotation cost analysis for stacking accounts.

## Verification

1. `hermes auth list` shows all intended credentials under the provider.
2. Send one real request with the target model; confirm response and no auth errors.
3. (Optional) confirm rotation by checking `~/.hermes/auth.json` `credential_pool` for `last_status`/`request_count` movement, or `hermes auth reset <provider>` to clear cooldowns between tests.

