Iterable

Integrate in-app purchase events from RevenueCat with Iterable

👍

The Iterable integration is available on the Pro plan.

Iterable is a cross-channel platform that powers unified customer experiences and empowers marketers to create, optimize and measure every interaction taking place throughout the customer journey. With Iterable, brands create individualized marketing touchpoints that earn engagement, solidify trust and galvanize loyal consumer-brand relationships.

RevenueCat can automatically send subscription events to Iterable. This can be helpful in understanding what stage a customer is in to react accordingly. For example, you might want to:

  • Automate an onboarding workflow to a user in a free trial
  • Send an SMS to a loyal user and offer them a discount
  • Trigger an email to users who cancel their free trial

With accurate and up-to date subscription data in Iterable, you’ll be set to increase your users’ engagement.

Events

The Iterable integration tracks the following events:

Event Type

Description

Iterable Event Type

Initial Purchase

The first purchase of an auto-renewing subscription product that does not contain a free trial.

Purchase

Trial Started

The start of an auto-renewing subscription product free trial.

Purchase

Trial Converted

When an auto-renewing subscription product converts from a free trial to normal paid period.

Purchase

Trial Cancelled

When a user turns off renewals for an auto-renewing subscription product during a free trial period.

Custom

Renewal

When an auto-renewing subscription product renews OR a user repurchases the auto-renewing subscription product after a lapse in their subscription.

Purchase

Cancellation

When a user turns off renewals for an auto-renewing subscription product during the normal paid period.

Custom

Uncancellation

When a user re-enables the auto-renew status for a subscription.

Custom

Non Subscription Purchase

The purchase of any product that's not an auto-renewing subscription.

Purchase

Subscription Paused

When a subscription is paused. Available for Google Play subscriptions only.

Custom

Expiration

When a subscription expires.

Custom

Billing Issue

When a billing issue is detected.

Custom

Product Change

When user has changed the product of their subscription.

This does not mean the new subscription is in effect immediately. See Managing Subscriptions for more details on updates, downgrades, and crossgrades.

Custom

For events that have revenue, such as trial conversions and renewals, RevenueCat will automatically record this amount along with the event in Iterable.

Setup

1. Set Iterable User Identity

In order to associate RevenueCat data with the Iterable User Profile, either the RevenueCat $email or $iterableUserId Subscriber Attributes should be set in RevenueCat. The preferred method is to send the $email attribute. If neither of these fields exist, RevenueCat will fallback to the RevenueCat app user ID. You can read more about Iterable user profiles in Iterable's Identifying the User documentation.

📘

$iterableUserId character limit

The $iterableUserId can be up to 52 characters long.

(optional) Set Iterable Campaign ID and/or Template ID

To attribute an event to an Iterable Campaign ID and/or Template ID, set the $iterableCampaignId and/or $iterableTemplateId subscriber attributes through the RevenueCat SDK or REST API.

// Configure Purchases
Purchases.configure(this, "public_sdk_key", "my_app_user_id");

// Initialize Iterable
IterableAPI.initialize(apiKey: "<YOUR_API_KEY>", launchOptions: launchOptions, config: config)

// Setting Iterable email or userId
IterableAPI.email = "[email protected]"
IterableAPI.userId = "user123"


// Set $email or $iterableUserId, (optional) $iterableCampaignId, $iterableTemplateId
Purchases.shared.setAttributes(["$email" : IterableAPI.email],
                               ["$iterableUserId" : IterableAPI.userId,
                               ["$iterableCampaignId" : "123"],
                               ["$iterableTemplateId" : "123"])
// Configure Purchases
[RCPurchases configureWithAPIKey:@"public_sdk_key"];

// Initialize Iterable
[IterableAPI initializeWithApiKey:@"<YOUR_API_KEY>" launchOptions:launchOptions config:config]

// Setting Iterable email or userId
IterableAPI.email = @"[email protected]";
IterableAPI.userId = @"user123";

// Set $email or $iterableUserId, (optional) $iterableCampaignId, $iterableTemplateId
[[RCPurchases sharedPurchases] setAttributes:@{
  @"$email": IterableAPI.email,
  @"iterableUserId": IterableAPI.userId ,
  @"$iterableCampaignId": @"123",
  @"$iterableTemplateId": @"123"
}];
// Configure Purchases
Purchases.configure(new PurchasesConfiguration.Builder(this, "public_google_sdk_key").build());

// Initialize Iterable
IterableApi.initialize(context, "<YOUR_API_KEY>", config);

// Setting Iterable email or userId
IterableApi.getInstance().setEmail("[email protected]");
IterableApi.getInstance().setUserId("user123");

// Set $email or $iterableUserId, (optional) $iterableCampaignId, $iterableTemplateId
Map<String, String> attributes = new HashMap<String, String>();
attributes.put("$email", IterableApi.getInstance().getEmail());
attributes.put("$iterableUserId", IterableApi.getInstance().getUserId());
attributes.put("$iterableCampaignId", "123");
attributes.put("$iterableTemplateId", "123");
Purchases.getSharedInstance().setAttributes(attributes);
// Configure Purchases
if (Platform.OS === 'ios') {
    await Purchases.setup("public_ios_sdk_key");
} else if (Platform.OS === 'android') {
    await Purchases.setup("public_google_sdk_key");
    // OR: if building for Amazon, be sure to follow the installation instructions then:
    await Purchases.setup({ apiKey: "public_amazon_sdk_key", useAmazon: true });
}

// Initialize Iterable
Iterable.initialize('<YOUR_API_KEY>', config);

// Setting Iterable email or userId
Iterable.setEmail("[email protected]");
Iterable.setUserId("user123");

// Set $email or $iterableUserId, (optional) $iterableCampaignId, $iterableTemplateId
Iterable.getEmail().then(email => {
    console.log("Current email: " + email);
    Purchases.setAttributes({ "$email" : email });
});

Iterable.getUserId().then(userId => {
    console.log("Current userId: " + userId);
    Purchases.setAttributes({ "$iterableUserId" : userId });
});

Purchases.setAttributes({ "$iterableCampaignId" : "123", "$iterableTemplateId" : "123" });
curl --request POST \
  --url https://api.revenuecat.com/v1/subscribers/app_user_id/attributes \
  --header 'Authorization: Bearer ' \
  --header 'Content-Type: application/json' \
  --data \ 
  '{ 
    "attributes" :  {
        "$iterableCampaignId": {
            "value": "123"
        },
        "$iterableTemplateId": {
            "value": "123"
        }
    }
}'

2. Send RevenueCat Events to Iterable

After you've set up the Purchase SDK and Iterable SDK to have the same user identity, you can "turn on" the integration and configure the event names from the RevenueCat dashboard.

  1. Navigate to your app in the RevenueCat and find the Integrations card in the left menu. Select + New
  1. Choose Iterable from the Integrations menu
  2. Add your Iterable Server-side API key to the API key field in RevenueCat
  3. Enter the event names that RevenueCat will send or choose the default event names
  4. Select whether you want RevenueCat to report proceeds (after app store cut) or revenue (gross sales)
Iterable configuration pageIterable configuration page

Iterable configuration page

📘

Iterable sandbox environment

Iterable recommends having a production and sandbox project to separate live and testing environments. You can input both keys in the RevenueCat Iterable settings page.

Testing the Iterable integration

Make a sandbox purchase with a new user

Simulate a new user installing your app, and go through your app flow to complete the sandbox purchase.

Check that the Iterable event delivered successfully

While still on the Customer View, select the purchase event in the Customer History page and make sure that the Iterable integration event exists and was delivered successfully.

Check Iterable dashboard for the delivered event

Navigate to your Iterable dashboard > Insights > Logs. To find Purchase events navigate to 'Purchases' and to find Custom events navigate to 'Events'. You will see events RevenueCat has dispatched to the Iterable under 'Purchase Log' and 'Events log' respectively.

Sample Event

Below is a sample JSON that is delivered to Iterable for a trial started event.

{
  "createdAt": 1644624970000,
  "id": "1000000967584331",
  "items": [
    {
      "dataFields": {
        "country_code": "US",
        "currency": "USD",
        "entitlement_ids": [
          "pro"
        ],
        "environment": "SANDBOX",
        "expiration_at_ms": 1644625150000,
        "is_family_share": false,
        "offer_code": null,
        "original_transaction_id": "1000000967584331",
        "period_type": "TRIAL",
        "presented_offering_id": "default",
        "store": "APP_STORE",
        "takehome_percentage": 0.7
      },
      "id": "rc_3999_1y_1w0",
      "name": "rc_trial_started_event",
      "price": 0,
      "quantity": 1
    }
  ],
  "total": 0,
  "user": {
    "dataFields": {
      "app_user_id": "$RCAnonymousID:354629ce52324242a03a42f5efe7d020",
      "original_app_user_id": "$RCAnonymousID:354629ce52324242a03a42f5efe7d020",
      "subscriber_attributes": {
        "$email": {
          "updated_at_ms": 1644624942354,
          "value": "[email protected]"
        }
      }
    },
    "email": "[email protected]",
    "preferUserId": true,
    "userId": "$RCAnonymousID:354629ce52324242a03a42f5efe7d020"
  }
}

Considerations

Refunds

Revenue for Iterable campaign reporting will not be accurate due to refund events. You can build custom workflows around a "refund" event and independently calculate the total revenue refunded for your campaigns.


Did this page help you?