Migration from RevenueCat
A migration from RevenueCat has eight steps. A coding agent does most of the work: it runs the migrations through the Adapty CLI and replaces the RevenueCat SDK in your app. You handle what the agent can’t reach — the secrets, and the settings in RevenueCat, App Store Connect, and Google Cloud.
- Learn the core differences.
- Move your catalog to Adapty.
- Move your paywall designs, if your offerings become flows.
- Replace the RevenueCat SDK with your coding agent.
- Move your integrations.
- Forward store events to Adapty.
- Test and release a new version of your app.
- (Optional) Import your transaction history.
Your subscribers will migrate automatically
All users who have ever activated a subscription will instantly move to Adapty as soon as they open a new version of your app with Adapty SDK. The subscription status validation and premium access will be restored automatically.
Before you push a new version of your app with Adapty SDK, make sure to check our release сhecklist.
Learn the core differences
Adapty and RevenueCat SDKs are similarly designed. The biggest difference is the network usage and the speed: Adapty SDK is designed to provide you with information on demand as fast as possible when you ask for it. For example, when requesting a paywall, you get the remote config first to pre-build your onboarding or paywall and then request products in a dedicated request.
Naming is slightly different:
| RevenueCat | Adapty |
|---|---|
| Package | Product |
| Offering | Paywall |
| Paywall | Flow |
| Entitlement | Access level |
Adapty has a concept of placement. It’s a logical place inside your app where the user can make a purchase. In most cases, you have one or two placements:
- Onboarding (because 80% of all purchases take place there);
- General (you show it in settings or inside the app after the onboarding).
Move your catalog to Adapty
The catalog migration creates a new Adapty app from your RevenueCat project: access levels from entitlements, products from packages, and a placement with a paywall or a flow for each offering.
Before you start
- Use a coding agent that runs terminal commands, for example Claude Code, Codex, or Cursor.
- In the terminal your agent uses, install the Adapty CLI and log in.
- In RevenueCat, create a secret API key (v2) for the project you migrate.
- Check the stores. The migration covers App Store and Google Play apps only.
Create a RevenueCat secret API key
Adapty reads your RevenueCat catalog with a secret API key of the project you migrate. Secret keys in RevenueCat belong to one project, so create the key in that project.
- To open the key list, in the RevenueCat dashboard, open the project, then go to API keys.
- To create the key, click New secret API key.
- To set up the key, enter a name, for example
Adapty migration, and choose V2 in API version. - To let Adapty read the catalog, set Project configuration permissions to Read only. Adapty needs no other permissions.
- To create the key, click Generate, then copy it.
Use a secret API key, not a public one. A public app-specific key can’t read the project configuration.
When the migration asks for the key, paste it into the Adapty Dashboard page that opens.
Run the catalog migration
-
To start the migration, ask your agent:
Migrate my RevenueCat project to a new Adapty app called "Acme Fitness" with the Adapty CLI. -
To connect RevenueCat, paste the secret API key into the Adapty Dashboard page the agent opens. The key goes to Adapty directly and never passes through the agent or the CLI.
-
To choose what to migrate, tell the agent which RevenueCat apps belong together, usually one per platform of the same product. Together they become a single Adapty app.
-
To settle the mapping, answer the agent’s questions about the entities Adapty couldn’t map on its own. For each offering, choose what its placement holds: a paywall that your app draws itself, or a flow from the Flow & Paywall Builder. Adapty suggests a flow for offerings with a RevenueCat paywall.
WarningDecisions are final. When every entity has a decision, Adapty creates the catalog, and you can’t change the mapping after that.
Adapty creates access levels, products, paywalls and flows, and placements, in that order. If some of them fail, the agent tells you why. When every entity is in Adapty, the migration completes.
-
To let the new app validate purchases, connect it to the stores in the Adapty Dashboard: App Store and Google Play.
To run the migration without an agent, use the migration commands. adapty migrations status names the next action and the input it takes.
How RevenueCat entities map to Adapty
- An entitlement identifier becomes the access level ID, so
customerInfo.entitlements["premium"]becomesprofile.accessLevels["premium"]. - A product that grants no entitlement grants the
premiumaccess level. - An offering identifier becomes the placement ID.
- Offering metadata becomes the remote config of the paywall or the flow, up to 256 KB.
What the catalog migration leaves out
- Offerings without products.
- Products whose App Store product ID Adapty rejects, for example an ID with a colon or a space. The agent tells you which ones, and they need no decision.
- Apps in stores other than App Store and Google Play.
- Integrations: Move them separately.
Move your paywall designs
Each flow the catalog migration creates is published with an empty screen over the offering’s products. To rebuild your RevenueCat paywall designs in these flows, ask your agent:
Migrate my RevenueCat paywall designs to my Adapty app "Acme Fitness" with the Adapty CLI.
The agent rebuilds the flows one at a time and publishes each one after you approve it. It lists what to add yourself, such as videos and custom fonts. It reads the designs with your RevenueCat secret API key, so keep the key until the designs are moved.
Until its design is moved, a flow shows an empty screen. Don’t release an app version that shows such a flow.
Replace the RevenueCat SDK
A coding agent replaces the RevenueCat SDK with the Adapty SDK in your app code, using the IDs of the catalog the migration created. Each run migrates one codebase: for an app with separate iOS and Android projects, run it in each.
Before you start, commit or stash your changes in the app’s repository, so the migration stays one reviewable diff.
-
To start the code migration, open your agent in the root of the app’s repository and ask:
Migrate the app code in this repository from RevenueCat to Adapty with the Adapty CLI, for my Adapty app "Acme Fitness".If the agent asks you to restart it to load the Adapty skills, restart it and repeat the request.
-
If a flow’s design isn’t moved yet, tell the agent whether the app shows the flow or keeps its own paywall screen until then.
-
To finish the code migration, review the changes on the
adapty-migratebranch, then work throughADAPTY_SETUP.mdin the root of your project. It lists what the agent left to you.
Move your integrations
Your agent finds the analytics, attribution, and messaging tools in your app code and reports how to set each one up in Adapty. It changes no files. Ask:
Find the integrations in my app code to set up in my Adapty app "Acme Fitness", with the Adapty CLI.
If the repository has the code of only one platform, tell the agent where the other one is. Then set up the integrations as described in Migrate integrations to Adapty. Webhooks, Slack, and cloud storage exports aren’t in the app code: find them on the Integrations page in RevenueCat.
Forward store events to Adapty
The App Store and Google Play report renewals, cancellations, and refunds to your server through notifications, including the ones that happen outside your app. Two migrations connect Adapty to these notifications while RevenueCat keeps receiving every event, so both stay up to date while your users move to the new app version.
Start them after the catalog migration completes. Adapty takes the bundle ID and the package name from the RevenueCat apps you selected there.
Forward App Store events
Adapty receives the App Store notifications and forwards each one to RevenueCat.
Before you start, create an In-App Purchase key in App Store Connect, and note its Issuer ID and Key ID.
-
To start forwarding, ask your agent:
Forward App Store events for my Adapty app "Acme Fitness" to Adapty, and keep RevenueCat receiving them. -
To give Adapty access to App Store events, in the Adapty Dashboard page the agent opens, upload the
.p8file, and enter the Issuer ID and the Key ID. The key goes to Adapty directly and never passes through the agent or the CLI. -
To keep RevenueCat receiving App Store events, give the agent the RevenueCat notification URL. In RevenueCat, open your iOS app, then copy the Apple Server Notification URL from Apple Server to Server notification settings. It starts with
https://api.revenuecat.com/v1/incoming-webhooks/. -
To point the App Store at Adapty, in App Store Connect, open your app, then go to App Information > App Store Server Notifications. Set both Production Server URL and Sandbox Server URL to the Adapty URL the agent gives you, with Version 2 notifications. For details, see Enable App Store server notifications. Forwarding to RevenueCat is already on at this point, so no event is lost.
-
To check the connection, tell the agent the URLs are set. Adapty asks the App Store for a test notification and waits for it. If it doesn’t arrive, the agent tells you why.
Forward Google Play events
Google Play sends notifications to a Pub/Sub topic. Adapty subscribes to the topic RevenueCat already uses, as a second subscriber, so RevenueCat keeps receiving events.
Don’t change the topic in Google Play Console, and don’t follow the steps in Enable RTDN for this app. A new topic stops the notifications to RevenueCat.
-
To start forwarding, ask your agent:
Forward Google Play events for my Adapty app "Acme Fitness" to Adapty, and keep RevenueCat receiving them. -
To give Adapty access to the topic, create a JSON key for the service account RevenueCat uses. In the Google Cloud console, go to IAM & Admin > Service Accounts, open the account, usually
revenuecat-service-account, then go to Keys > Add key and choose JSON. A new key doesn’t affect RevenueCat. For details, see Google’s guide to creating a service account key. -
To upload the key, in the Adapty Dashboard page the agent opens, upload the file to Google Play service account key (JSON). The key goes to Adapty directly and never passes through the agent or the CLI.
-
To subscribe Adapty to the topic, give the agent its ID. In RevenueCat, open your Google Play app settings, then copy the Topic ID from Google developer notifications. Google Play Console shows the same value in Monetize > Monetization setup > Topic name.
Adapty subscribes to the topic, then publishes a test notification and waits for it. If it doesn’t arrive, the agent tells you why.
-
If the test fails on a permission, give the service account the Pub/Sub Editor role in the topic’s project, or the Pub/Sub Subscriber role on the topic and Pub/Sub Editor in the project of the key. Then ask the agent to check again.
Test and release a new version of your app
If you’re reading this, you’ve already:
- Moved your catalog to Adapty
- Moved your paywall designs, if you use flows
- Replaced the RevenueCat SDK with Adapty
- Worked through
ADAPTY_SETUP.mdfrom your coding agent - Set up your integrations in Adapty
- Forwarded App Store and Google Play events to Adapty
- Made a sandbox purchase
- Made a new app release
If you checked the points above, just make a test purchase in the Sandbox and then release the app.
Go through release checklist.
Make the final check using our list to validate the existing integration or add additional features such as attribution or analytics integrations.
(Optional) Import your transaction history
The import fills profiles and charts with the payment history of your users. It doesn’t affect anyone’s access.
Don’t rush the historical data import
You should wait for at least a week after the release with the SDK before doing historical data import. During that time we will get all the info about purchase prices from the SDK, so the data you import will be more relevant.
Two migrations import the history into the app your catalog migration created. Use a Cloud Export if your RevenueCat plan has one.
With a RevenueCat Cloud Export
RevenueCat delivers a daily export into a bucket Adapty prepares for your app, and Adapty imports every file it receives.
-
To start the import, ask your agent:
Import the RevenueCat transaction history into my Adapty app "Acme Fitness" with a Cloud Export. -
To connect the export, give the agent the External ID from RevenueCat. In RevenueCat, open the Scheduled Data Exports settings, choose IAM Role (ARN) as the credential type, and copy the External ID RevenueCat shows. The External ID isn’t a secret.
-
To finish the export settings, in RevenueCat, enter the bucket, region, and role ARN the agent gives you. Turn on Receive new and updated transactions only. Otherwise, RevenueCat exports the whole history every day, and Adapty imports every file.
RevenueCat can take up to 24 hours to deliver the first file, and Adapty looks for new files in the bucket every hour. The migration finishes on its own a week after Adapty imports the first file. The Customer User ID of each imported profile is rc_last_seen_app_user_id_alias.
Through support
Use this way if your RevenueCat plan has no Cloud Export: RevenueCat support sends you the export, and Adapty support imports it.
-
To start the import, ask your agent:
Import the RevenueCat transaction history into my Adapty app "Acme Fitness" through support. -
To request the export, send RevenueCat support the first of the two messages the agent gives you.
-
To import the export, forward the files RevenueCat sends to Adapty support with the second message. Attach the files exactly as RevenueCat sent them: opening, re-saving, or merging them changes the column format the import expects.
What the import brings over
The following data will imported to Adapty for every transaction:
| Parameter | Description |
|---|---|
| user_id | Customer User ID, the main identifier of your user in Adapty and your system. |
| apple_original_transaction_id | For subscription chains, this is the original transaction’s purchase date, linked by store_original_transaction_id. |
| google_product_id | The product ID in the Google Play Store. |
| google_purchase_token | A unique identifier provided by Google Play for each transaction, required for validation. |
| country | The country of the user. |
| created_at | The date and time of the user creation. |
| subscription_expiration_date | The date and time when the subscription expires. |
| The end user’s email. | |
| phone_number | The end user’s phone number. |
| idfa | The Identifier for Advertisers (IDFA), assigned by Apple to a user’s device. |
| idfv | The Identifier for Vendors (IDFV), a code assigned to all apps by one developer and shared across those apps on a device. |
| advertising_id | A unique identifier provided by the Android OS that advertisers may use for tracking. |
| attribution_channel | The marketing channel name. |
| attribution_campaign | The marketing campaign name. |
| attribution_ad_group | The attribution ad group. |
| attribution_ad_set | The attribution ad set. |
| attribution_creative | The attribution creative keyword. |
In addition, integration identifiers for the following integrations will be imported: Amplitude, Mixpanel, AppsFlyer, Adjust, and FacebookAds.
What doesn’t come across
- Every transaction is re-validated with the store during import, so rows the store no longer recognizes are dropped.
- Rows without a real store transaction ID — for example, RevenueCat promotional or manually granted entitlements — import as profiles without transactions. To restore such users’ access, grant them an access level with the server-side API.
- Refund and billing-issue history isn’t carried over verbatim: a refund keeps only its cancellation date, and a subscription’s billing-issue state is recorded as of the import, not with the historical dates.
FAQ
I successfully installed Adapty SDK and released a new app version with it. What will happen to my legacy subscribers who did not update to a version with Adapty SDK?
Most users charge their phones overnight, it’s when the App Store usually auto-updates all their apps, so it shouldn’t be a problem. There may still be a small number of paid subscribers who did not upgrade, but they will still have access to the premium content. You don’t need to worry about it and force them to update.
Do I need to export my historical data from RevenueCat as quickly as possible, or will I lose it?
You don’t need to make it super fast; make a release with Adapty SDK first, and then import your history. We will restore the history of your users’ payments and fill in profiles and charts.
I use MMP (AppsFlyer, Adjust, etc.) and analytics (Mixpanel, Amplitude, etc.). How do I make sure that everything will work?
You first need to pass us the IDs of such 3rd party services via our SDK that you want us to send data to. Read the guide for attribution integration and for analytics integration. For historical data and legacy users, make sure you pass us those IDs from the data you exported from RevenueCat.