API tier gating

Dashboard's API has two tier behaviours, applied uniformly across the programmatic surface (account API keys). The web dashboard (session cookie auth) is unaffected by tier gating and works for any customer at any tier.

Overview

  • Free tier: full read access to your own data via API. Full web-dashboard access.
  • Pro tier: every Free feature, plus programmatic mutations, AI analysis, trend warnings, and the premium notification destinations.

Tier gating exists to differentiate programmatic API access, not to limit human use of the product. A Free customer can manage everything from the web dashboard; the same operations via API key require Pro.

What's Free

Read access to your own data:

  • GET /api/v1/servers, GET /api/v1/servers/{id}
  • GET /api/v1/servers/{id}/alerts, GET /api/v1/servers/{id}/health, GET /api/v1/servers/{id}/history
  • GET /api/v1/servers/{id}/metrics, GET /api/v1/servers/{id}/disk-health
  • GET /api/v1/health/{server_id}/... (legacy paths; same data)
  • GET /api/v1/channels, GET /api/v1/channels/{id} (channel list; mutations are Pro)
  • GET /api/v1/servers/{id}/mutes (list muted rules; mute / unmute are Pro)
  • All auth endpoints (/auth/login, /auth/register, /auth/me, etc.)
  • All billing endpoints (/billing/checkout, /billing/status, etc.); Free customers need these to upgrade.
  • Crucible agent ingest: POST /api/v1/ingest (collector key, never gated)
  • GET /api/v1/version (unauthenticated)
  • Public health probe: GET /api/v1/health (unauthenticated)

What's Pro

Programmatic mutations on your account state, plus the AI and trend-warning features:

Channels (notification destinations)

  • POST /api/v1/channels (create)
  • PUT /api/v1/channels/{id} (update)
  • DELETE /api/v1/channels/{id} (delete)
  • POST /api/v1/channels/{id}/test (send test notification)

Alert mutations

  • POST /api/v1/servers/{id}/mutes (mute a rule)
  • DELETE /api/v1/servers/{id}/mutes (unmute)
  • POST /api/v1/alerts/{id}/acknowledge
  • POST /api/v1/alerts/{id}/resolve

Server management

  • POST /api/v1/servers (create)
  • PATCH /api/v1/servers/{id} (rename / re-tag)
  • DELETE /api/v1/servers/{id}
  • POST /api/v1/servers/{id}/rotate-key
  • POST /api/v1/servers/{id}/restore and POST /api/v1/servers/restore-all

AI analysis

  • POST /api/v1/servers/{id}/analyze (trigger health analysis)
  • GET /api/v1/servers/{id}/analyses (per-server analysis history)
  • GET /api/v1/servers/{id}/trend-warnings
  • POST /api/v1/trend-warnings/{id}/feedback
  • DELETE /api/v1/trend-warnings/{id}/feedback (dismiss)
  • GET /api/v1/trend-warnings/track-record

Account management

  • GET /api/v1/account/audit
  • GET /api/v1/account/keys, POST /api/v1/account/keys, POST /api/v1/account/keys/{id}/rotate, DELETE /api/v1/account/keys/{id}

What a 402 response looks like

When a Free-tier API key hits a Pro-only endpoint, Dashboard returns 402 Payment Required:

HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "error": "pro_required",
  "message": "Programmatic API access is available on the Pro plan. Visit app.glassmkr.com/settings to upgrade.",
  "upgrade_url": "https://app.glassmkr.com/settings",
  "documentation_url": "https://app.glassmkr.com/docs/programmatic-api"
}

The shape is stable; error is the machine-readable code, message is human-readable, upgrade_url points to the billing flow. Integrators building against the Free tier should handle 402 explicitly and route it to a "your plan needs upgrading" message rather than a generic auth-error path.

402 is distinct from 403 (insufficient_scope) and 401 (auth_failed); the codes are stable and safe to branch on.

Web dashboard exception

The web dashboard (session cookie auth) is unaffected by tier gating. Free customers see the full UI; Pro-only features render upgrade prompts where appropriate, but the dashboard is fully functional for any customer.

This is intentional. Tier-gating exists to differentiate programmatic API access; humans using the product through the browser are not the surface the policy applies to.

Free trial quotas

Some Pro features have Free-tier trial quotas accessible only through the web dashboard:

  • AI analysis: each Free server gets one trial analysis. After that, additional analyses require Pro. The trial counter is per-server and persistent.

API key callers do not have access to these trial quotas. Calls to gated endpoints from a Free-tier key return 402 immediately, without consuming the trial budget.

How we keep this honest

A CI lint (pnpm lint:tier-gating) enforces that every endpoint in /api/v1 declares its tier, either via inline marker or via the explicit allowlist at scripts/tier-gating-allowlist.json. CI fails if any new endpoint ships without a declaration. Customers shouldn't see silent leakage between Free and Pro.