Keeper
keeper is the background worker for the account pool. Where relay is the hot request path, keeper is the offline side: it ingests raw usage, mirrors the pool’s identities and keys, rolls usage up into hourly/daily stats, keeps model pricing current, and probes account quota. It also exposes an admin API that the pool console (in platform-api) reads.
- Base URL (dev):
http://localhost:3114 - Admin API: under the global
/apiprefix, e.g.GET /api/admin/keeper/overview - Audience: internal — consumed by the admin console, not by end users
Responsibilities
| Module | What it does |
|---|---|
ingest | Consumes raw usage from CLIProxyAPI into KeeperUsageInbox, then processes it into KeeperUsageEvent (reliable-queue, at-least-once with dead-lettering) |
usage | Aggregates events into hourly/daily overview + health stats; serves the overview/analysis/export admin endpoints |
identities | Mirrors the pool’s auth-files and api-keys into KeeperUsageIdentity / KeeperCpaApiKey |
pricing | Syncs per-model prices into ModelPriceSetting (source refreshable on demand); relay reads these |
quota | Probes per-account ChatGPT quota through the CLIProxyAPI management API |
cliproxy | Client to the CLIProxyAPI management API (via @magic/cliproxy) |
health | Liveness / readiness |
Ingest pipeline
Usage arrives asynchronously and must not be lost or double-counted:
- Raw usage lands in
KeeperUsageInbox(an inbox table backed by a reliable queue). - A processor turns each inbox row into a normalized
KeeperUsageEvent, returning one ofprocessed/failed/dead_letter. - Failures are retried by a sweeper; rows that exceed the retry budget are dead-lettered and acknowledged so a single poison record can’t wedge the queue.
- Processed events feed the aggregation into
KeeperUsageOverviewHourlyStat/…DailyStatandKeeperUsageHealthStat.
Aggregation is checkpointed (AggregationCheckpoint), so a restart resumes where it left off instead of re-scanning or double-aggregating.
Admin API surface
All routes live under /api/admin/keeper and are grouped by concern:
| Area | Endpoints (relative to /api/admin/keeper) |
|---|---|
| Overview | overview, overview/realtime, analysis, models/used |
| Usage events | events, events/export, events/filters/{models,sources,apikeys} |
| Identities / keys | auth-files, api-keys, sync/preview, reset (POST) |
| Pricing | pricing, pricing refresh (POST), pricing/models |
| Quota | quota, quota/refresh/:auth_index |
| Status / cache | status, cache (POST) |
Data it owns
KeeperCpaApiKey, KeeperUsageIdentity, KeeperUsageInbox, KeeperUsageEvent, KeeperUsageOverviewHourlyStat / …DailyStat, KeeperUsageHealthStat, ModelPriceSetting, and AggregationCheckpoint.
Relationship to the rest of the system
- CLIProxyAPI is the source of raw usage and the pool’s identities; keeper reads it through the management API.
- relay consumes the model prices keeper maintains and spends against the pool keeper observes.
- platform-api hosts the admin console that renders keeper’s overview/analysis data and drives its sync/reset actions.
Keeper shares the Postgres database but does not run migrations — only platform-api does, at boot. See Architecture & conventions.