Entitlements

Gate features on access levels instead of products, check them on device and server-side, and sync across platforms.

An entitlement is a level of access: pro, premium, gold. A product is a purchasable SKU: pro_monthly, pro_annual, lifetime. Products grant entitlements. Your app should always ask "is pro active?" rather than "did they buy pro_monthly?"

Check on device#

Read the entitlement off the cached snapshot. It reflects the latest purchase, renewal, refund and cross-device change:

swift
// Synchronous and offline-valid, so safe to read anywhere.
if CashSDK.shared.entitlements.isActive("pro") {
  unlockPro()
}

// Give customers a way to recover access on a new device or reinstall.
try await CashSDK.shared.restore()
kotlin
if (CashSDK.shared.entitlements.isActive("pro")) {
  unlockPro()
}

CashSDK.shared.restore()

Check server-side#

Never trust the client for anything that unlocks paid value on your backend. Ask CashSDK for the customer's live entitlements:

bash
curl https://api.cashsdk.com/v1/apps/{app}/customers/u_812 \
  -H "Authorization: Bearer csk_sk_..."
json
{
  "app_user_id": "u_812",
  "entitlements": {
    "pro": {
      "active": true,
      "product_id": "pro_annual",
      "expires_at": "2027-01-04T00:00:00Z",
      "store": "app_store"
    }
  }
}

A client-reported isActive is great for UI, but authorize sensitive actions (server-rendered content, API access, cloud features) against the API or a verified webhook. See receipt validation.

Cross-platform sync#

Entitlements follow the customer, not the device. Call identify(userId:userToken:) with your own stable user id and CashSDK unifies purchases made on iOS, Android, and Web under one customer. A subscription bought on an iPhone unlocks pro on the same account's Android tablet and your web app automatically.

swift
CashSDK.shared.identify(userId: "8841", userToken: tokenFromYourBackend)

Grant entitlements manually#

For support credits, promos, giveaways, or comping a beta tester, grant an entitlement directly, with no purchase required. Use the dashboard, or the MCP server's grant_entitlement tool:

text
grant_entitlement(app_user_id="u_812", entitlement="pro", duration="30d")

Next steps#