---
id: "integrations/attribution/meta-ads"
title: "Meta Ads"
description: "With our Meta Ads (formerly Facebook Ads) integration, you can:"
permalink: "/docs/integrations/attribution/meta-ads"
slug: "meta-ads"
version: "current"
original_source: "docs/integrations/attribution/meta-ads.mdx"
---

> **AI agents:** This is the Markdown version of a RevenueCat documentation page. For the complete documentation index, see [llms.txt](https://www.revenuecat.com/docs/llms.txt).

With our Meta Ads (formerly Facebook Ads) integration, you can:

- Accurately track subscriptions generated from Meta Ads campaigns, so you know precisely how much revenue your campaigns generate.
- Send trial starts, trial conversions, and renewals directly from RevenueCat to Meta Ads Manager for accurate tracking without an open app.
- Continue to follow your cohorts for months to know the long-tail revenue generated by your campaigns.

### Integration at a glance

| Revenue support | Supports Negative Revenue |               Sends Sandbox Events               | Includes Customer Attributes | Sends Transfer Events |       Optional Event Types       |
| :-------------: | :-----------------------: | :----------------------------------------------: | :--------------------------: | :-------------------: | :------------------------------: |
|       ✅        |            ❌             | Requires Sandbox Client Token and Sandbox App ID |        Matching only         |          ❌           | [Funnel Events](#funnels-events) |

For a cross-provider view of identifiers, revenue support, sandbox behavior, and attribution responsibilities, see the [attribution provider comparison](https://www.revenuecat.com/docs/integrations/attribution/provider-comparison).

## Before you begin

Review [Getting Started with Attribution Integrations](https://www.revenuecat.com/docs/integrations/attribution/getting-started) for how attribution integrations fit together, then use the [setup checklist](https://www.revenuecat.com/docs/integrations/attribution/setup-checklist) as a reference for required lifecycle events, reporting choices, duplicate-event risks, and testing checks.

The following considerations are specific to Meta Ads:

- This page covers sending subscription and funnel events to Meta Ads. If you're tracking ad monetization revenue from Meta Audience Network or another ad network, use the [ad monetization docs](https://www.revenuecat.com/docs/ad-monetization) instead.
- Keep the Meta SDK installed and initialized for install, activation, and on-device signals. RevenueCat sends subscription events server-to-server, but it doesn't replace Meta's SDK setup for install campaigns, SKAdNetwork (SKAN), or Aggregated Event Measurement (AEM).
- Turn off Meta SDK purchase or revenue tracking for the same subscription events RevenueCat sends, unless you intentionally manage deduplication in Meta.
- For iOS app promotion campaigns, confirm whether your campaign uses SKAN, AEM, or both. RevenueCat doesn't configure SKAN or AEM, and it doesn't update SKAN conversion values. If your app updates SKAN values directly, use one updater, such as your app, the Meta SDK, or a mobile measurement partner (MMP), so conversion values don't conflict.
- A successful RevenueCat delivery means Meta accepted the event from RevenueCat. Meta can still decide that the event isn't eligible for a campaign, optimization goal, or report.
- You can use RevenueCat alongside a mobile measurement partner (MMP) for Meta campaigns. The MMP can provide final source and campaign values to your app. Your app can store those values in RevenueCat using reserved attribution attributes such as `$mediaSource` and `$campaign`. Meta still matches and attributes RevenueCat-delivered events inside Meta using Meta's event data, identifiers, campaign setup, and reporting rules.
- If your app collects an email address or phone number, set `$email` and `$phoneNumber` in RevenueCat before the first purchase when privacy rules allow. RevenueCat hashes and forwards these values to Meta, where they can materially improve event match quality, especially when advertising identifiers (such as IDFA) are unavailable.

## 1. Install Meta SDK

Before RevenueCat can integrate with Meta, your app must be running the Meta SDK. Refer to the [Meta developer documentation](https://developers.facebook.com/docs/) for the latest installation instructions.

### Keep install and usage events on-device

RevenueCat sends subscription lifecycle and revenue events to Meta server-to-server. To continue sending install and app activation signals from the device, disable Meta SDK purchase tracking and manually call Meta's `activateApp()` event after configuration:

```swift
import FBSDKCoreKit // Provides Settings and AppEvents

// disable automatic tracking
Settings.shared.isAutoLogAppEventsEnabled = false

// optional: call activateApp
AppEvents.shared.activateApp()
```

See Meta's [App Events Reference](https://developers.facebook.com/docs/app-events/reference) for more details.

::::caution\[Avoid duplicate purchase events]
Remove client-side purchase and revenue tracking for the same events RevenueCat sends to Meta. Meta requires deduplication when the same app event is sent from multiple sources, such as the SDK, Conversions API, an MMP, or App Events API. The Meta SDK and RevenueCat don't coordinate a shared `event_id`, so sending the same purchase from both paths can double count revenue or affect Meta's conversion reporting and campaign performance.
::::

You can disable automatic In-App Purchase event logging from the Meta SDK or from your Meta app dashboard. Go to the iOS or Android card under **Settings > Platform > Log In-App Events Automatically**, then select **No**.

## 2. Send attribution data to RevenueCat

Meta matches RevenueCat events to users and campaigns using device identifiers, the Facebook anonymous ID, and any additional matching attributes that are present when RevenueCat processes the event.

| Key            | Description                                                                                                                                     | Platform |
| :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :------- |
| `$idfa`        | iOS [advertising identifier](https://developer.apple.com/documentation/adsupport/asidentifiermanager/1614151-advertisingidentifier) UUID        | iOS      |
| `$gpsAdId`     | Google [advertising identifier](https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info) | Android  |
| `$fbAnonId`    | Facebook anonymous identifier                                                                                                                   | iOS      |
| `$idfv`        | iOS [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor) UUID                              | iOS      |
| `$ip`          | The IP address of the device                                                                                                                    | Any      |
| `$email`       | The email address of the user                                                                                                                   | Any      |
| `$phoneNumber` | The phone number of the user                                                                                                                    | Any      |

### Required attributes for event delivery

For RevenueCat to attempt delivery to Meta, the associated customer must have specific attributes set at the time the event is processed. These requirements differ based on which Meta integration path you're using and which platform the event originates from.

::::caution\[Use real advertising identifiers]
We treat empty or zeroed `$idfa` or `$gpsAdId` values as missing. They don't represent a real device advertising ID, so they won't help Meta match the event. Use another required identifier, such as `$fbAnonId` where supported, and follow the App Tracking Transparency (ATT) and consent guidance below.
::::

#### App Events API

| Platform   | Required Attributes                                                                                              |
| :--------- | :--------------------------------------------------------------------------------------------------------------- |
| App Store  | ✅ $fbAnonId or $idfa<br>✅ $attConsentStatus == authorized |
| Play Store | ✅ $fbAnonId or $gpsAdId                                                               |

#### Conversions API

| Platform   | Required Attributes                                                                                                                                                                                                |
| :--------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| App Store  | ✅ $fbAnonId or $idfa<br>✅ $attConsentStatus == authorized (or the dashboard setting Send events when ATT consent is not authorized is enabled) |
| Play Store | ✅ $fbAnonId or $gpsAdId                                                                                                                                                                 |

### Setting device attributes

These attributes can be set manually, like any other [Customer Attributes](https://www.revenuecat.com/docs/customers/customer-attributes), or through the helper methods `collectDeviceIdentifiers()` and `setFBAnonymousID()`. Set them after the RevenueCat SDK is configured and before the first purchase occurs whenever possible.

The examples below show the recommended app-side flow:

1. Configure the RevenueCat SDK.
2. Collect device identifiers.
3. Set the Facebook anonymous ID (`$fbAnonId`) in RevenueCat.
4. Set optional matching attributes, such as `$email` or `$phoneNumber`, when available and privacy-compliant.
5. Collect device identifiers again if a new value becomes available, such as after ATT permission is granted.

#### iOS

- Call `collectDeviceIdentifiers()` after configuring RevenueCat, even if
  ATT is still `.notDetermined`. RevenueCat can collect values such as the
  Identifier for Vendor (IDFV) and IP address, and won't save an invalid
  IDFA.
- If the customer later accepts ATT permission, call
  `collectDeviceIdentifiers()` again to update the `$idfa` attribute in
  RevenueCat.
- The AdSupport framework is required to access the IDFA parameter. In
  Xcode, add `AdSupport.framework` to your app target under **Frameworks,
  Libraries, and Embedded Content**, leave it set to **Do Not Embed**, then
  import `AdSupport` in your Swift file.

#### Android

- RevenueCat's current Android SDKs don't collect Android ID. Google's
  Advertising ID (`$gpsAdId`) is the primary Android device identifier
  RevenueCat uses for third-party integrations.

```swift
import FBSDKCoreKit // Provides AppEvents
import RevenueCat
import AdSupport // Required for IDFA collection

// ...
Purchases.configure(withAPIKey: "public_sdk_key")
// ...

// Automatically collect the $idfa, $idfv, and $ip values
Purchases.shared.attribution.collectDeviceIdentifiers()

// REQUIRED: Set the Facebook anonymous ID
Purchases.shared.attribution.setFBAnonymousID(AppEvents.shared.anonymousID)

// Optionally set additional user data
Purchases.shared.attribution.setEmail("test@example.com")
Purchases.shared.attribution.setPhoneNumber("+16505551234")
```

```dart
// NOTE: There is no official Facebook Ads plugin for Flutter.

// NOTE: You can find a community-supported alternative for the SDK here: https://github.com/oddbit/flutter_facebook_app_events

// Automatically collect the device and advertising identifiers
await Purchases.collectDeviceIdentifiers();

// Set the Facebook anonymous ID
await Purchases.setFBAnonymousID(facebookAnonymousId);
```

```kotlin
//..
Purchases.configure(this, "public_sdk_key")
//..
  
// Automatically collect the $gpsAdId and $ip values
Purchases.sharedInstance.collectDeviceIdentifiers()

// Set the Facebook anonymous ID
Purchases.sharedInstance.setFBAnonymousID(facebookAnonymousId)

// Optionally set additional user data
Purchases.sharedInstance.setEmail("test@example.com")
Purchases.sharedInstance.setPhoneNumber("+16505551234")
```

```jsx
// NOTE: Facebook has officially ended support for their React Native SDK. You can read more about this here: https://developers.facebook.com/blog/post/2021/01/19/introducing-facebook-platform-sdk-version-9/

// NOTE: You can find a community-supported alternative for the SDK here: https://github.com/facebookarchive/react-native-fbsdk

// The following docs are left in place for reference

import FBSDK from "react-native-fbsdk";
import Purchases from "react-native-purchases";

//...
Purchases.setLogLevel(Purchases.LOG_LEVEL.DEBUG);
Purchases.configure({ apiKey: <public_sdk_key> });
//...

// Automatically collect the $idfa, $idfv, and $ip values
Purchases.collectDeviceIdentifiers();

// REQUIRED: Set the Facebook anonymous ID
const anonymousId = await FBSDK.AppEventsLogger.getAnonymousID();
Purchases.setFBAnonymousID(anonymousId);

// Optionally set additional user data
Purchases.setEmail("test@example.com");
Purchases.setPhoneNumber("+16505551234");
```

If you set identifiers after configuring Purchases and before a purchase occurs, RevenueCat syncs them with the purchase event. You usually don't need to call `syncAttributesAndOfferingsIfNeeded()` for Meta. Reserve explicit syncs for cases where newly set attributes must affect [Targeting](https://www.revenuecat.com/docs/tools/targeting/custom-attributes) or where you need to avoid a race with server-side purchase tracking; if you use it for that race, await it before continuing to purchase. Avoid frequent calls because this SDK method is limited to 5 calls per minute per running app instance.

## 3. Send RevenueCat events into Meta Ads Manager

After you've set up the RevenueCat SDK to send attribution data to RevenueCat, enable the integration and configure Meta credentials from the RevenueCat dashboard. At this point, choose which Meta integration path RevenueCat should use to send events: Conversions API or App Events API.

1. Go to your dashboard and select your project.
2. In the lower-left corner, select **Integrations**.
3. Select **Meta Ads**.

Next, follow the setup path for the API you want RevenueCat to use.

### Integrating with the Conversions API

We recommend integrating with the Conversions API (CAPI) for better reliability and long-term support. CAPI can send subscription lifecycle events, such as trial conversions and renewals, even when the app isn't open. The Meta SDK can provide richer on-device context for app-open events, but it can't reliably report later subscription events that happen while the app is closed.

1. Select the **Conversions API** integration type.
2. Add your Dataset ID for production events.

   CAPI can support iOS App Events datasets and isn't limited to web Pixels. The Dataset ID doesn't need to match your Meta App ID, but the dataset must be linked to the Meta app.
3. (Optional) To let RevenueCat send sandbox events to Meta, add a Sandbox Dataset ID.
4. Add the Conversions API Token for your app.

   You can find your token in Meta Events Manager under the selected dataset's **Settings → Generate Access Token** section. Make sure the token is valid for the dataset and Meta setup you're using.
5. If you configured a sandbox dataset, add the Sandbox Conversions API Token.
6. Decide whether RevenueCat should send App Store events when ATT consent isn't authorized. [Learn more](https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/app-data).
   - Enable `Send events when ATT consent is not authorized` to allow those events to be sent to Meta.
   - Leave it disabled to require authorized ATT consent before App Store events are sent.
7. Configure Meta event names if you want to override the defaults in [Event names](#event-names).
8. Select whether you want sales reported as gross revenue (before app store commission), or after store commission and/or estimated taxes. This setting changes the revenue value RevenueCat sends to Meta, so use the same reporting mode when comparing Meta-side return on ad spend (ROAS) to RevenueCat revenue metrics. Learn more about [taxes and commissions](https://www.revenuecat.com/docs/dashboard-and-metrics/taxes-and-commissions).

### Integrating with the App Events API

If you choose to integrate with the App Events API, follow these steps:

1. Select the **App Events API** integration type.
2. Add your Meta App ID for production events.
3. (Optional) To let RevenueCat send sandbox events to Meta, add a Sandbox App ID.
4. Add the Meta Client Token for your app.

   You can find your Client Token in the Meta dashboard under **App → Settings → Advanced → Client Token**. You may need to click **Reset** if there's no Client Token visible.
5. If you configured a Sandbox App ID, add the Sandbox Client Token.
6. Configure Meta event names if you want to override the defaults in [Event names](#event-names).
7. Select whether you want sales reported as gross revenue (before app store commission), or after store commission and/or estimated taxes. This setting changes the revenue value RevenueCat sends to Meta, so use the same reporting mode when comparing Meta-side revenue to RevenueCat revenue metrics.

### Event names

RevenueCat sends the core subscription lifecycle events described in the [setup checklist](https://www.revenuecat.com/docs/integrations/attribution/setup-checklist#configure-provider-communication). You can choose from different Meta standard event names for these events. Using standard events is recommended by Meta for optimizing advertising campaigns and audiences.

| RevenueCat Event      | Default Meta Event     |
| :-------------------- | :--------------------- |
| Trial Started         | StartTrial             |
| Trial Converted       | Subscribe              |
| Initial Purchase      | Subscribe              |
| Renewal               | Subscribe              |
| Non-Renewing Purchase | fb\_mobile\_purchase     |

### Funnels events

You can also enable Funnels events to be tracked in Meta. These events are triggered when a customer takes the corresponding action in any of your funnels and are sent to Meta as **custom events** for your own analytics. Meta doesn't use Funnels events for ad attribution or campaign optimization; only the standard subscription events in the table above are used for that. To learn more about Funnels, check out our [Funnels documentation](https://www.revenuecat.com/docs/tools/funnels).

| Event                            | Default Event Name                           | Description                                                                                                                                          |
| -------------------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Workflow step started            | `rc_workflows_step_started_event`            | A workflow step started and was displayed to a customer.                                                                                             |
| Workflow step completed          | `rc_workflows_step_completed_event`          | A customer completed a workflow step by clicking a button or exiting.                                                                                |
| Workflow non-checkout completion | `rc_workflows_non_checkout_completion_event` | A customer ended the workflow through a configured exit without a purchase.                                                                          |
| Workflow purchase                | `rc_workflows_purchase_event`                | A purchase was made through a workflow. This event is separate from a purchase made in your app, and helps you track the performance of your funnel. |

## 4. Test the Meta Ads Manager integration

Before rolling out the integration, test with a new customer after the app-side setup, customer attributes, and dashboard settings are configured. To test sandbox purchases, make sure the matching sandbox credentials are already configured in RevenueCat: a Sandbox Dataset ID and Sandbox Conversions API Token for Conversions API (CAPI), or a Sandbox App ID and Sandbox Client Token for App Events API.

1. Make a sandbox purchase with a new customer.
2. In the RevenueCat [Customer Profile](https://www.revenuecat.com/docs/dashboard-and-metrics/customer-profile#customer-details), confirm the required attributes from [Send attribution data to RevenueCat](#2-send-attribution-data-to-revenuecat) are present.
3. In [Customer History](https://www.revenuecat.com/docs/dashboard-and-metrics/customer-profile#customer-history), open the sandbox purchase event and confirm the Meta Ads delivery row exists. If RevenueCat doesn't show a Meta Ads delivery row, see [no provider delivery row troubleshooting](https://www.revenuecat.com/docs/integrations/attribution/troubleshooting#no-provider-delivery-row-appears-in-revenuecat).
4. Open the Meta Ads delivery details in Customer History and review the Request and Response tabs. For CAPI events, the response can include `fbtrace_id`, which Meta support can use to inspect ingestion on their side.
5. Check Meta Events Manager after the expected reporting delay. For iOS app promotion campaigns, also review Meta's event eligibility and diagnostics for Aggregated Event Measurement (AEM), SKAdNetwork (SKAN), Ads Manager optimization, and App Promotion eligibility. See Meta's guidance on [how to check if your app events are eligible for Aggregated Event Measurement](https://www.facebook.com/business/help/617021863580582?id=1877298665783613). If RevenueCat shows successful delivery but Meta reporting still looks wrong, see [provider attribution troubleshooting](https://www.revenuecat.com/docs/integrations/attribution/troubleshooting#revenuecat-shows-delivery-but-provider-attribution-or-reporting-is-wrong).

:::success
You have completed the Meta Ads integration setup.
:::

## 5. View events in Meta

After RevenueCat delivers events, use Meta's dashboards to confirm that Meta has processed them for the reports and workflows you care about. Meta Events Manager can take up to 24 hours to show accepted events.

1. In Meta Events Manager, open the dataset or app you configured in RevenueCat and look for the standard events RevenueCat sends, such as `StartTrial`, `Subscribe`, or `fb_mobile_purchase`. See Meta's [Conversions API setup verification guide](https://developers.facebook.com/docs/marketing-api/conversions-api/verifying-setup/) for where to monitor received events.

   Events sent with revenue attached count toward Meta's Revenue number, including trial conversions and renewals that occur when the app isn't active.
2. Review Meta's [event match quality](https://www.facebook.com/business/help/765081237991954), diagnostics, and app event eligibility. For iOS app promotion campaigns, see Meta's guidance on [how to check if your app events are eligible for Aggregated Event Measurement](https://www.facebook.com/business/help/617021863580582?id=1877298665783613).

   A successful RevenueCat delivery means Meta accepted the event, but Meta still decides whether the event can be matched, attributed to a campaign, made eligible for App Promotion, or used for Ads Manager optimization. If Meta reporting still looks wrong, see [provider attribution troubleshooting](https://www.revenuecat.com/docs/integrations/attribution/troubleshooting#revenuecat-shows-delivery-but-provider-attribution-or-reporting-is-wrong).
3. In Meta Ads Manager, [customize columns](https://www.facebook.com/business/help/1452248935049010) to include subscription metrics, such as Subscriptions and Trials Started. Compare Meta-attributed results with the matching RevenueCat campaign, date range, attribution window, and revenue basis; don't compare all RevenueCat trials directly with Meta-attributed conversions.
4. (Optional) In Meta Audiences, create [custom audiences](https://www.facebook.com/business/help/744354708981227) from app activity events such as `Subscribe`, then use those audiences for subscriber retargeting or lookalike audiences.
