Skip to main content

Importing your Historical Purchases

Choosing Your Import Path

Importing existing purchase data to RevenueCat can be done server-side, or client-side. A server side migration is preferable whenever possible because it ensures that all subscriptions will be recorded in RevenueCat regardless of any in-app activity.

Do you have all of the raw base64 Apple receipts, StoreKit 2 signed transactions and/or Google / Amazon purchase tokens saved in your database?

Yes Server-side data import →

No Client-side data import →

Server Side Data Import

A server side import involves sending all of the Apple receipts and/or purchase tokens to RevenueCat via the POST /receipts REST API endpoint. This will create the customer in RevenueCat, RevenueCat will validate the receipt and keep the subscription up-to-date. Ideally, you set up forwarding of new receipts/tokens first before sending any historic ones. RevenueCat will automatically deduplicate them.

This is the quickest way to get your existing subscribers into RevenueCat. See the API reference for more details.

Afterwards, the purchase data will be up to date in charts, customer lists, REST API etc., and if any of your customers open the version of the app containing the RevenueCat SDK their subscription status will automatically be synced.

📘Bulk imports available for very large volumes of historical data

If you are aiming to import very large volumes of historical data, please contact RevenueCat support to start a bulk data import process.

⚠️Limited historical data for Google Play purchases

Google Play receipts that have been expired for more than 90 days ago can't be imported, and only the current status can be retrieved from each receipt. This means that historical data won't be presented accurately in Charts. To fill the gaps in historical data, you can use Google Historical Imports.

Client-side (SDK) Data Import

A client-side data migration is a technique to sync existing purchases with RevenueCat when the app is first launched. It requires integrating the RevenueCat SDK in your app.

The RevenueCat SDK will automatically detect new transactions and sends them to RevenueCat. However, when migrating from an older system, you need to tell the RevenueCat SDK to sync to ensure we are tracking your subscribers correctly. Keep in mind that with a client-side migration RevenueCat will only ever "see" customers that open the latest version of the app containing RevenueCat and sync their purchases.

The way to do this is: if your existing in-app purchase code knows that the customer has pre-existing purchases, but RevenueCat does not, then programmatically sync purchases.

See the following pseudo example.

const isSubscribedInOldSystem = oldTracking.isSubscribed()
const isSubscribedInRevenueCat = !customerInfo.entitlements.active.isEmpty

// If the old system says we have a subscription, but RevenueCat does not
if (isSubscribedInOldSystem && !isSubscribedInRevenueCat)
{
// Tell Purchases to syncPurchases.
// This will sync the user's receipt with RevenueCat.
Purchases.shared.syncPurchases { (customerInfo, error) in }
}

When a customer launches with the first version containing RevenueCat it will trigger a sync. Once the sync is complete, it won't be triggered again.

⚠️Do not sync or restore on every app launch

It's okay to trigger a sync once per subscriber programmatically the first time they open a version of your app containing RevenueCat. You should not call this programmatically on every app launch for every user. This can increase latency in your app and can unintentionally alias customers together.