Surfil

API · GET /v1/entitlement

Returns the caller's org plan and the user's Credit balance. Read-only - it never mutates a balance (that is exclusively meter/consume).

Auth

Dual-auth: either a Supabase session (the Hub's path) or a device token(the runtime heartbeat). The device path resolves the org from the D1 mirror only and can see only its own user's row.

Response · 200

{
  "plan": "pro",
  "status": "active",
  "features": { },
  "expires_at": 1767225600,
  "credits": {
    "window":  240,
    "monthly": 1500,
    "paid":    3200,
    "granted": 100,
    "total":   5040,
    "resets_at": 1767225600
  }
}
  • plan / status - current plan and its state.
  • expires_at - unix seconds, or null for no expiry.
  • credits - the four buckets plus their total and reset time. Consumption order is window → monthly → paid → granted.

The honest default

A user who never subscribed has no active plan: the row reads plan: "starter" with status: "cancelled" and zero provisioned credits. That default returns instead of an error - absence is a fact, not a failure.

Errors

  • 401 - missing or invalid credential.
See Credits for what a Credit is and why the buckets exist.