Roadie is built for apps that serve their own users. Attach an end-user identity to a request and the platform applies that user’s limits, attributes usage and cost to them, lets you block an individual abuser, and resolves the plan entitlement that gates your premium features — all without you standing up a per-user backend.

Attaching a user

For server-key calls, pass user on the request (or as a client-level default):
  • id — your stable identifier for the end user (opaque to Roadie, up to 256 characters).
  • plan — an optional asserted plan tag (e.g. free, pro) that selects a per-plan limit policy.
Set it once as a default when constructing the client, and override per call as needed:
With a client token, the end-user id and plan are carried in the token — the customer’s auth system is the source of truth. A user in the request body must match the token or be omitted.
End users are created lazily on first sight, so there is no registration step; the first attributed request registers the user.

Per-user limits

You configure end-user limit policies, including per-plan presets (free vs pro). Because a request is attributed to a user, the limits engine enforces that user’s rate limits and quotas in addition to the key, environment, and project limits. A user over their limit fails with a rate_limit_error (e.g. end_user_rpm_exceeded) or a quota_error — without affecting your other users.

Analytics

Usage and cost roll up per end user, so the dashboard can show your top users by spend or volume, and per-user usage over time. This is the same data your support team uses to answer “why is this user’s bill high?”.

Blocking a user

If a user abuses your app, block them from the dashboard. A block is enforced instantly: it writes a Redis denylist entry keyed by (project, external id) — the same fast-propagation path that revokes keys — so the gateway rejects that user’s requests within a second with permission_error / end_user_blocked. Unblock to restore access. The durable source of truth is the user’s blocked_at, which the denylist is re-synced from.

Entitlements

An end user has two independent plan axes:
  • Asserted plan — the plan in the request body or client token. It reflects what the client claims and is convenient for selecting per-plan limits.
  • Authoritative entitlement — a tier your backend grants and that a client can never set itself. This is what you gate paid features on.
When both are present, the authoritative entitlement wins. It is stamped into the client token’s plan claim at the next mint, so the existing per-plan policy engine enforces it with no gateway hot-path change. An explicit entitlement of free is an authoritative downgrade that overrides an asserted pro; an expired or unset entitlement falls back to the asserted plan.

Granting an entitlement

Grant or change an entitlement with a secret key only — this is the anti-self-upgrade gate, so a client token or publishable key is rejected with a permission_error and a device can never raise its own tier:
  • tier — the authoritative tier (e.g. free, pro). Last-write-wins per user.
  • expires_at — optional; past it, the effective tier falls back to the asserted plan.
  • source — optional provenance (e.g. storekit, manual).
The call is idempotent and records a “customer since” marker on the first non-free grant that survives later downgrades. See the entitlement endpoint.
Entitlement is read-only in the dashboard — there is no entitlement editor. A grant is always an authenticated PUT from your backend (typically your App Store Server Notification or webhook handler), which keeps your server the sole authority over who is a paying user.

The reserved free_exhausted tier

free_exhausted is a reserved tier that resolves to an intrinsic hard requests = 0 / month deny — request #1 is refused with a quota_error the instant it is stamped, without any configured policy. It is used by the mobile free-tier guard to paywall a device that has burned its monthly free allotment; the deny self-heals when the UTC month rolls over, and a pro grant overrides it at any time. For the full flow — from a free device to a paying customer — see the free-to-pro entitlements guide and the StoreKit tutorial.