syncPurchases() in RevenueCat: When and How to Use It
Overview
syncPurchases() is the RevenueCat method that makes RevenueCat aware of purchases it
did not process itself. It reads the current purchase state from the store
(App Store or Google Play) and syncs it to the user's RevenueCat record, returning an updated
CustomerInfo.
The short answer most people are looking for: in a standard RevenueCat integration you almost never
call syncPurchases() yourself. The SDK already syncs purchases automatically. The method
exists mainly for observer mode, where another in-app purchase library makes the
purchase and RevenueCat only observes (it does not make the purchase). In that setup you call
syncPurchases() so RevenueCat learns about purchases it did not handle.
syncPurchases(). If another library makes the purchases (observer mode), call it after
that library completes a transaction.
Purchases.configure(...). See the React Native codelab
and the Configure the SDK guide for setup.
What syncPurchases Does
When you call syncPurchases(), the SDK collects the purchase information available from
the underlying store and posts it to RevenueCat's backend. RevenueCat then re-evaluates the user's
entitlements and returns a fresh CustomerInfo that reflects any purchases it just learned
about.
- It informs RevenueCat of purchases that another SDK or process completed.
- It returns an updated
CustomerInfoso you can read the user's current entitlements. - It is not user-facing: there is no button or user gesture tied to it.
- It does not perform the account-transfer logic that
restorePurchases()does.
In a normal RevenueCat integration, the SDK already detects and syncs purchases automatically, so the
updated CustomerInfo flows to you without an explicit call. That is why this method is so
rarely needed outside observer mode.
syncPurchases vs restorePurchases
These two methods are frequently confused because both end up updating CustomerInfo, but
they serve different roles. restorePurchases() is the user-initiated
action you tie to a "Restore Purchases" button; syncPurchases() is a
background sync used mostly in observer mode.
| Aspect | syncPurchases() |
restorePurchases() |
|---|---|---|
| Who triggers it | Automatic / observer mode (no button) | The user, via a "Restore Purchases" button |
| Purpose | Tell RevenueCat about purchases it did not process | Let a user recover purchases on a new install or device |
| Account transfer | No (does not transfer entitlements between accounts) | Yes (can transfer entitlements between accounts) |
| App Store requirement | Not a user-facing feature, not required | A "Restore Purchases" action is required by App Store guidelines |
If you are looking for the button users tap to recover their subscriptions, you want
restorePurchases(), not syncPurchases(). See the platform restore guides:
React Native,
iOS, and
Android.
Observer Mode (The Main Use Case)
Observer mode is the one setup where syncPurchases() is genuinely needed. In observer
mode, RevenueCat does not make purchases. Another in-app purchase library (your own
billing code, or a different SDK) completes the transaction, and RevenueCat simply observes to power
its analytics, charts, and integrations.
Because RevenueCat is not the one finishing the transaction, it will not automatically know about the
purchase. After the other library reports a successful purchase, you call syncPurchases()
so RevenueCat reads the store state and records the purchase against the current user.
syncPurchases(), (4) RevenueCat picks up the
purchase and returns an updated CustomerInfo you can use to unlock content.
See the official RevenueCat docs for how to enable observer mode at configuration time on each platform.
Code Per Platform
The examples below show how to call syncPurchases() on each platform. Call these only in
observer mode, after the other purchase library has completed a transaction.
React Native
import Purchases, { CustomerInfo } from 'react-native-purchases';
// Observer mode: call this AFTER your other IAP library completes a purchase.
async function syncAfterExternalPurchase(): Promise<void> {
try {
const customerInfo: CustomerInfo = await Purchases.syncPurchases();
const isPro = typeof customerInfo.entitlements.active['premium'] !== 'undefined';
console.log('Synced purchases. Pro active?', isPro);
} catch (e) {
console.error('syncPurchases failed', e);
}
}
iOS (Swift)
import RevenueCat
// Observer mode: call this AFTER your other IAP code finishes a transaction.
func syncAfterExternalPurchase() async {
do {
let customerInfo = try await Purchases.shared.syncPurchases()
let isPro = customerInfo.entitlements["premium"]?.isActive == true
print("Synced purchases. Pro active? \(isPro)")
} catch {
print("syncPurchases failed: \(error)")
}
}
Android (Kotlin, coroutines)
// Observer mode: call this AFTER your other IAP library completes a purchase.
viewModelScope.launch {
try {
val customerInfo = Purchases.sharedInstance.awaitSyncPurchases()
val isPro = customerInfo.entitlements["premium"]?.isActive == true
Log.d("Purchases", "Synced purchases. Pro active? $isPro")
} catch (e: PurchasesException) {
Log.e("Purchases", "syncPurchases failed: ${e.message}")
}
}
Android (Kotlin, callback)
Purchases.sharedInstance.syncPurchases(
object : SyncPurchasesCallback {
override fun onSuccess(customerInfo: CustomerInfo) {
val isPro = customerInfo.entitlements["premium"]?.isActive == true
Log.d("Purchases", "Synced purchases. Pro active? $isPro")
}
override fun onError(error: PurchasesError) {
Log.e("Purchases", "syncPurchases failed: ${error.message}")
}
}
)
When NOT to Call syncPurchases()
purchase(...) or the paywall), the SDK syncs automatically. Calling
syncPurchases() yourself is redundant and adds unnecessary network requests.
restorePurchases() is for. restorePurchases() is user-initiated, can transfer
entitlements between accounts, and satisfies App Store requirements. syncPurchases() does
not transfer accounts and is not a user-facing feature.
FAQ
What does syncPurchases() do?
It tells RevenueCat about purchases it did not process itself, reads the store's purchase state, syncs
it to the user's RevenueCat record, and returns an updated CustomerInfo. In a normal
integration the SDK does this automatically, so you rarely call it.
What is the difference between syncPurchases() and restorePurchases()?
restorePurchases() is the user-initiated action behind a "Restore Purchases" button; it
can transfer entitlements between accounts and is required by the App Store.
syncPurchases() is not user-facing, needs no button, does not transfer accounts, and is
used mostly in observer mode to inform RevenueCat of purchases made by another SDK.
When should I call syncPurchases()?
In observer mode, right after another in-app purchase library completes a transaction, so RevenueCat
can pick it up. In a standard integration you normally never call it.
Do I need to call it after every purchase?
No. In a normal integration the SDK syncs automatically. Only call it in observer mode after the other
purchase library finishes a transaction.
Related Guides
- Restore Purchases on React Native the user-facing restore action
- Restore Purchases on iOS (Swift) the iOS restore flow
- Restore Purchases on Android (Kotlin) the Android restore flow
- Get CustomerInfo & Refresh the Cache read entitlements after a sync
- Configure the RevenueCat SDK apiKey and appUserID setup (including observer mode)
- React Native In-App Purchases Tutorial full end-to-end integration
- RevenueCat Docs official reference