Access levels and mappings
Define feature access and connect store products to stable lookup keys.
Download this chapterOn this page
An access level is a stable capability your application checks, such as pro. Store SKU names can differ across platforms while both map to the same access level. This keeps application feature checks independent of product naming and pricing changes.
Create an access level
Open Access levels → New access level, choose an immutable lookup key, and enter a display name. The lookup key is the value used by application code. A display-name edit is not a rename of that key.
Then add a mapping from the appropriate app/platform/product to the access level. A mapping is explicit: a purchase of an unmapped SKU does not automatically grant a similarly named level.
Choose the grant mode
| Mode | Behavior | Typical use |
|---|---|---|
store_managed | Access follows verified store state and expiry | A recurring subscription |
lifetime | Access has no scheduled expiry, but verified revocation/refund still matters | A permanent unlock |
Lifetime is a catalog rule, not a manual grant to a chosen customer. The current dashboard does not provide an arbitrary customer-access override flow.
Read access from your app
The subscriber API returns an access-level map keyed by the lookup key:
{
"app_user_id": "user-123",
"customer_id": "22222222-2222-4222-8222-222222222222",
"access_levels": {
"pro": {
"active": true,
"expires_at": "2026-10-09T10:00:00Z",
"platform": "apple",
"product_id": "pro.monthly",
"last_verified_at": "2026-09-09T10:00:00Z",
"event_id": "123"
}
}
}The SDK exposes the corresponding language-native accessLevels map. Check its active value. A missing key does not grant access. expires_at can be absent for an access grant without scheduled expiry. This is an illustrative response, not a live entitlement certificate.
How multiple purchases combine
CherrySub maintains per-store-identity, per-product grants and resolves their union. One expired Apple subscription cannot mask a different active Google purchase or a lifetime unlock. An observation replaces only the affected identity's grant contribution.
Cancellation of auto-renewal is not immediate expiration. Current access is evaluated against persisted expiry at read time, so it becomes inactive at the boundary even without a timer event. Do not assume a webhook will arrive at that exact wall-clock instant.
Mapping changes are versioned
Creating, changing, or ending a mapping establishes a safe event boundary. Old source events retain the mapping version that applied when they were observed. New authoritative observations use the applicable newer version.
This means changing a mapping does not silently reprocess every past transaction into a different access history. Existing purchases may reflect the rule change on their next new authoritative observation. Validate migration behavior with a representative sandbox customer before broad catalog changes.
Inspect and troubleshoot
Access-level details show mapped products and customer grant rows. A mapping can exist while no customer currently has active access. Inspect the customer's current access, transaction expiry/revocation, product ID, app scope, and ownership.
Use Customers to trace a specific case. Use the runtime API reference for access-level creation, display-name updates, archival, and mapping changes available to trusted server integrations. Archival preserves historical/replay records; it is not a deletion of evidence.