Skip to content

Status codes & limits

Status codes, plan limits, retention, and billing — the operational rules that apply across every endpoint.

Status codes at a glance

CodeMeaning
200OK (incl. deduped baseline upload)
201Created (new run / new baseline version)
400Malformed JSON or failed validation
401Missing or invalid client credentials
402A write would exceed a hard plan limit (managed billing only)
404Resource not found / not in your repository
413Request body exceeds the size limit
429Too many failed auth attempts — see Retry-After

Plan limits

When the server runs with managed billing (DUNGBEETLE_BILLING=managed), ingest endpoints are subject to the plan limits of the team that owns the repository. On the Free tier the repository, storage, and snapshot limits are hard: a write that would exceed one is rejected with 402 Payment Required and an actionable message, while existing data is always preserved (over-quota is read-only, never destructive). Paid tiers are soft fair-use — writes are never blocked; usage past the limit only surfaces as a warning (and, on Business+, a storage overage at billing time).

Self-hosted servers (DUNGBEETLE_BILLING=none, the default) never enforce limits — every quota is unlimited and ingest is never metered. See Pricing and GET /api/v1/usage for the current numbers.

Retention. Each plan keeps runs for a fixed window (14 days on Free up to a year on Business; custom on Enterprise). A cron runs npm run retention:prune to delete runs and their report blobs past the cutoff and free the storage they held — baselines are the durable reference and are never pruned. With managed billing off, retention is unlimited and pruning is a no-op, so a self-hosted server keeps everything by default.

Subscriptions (Stripe). The managed cloud turns plans into Stripe subscriptions. It stays completely dormant until an operator sets STRIPE_SECRET_KEY (plus STRIPE_WEBHOOK_SECRET and the per-plan price ids STRIPE_PRICE_STARTER / STRIPE_PRICE_TEAM / STRIPE_PRICE_BUSINESS) — a self-hosted server never needs Stripe. Users subscribe, upgrade/downgrade, and cancel through Stripe Checkout and the customer portal (from the Usage page, /ui/usage, for the active team); plan and status are driven entirely by signature-verified webhooks at:

MethodPathAuthPurpose
POST/webhooks/stripeStripe signatureSubscription lifecycle → plan + status

The webhook maps checkout.session.completed → subscribe, customer.subscription.updated → plan/status (a past_due subscription makes the team read-only until billing is fixed — never destructive), and customer.subscription.deleted → revert to Free. Invalid signatures are rejected with 400 and change nothing.

Source-available: CLI under FSL-1.1-ALv2, cloud server under BUSL-1.1. See Licensing.