What happens to my customers' access when RevenueDot is down?

Paying customers keep their access. The RevenueCat SDKs cache a product-to-entitlement mapping from your server and, when the server answers with a 5xx, compute the customer's entitlements on the device from the store's own record of their purchases. This is the SDKs' "offline entitlements" feature, described in RevenueCat's customer info docs. It needs nothing from you beyond the normal setup.

How it works#

  1. The SDK fetches GET /v1/product_entitlement_mapping and caches it. It refreshes it when the copy is 25 hours old.
  2. When GET /v1/subscribers/{app_user_id} or POST /v1/receipts answers 5xx and no customer info is cached, the SDK reads the active purchases from StoreKit or Google Play and looks each product up in the mapping.
  3. The result is marked as verified on the device and is not cached. The purchase stays unfinished, so the SDK posts it again once the server is back.

RevenueDot answers 5xx for its own failures and for store outages, never 4xx, so this path is always taken when it should be. See 4xx vs 5xx on receipts.

What the mapping contains#

Each app key gets its own app's products, keyed the way that app's SDK looks them up:

Store Product in RevenueDot Keys in the mapping
App Store pro_monthly pro_monthly
App Store, iOS 26.4 billing plan pro_annual:monthly pro_annual:monthly (base plan monthly)
App Store, up-front billing plan pro_annual:upFront pro_annual
Google Play pro:monthly and pro:annual pro:monthly, pro:annual, and pro
Google Play, product without a base plan legacy_pro legacy_pro
  • Google Play's bare key (pro above) carries the entitlements of every base plan of the subscription. Android's purchase record names the subscription but not the base plan, so the SDK can only look up pro. With the union, nobody who paid loses access; a customer on a cheaper base plan may see the richer plan's entitlements for at most a day, and only while the server is down. RevenueCat's sample mapping uses the first base plan's entitlements instead.
  • Archived products still map, so earlier buyers keep access. Archived entitlements unlock nothing, online or offline.
  • Consumables are left out: they never unlock an entitlement.
Shell
curl -s https://api.revenuedot.app/v1/product_entitlement_mapping -H "Authorization: Bearer $GOOGLE_APP_KEY"
JSON
{
  "product_entitlement_mapping": {
    "pro:monthly": { "product_identifier": "pro", "base_plan_id": "monthly", "entitlements": ["pro"] },
    "pro:annual": { "product_identifier": "pro", "base_plan_id": "annual", "entitlements": ["pro", "cloud_sync"] },
    "pro": { "product_identifier": "pro", "base_plan_id": "monthly", "entitlements": ["pro", "cloud_sync"] }
  }
}

A secret key with no X-Platform header gets the whole project. Reference: SDK endpoints.

When offline entitlements do not apply#

These limits are the SDKs' own:

  • The app completes purchases itself (observer mode, purchasesAreCompletedBy = .myApp).
  • The Test Store, and iOS before 15.
  • A pending consumable on iOS, or any active one-time purchase on Android: the SDK returns an error instead.
  • A network error with no answer at all. Only a 5xx counts as "server down".
Edit this page on GitHub ↗ View as Markdown Last updated