Skip to content

Subscription

github-actions[bot] edited this page Aug 4, 2026 · 1 revision

Enjoy Player uses three membership tiers. Entitlements are local-first in the UI but reconciled against the Enjoy API whenever the app starts or resumes.

Tiers

Tier Active daily credits Feature access
Free 1,000 Free baseline
Lite 12,000 Paid-tier features
Pro 60,000 Paid-tier features

SubscriptionStatus derives isLite, isPro, and the shared isPaidTier gate from both the tier and active status. Lite and Pro therefore share paid feature gates; their principal difference is the daily credit allocation. The membership card displays tier-aware labels, renewal or expiry details, and credits.

Catalog and checkout

The subscription screen presents Free, Lite, and Pro cards with a monthly/yearly selector. Pricing and savings come from GET /api/v1/subscriptions/plans; missing plan data produces a loading skeleton rather than a hardcoded fallback.

flowchart LR
  Catalog["Free, Lite, Pro catalog"] --> Plans["GET /api/v1/subscriptions/plans"]
  Catalog --> Purchase["Unified purchase sheet"]
  Purchase --> Checkout["External checkout"]
  Checkout --> Reconcile["Resume reconciliation"]
  Reconcile --> Status["Live tier and credits"]
Loading

On Windows, macOS, and Linux, choosing Lite or Pro opens an adaptive purchase sheet. Auto-renew is the primary path; prepaid months are the secondary path. The selected tier is carried through PurchaseRequest. Mobile currently shows a purchase-unavailable dialog instead of launching an external checkout.

Method Path Purpose
GET /api/v1/subscriptions Current tier, activity, expiry, and auto-renew state
GET /api/v1/subscriptions/plans Tier and billing-interval catalog
POST /api/v1/subscriptions Prepaid checkout with months, processor, and tier
POST /api/v1/subscriptions/auto_renew Start auto-renew with plan_id
POST /api/v1/subscriptions/cancel Cancel renewal at the period end

See the REST client and tier catalog.

Reconciliation

TierReconcileHost refreshes live subscription status, the cached profile, and credits on cold start and app resume. After an app-initiated checkout, it polls every three seconds for up to 30 seconds and accepts either Lite or Pro as a successful paid upgrade. A genuine Free-to-paid transition produces a tier-specific success notice.

See reconciliation orchestration and ADR-0041.