Core concepts
Six objects and one rule. Get these straight and the rest of EntitleHub follows.
Entitlement
A durable capability your app checks — premium, pro, team, lifetime. This is the only thing your app code should reference. Its key is a stable contract: SKUs, prices, and platforms can change underneath it without an app update.
Product
A thing sold in a specific store — an App Store / Play Console / Stripe SKU. A product has a store (app_store, play, stripe, web, amazon), a store product id (exactly as registered in that store), a type (subscription, non_consumable, consumable), and a price.
Mapping
The many-to-many link from products to entitlements. One product can grant several entitlements; one entitlement can be granted by many products (the iOS SKU, the Android SKU, the web SKU all map to the same pro). Mappings are retroactive — change a mapping and existing subscribers resolve against the new rule immediately.
Subscriber
A user, keyed by your app_user_id(whatever id your system uses). One subscriber's state is consistent across every device and platform. Use a stable id — your own user id, not a device id — so purchases survive reinstalls and follow the person across platforms.
Grant
A record that a subscriber holds an entitlement, for a reason: a validated purchase, a renewal, a promo, a manual comp. A grant carries a status (active, trial, grace, expired, revoked), an optional expiry, and whether it will renew.
Offering
The set of products you present on a paywall, with their entitlements — the data you need to build a purchase screen. Fetch it from /v1/offerings.
Event
An immutable log entry for everything that changes state — initial_purchase, renewal, cancellation, expiration, billing_issue, refund, override. Events drive analytics and webhooks.
The check() rule
check(app_user_id, entitlement) is active when the subscriber has at least one grant for that entitlement whose status is live (active, trial, or grace) and whose expiry (if any) is in the future. Sandbox grants are excluded unless you explicitly ask for them. When several grants overlap, the one with the furthest expiry wins.
Name entitlements after capabilities (pro), not products (monthly_sub_v2). You'll thank yourself when you add a second SKU, a lifetime tier, or a bundle later.
