Tracks API usage and cost across providers via poller snapshots, pushed telemetry, and Claude Code OTLP metrics, with per-project cost attribution and recurring-subscription tracking.
Production: usage.jays.services on Coolify (see private jaywedgeworth22/fleet-ops:ATTACK-MAP.md). Cloudflare proxies public TLS for that hostname; it is not the application host. Oracle Cloud and Render are retired (historical scripts in deploy/oracle/; Render rollback notes in deploy/render/RETIRED-rollback.md).
Keep the public repository About aligned with production. Do not add provider counts or vendor lists.
| Field | Value |
|---|---|
| Homepage | https://usage.jays.services |
| Description | Tracks API usage and cost via poller snapshots, pushed telemetry, and OTLP metrics. Production: usage.jays.services |
| Topics | none |
| Method | Path | Purpose |
|---|---|---|
POST |
/api/ingest/usage |
Ingest shared usage-telemetry v2 events from sibling apps (bearer token); durable eventId, typed ACK/errors, optional project; legacy v1 remains replay-only |
GET |
/api/budget-status |
Per-provider and per-project month-to-date spend vs monthly budget (read token) |
POST |
/api/otlp/v1/metrics |
Receive OTLP metrics from Claude Code (same bearer token as ingest); reads the project resource attribute |
GET |
/api/usage-events |
Usage summary grouped by source/provider/project (?projectId= filter) |
GET POST |
/api/subscriptions |
List / create recurring subscriptions (fixed fee + renewal cycle) |
PUT DELETE |
/api/subscriptions/:id |
Update / delete a subscription |
GET |
/api/sentry-health |
Per-project unresolved-issue counts from Sentry (dashboard-gated) |
GET |
/api/health |
Public process liveness plus version and deployed revision |
GET |
/api/ready |
Public SQLite, scheduler, startup-entrypoint, and backup readiness |
- Per-project cost: tag usage with a project so spend rolls up per project. Claude Code:
OTEL_RESOURCE_ATTRIBUTES=project=<name>(per-repo via direnv). Other apps: a top-levelprojectfield on the ingest contract. Names resolve case-insensitively to aProject; create the Project (with a budget) in Settings → Projects. - Subscriptions: track recurring fixed fees (e.g. a Claude plan) with an interval and renewal date in Settings → Subscriptions. A maintenance job materializes each billing period's fee as a usage event, so subscriptions count toward provider and project budgets automatically.
npm ci
cp .env.example .env # fill in required values
npx prisma db push # this repo intentionally has no migrations directory
npm run dev -- --turbopackThe webpack next dev path is affected by an upstream instrumentation-bundling
bug in this project. Turbopack is required for local development; production
next build / next start are unaffected.
npm run verifyverify runs lint, TypeScript, unit/integration tests, the real SQLite safe-
migration reproduction, transaction-consistent pre-migration backup and
retention tests, startup/backup configuration tests, and a production Next.js
build. CI uses the same pinned Node version from .node-version.
- Next.js (App Router) — web framework
- Prisma (SQLite) — ORM + database (
/data/prod.dbon the production block volume) - Hetzner NBG1 / Coolify — production host (see
DEPLOY.md) - Cloudflare — public HTTPS proxy for
usage.jays.services; also hosts the optional receipt-inbox Worker - Backblaze B2 — Litestream replica; Cloudflare R2 is weekly archive only
- Sentry — error monitoring (Sentry Health card)
- AGENTS.md — agent-facing guide (schema, auth, ingest flows, env vars)
- DEPLOY.md — Production runbook (see private
fleet-ops:ATTACK-MAP.md); Render notes retired todeploy/render/RETIRED-rollback.md - docs/litestream.md — backup and restore runbook
- docs/release-maintenance.md — why one-time data repairs/seeds remain explicit and what safe marker automation requires
- docs/direct-billing-integrations.md — provider billing/API connection matrix (when present)