Feature

Offline entitlements: keep paying customers' access when your purchase server is down

Paying customers keep their access when RevenueDot is down. The RevenueCat SDKs cache a product-to-entitlement mapping from your server and, when it answers with a 5xx, work out the customer's entitlements on the device from the store's own record of their purchases. RevenueDot serves the mapping for each app and answers 5xx, never 4xx, for its own failures.

Free up to $10,000 a month in tracked revenue. Works with the RevenueCat SDK you already ship.

No extra setup

The SDK fetches and caches the mapping by itself and refreshes it when the copy is 25 hours old.

Per app and store

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

5xx, never 4xx

RevenueDot answers 5xx for its own failures and store outages, so the SDK's offline path runs when it should.

Syncs when you are back

The purchase stays unfinished, so the SDK posts it again once the server is up.

How do offline entitlements work?

  1. 01

    The SDK fetches the mapping

    It calls GET /v1/product_entitlement_mapping and caches the answer, refreshing it when the copy is 25 hours old.

  2. 02

    The server fails

    GET /v1/subscribers/{app_user_id} or POST /v1/receipts answers 5xx and no customer info is cached.

  3. 03

    The SDK computes entitlements on the device

    It reads the active purchases from StoreKit or Google Play and looks each product up in the mapping.

  4. 04

    The result is not cached

    The result is marked as verified on the device. The purchase stays unfinished, so the SDK posts it again once the server is back.

What does the mapping contain for each store?

Google Play's bare key carries the entitlements of every base plan of the subscription, because Android's purchase record names the subscription but not the base plan. Nobody who paid loses access, and a customer on a cheaper base plan may see the richer plan's entitlements for at most a day, only while the server is down. Archived products still map. Consumables are left out.

StoreProduct in RevenueDotKeys in the mapping
App Storepro_monthlypro_monthly
App Store, iOS 26.4 billing planpro_annual:monthlypro_annual:monthly
App Store, up-front billing planpro_annual:upFrontpro_annual
Google Playpro:monthly and pro:annualpro:monthly, pro:annual and pro
Google Play, product without a base planlegacy_prolegacy_pro

How do you read the mapping for an app?

A secret key with no X-Platform header gets the whole project's mapping.

Product-to-entitlement mappingcurl
curl -s https://api.revenuedot.app/v1/product_entitlement_mapping \
  -H "Authorization: Bearer $GOOGLE_APP_KEY"

# {"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"]}}}

When do offline entitlements not apply?

These limits are the SDKs' own, not RevenueDot's.

  • The app completes purchases itself (observer mode, purchasesAreCompletedBy = .myApp).
  • The Test Store, and iOS before version 15.
  • A pending consumable on iOS, or any active one-time purchase on Android, where the SDK returns an error instead.
  • A network error with no answer at all. Only a 5xx counts as the server being down.

FAQ

Offline entitlements: questions people ask

What happens to my subscribers' access if my purchase server goes down?

Paying customers keep access. When the server answers 5xx, the RevenueCat SDK reads the customer's active purchases from StoreKit or Google Play and maps each product to entitlements with a mapping it cached from RevenueDot. Access is computed on the device until the server is back.

Do I need to change my app code for offline entitlements?

No. It is a feature of the RevenueCat SDKs and needs only the normal setup. RevenueDot serves the mapping at GET /v1/product_entitlement_mapping for each app, and the SDK fetches and refreshes it by itself.

Why does RevenueDot answer 5xx and not 4xx when it fails?

A 4xx tells the SDK the purchase can never be accepted, so it finishes the transaction. A 5xx tells it to try again later and to use the offline mapping. RevenueDot answers 5xx for its own failures and store outages so purchases are not dropped.

Does offline entitlement work with the Test Store or observer mode?

No. The SDK does not use it in observer mode, with the Test Store or on iOS before version 15. A pending consumable on iOS and any active one-time purchase on Android also return an error instead.

Get started

Run subscriptions without the revenue share.

Start free on RevenueDot Cloud, free up to $10,000 a month in tracked revenue, or move an existing RevenueCat app with one line of code.

Already have an account? Sign in · Prefer your own servers? Self-host free