Flutter SDK+ Integration Guide
This page explains how to implement the Flutter SDK+ for Rokt Ecommerce. Select your target platform to see the full integration guide for that platform.
Work with your Rokt account manager to first implement the SDK+ in a development environment so you can thoroughly test before going live.
1. Add the Rokt SDK to Your iOS AppDirect link to 1. Add the Rokt SDK to Your iOS App
Rokt SDK+ requires a minimum deployment target of iOS 15.0.
- CocoaPods
- SPM
Add the following pods to your ios/Podfile:
pod 'mParticle-Apple-SDK', '~> 9.0'
pod 'mParticle-Rokt', '~> 9.0'
pod 'RoktPaymentExtension', '~> 1.0'
In Xcode, select File → Add Package Dependencies and add the following packages with the dependency rule set to Up to Next Major Version:
| Package | Repository URL | Product |
|---|---|---|
| mParticle Apple SDK | https://github.com/mParticle/mparticle-apple-sdk | mParticle-Apple-SDK |
| mParticle Rokt Kit | https://github.com/mparticle-integrations/mp-apple-integration-rokt.git | mParticle-Rokt |
| Payment Extension | https://github.com/ROKT/rokt-payment-extension-ios.git | RoktPaymentExtension |
If you manage dependencies in Package.swift:
dependencies: [
.package(url: "https://github.com/mParticle/mparticle-apple-sdk", from: "9.0.0"),
.package(url: "https://github.com/mparticle-integrations/mp-apple-integration-rokt.git", from: "9.0.0"),
.package(url: "https://github.com/ROKT/rokt-payment-extension-ios.git", from: "1.0.0"),
]
2. Initialize the Rokt SDKDirect link to 2. Initialize the Rokt SDK
Insert the following initialization snippet in your AppDelegate file. Replace your-key and your-secret with the values provided by your Rokt team.
- Swift
- Objective-C
import mParticle_Apple_SDK
import RoktPaymentExtension
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Initialize the SDK
let options = MParticleOptions(key: "your-key",
secret: "your-secret")
// Specify the data environment with environment:
// Set it to .development if you are still testing your integration.
// Set it to .production if your integration is ready for production data.
// The default is .autoDetect which attempts to detect the environment automatically
options.environment = .development
// Identify the current user:
let identifyRequest = MPIdentityApiRequest.withEmptyUser()
// If you're using an un-hashed email address, set it in 'email'.
identifyRequest.email = "j.smith@example.com"
// If you're using a hashed email address, set it in 'other' instead of email
identifyRequest.setIdentity("sha256 hashed email goes here", identityType: .other)
// If the user is identified with their email address, set additional user attributes.
options.identifyRequest = identifyRequest
options.onIdentifyComplete = {(result: MPIdentityApiResult?, error: Error?) in
if let user = result?.user {
user.setUserAttribute("example attribute key", value: "example attribute value")
}
}
MParticle.sharedInstance().start(with: options)
// Register after MParticle.sharedInstance().start(), before selectShoppableAds
if let paymentExt = RoktPaymentExtension(
applePayMerchantId: "merchant.com.yourapp.rokt"
) {
MParticle.sharedInstance().rokt.registerPaymentExtension(paymentExt)
}
return true
}
#import <mParticle_Apple_SDK.h>
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Initialize the SDK
MParticleOptions *options =
[MParticleOptions optionsWithKey:@"your-key"
secret:@"your-secret"];
// Specify the data environment with environment:
// Set it to MPEnvironmentDevelopment if you are still testing your integration.
// Set it to MPEnvironmentProduction if your integration is ready for production data.
// The default is MPEnvironmentAutoDetect which attempts to detect the environment automatically
options.environment = MPEnvironmentDevelopment;
// Identify the current user:
MPIdentityApiRequest *identifyRequest = [MPIdentityApiRequest requestWithEmptyUser];
// If you're using an un-hashed email address, set it in 'email'.
identifyRequest.email = @"j.smith@example.com";
// If you're using a hashed email address, set it in 'other' instead of email
[identifyRequest setIdentity:@"sha256 hashed email goes here"
identityType:MPIdentityOther];
options.identifyRequest = identifyRequest;
// If the user is identified with their email address, set additional user attributes.
options.onIdentifyComplete = ^(MPIdentityApiResult *_Nullable apiResult, NSError *_Nullable error) {
if (apiResult) {
[apiResult.user setUserAttribute:@"example attribute key"
value:@"example attribute value"];
}
};
[[MParticle sharedInstance] startWithOptions:options];
return YES;
}
When inserting the initialization snippet, you will see customizable fields for:
-
Entering your Rokt key and secret.
Set
keyandsecretto the values provided by your Rokt account manager. -
Setting your data environment.
Set
environmentto.development(Swift) orMPEnvironmentDevelopment(Objective-C) while testing to route data to the Development environment, and.productionorMPEnvironmentProductionto send live customer activity to Production. -
Identifying your user and setting attributes.
In
identifyRequest, pass the user's raw, un-hashed email in theemailproperty. Once identified, use theonIdentifyCompletecallback to set additional user attributes.noteAlways include
identifyRequestin the initialization snippet. If you don't have the user's email at initialization, omit the assignment — the SDK will still initialize, and you can identify the user later via Step 4: Identify the User. See Appendix C: Error Handling for how to handle identity failures — without error handling you may see data consistency issues at scale. -
Registering the payment extension.
Register
RoktPaymentExtensionafterMParticle.sharedInstance().start()and beforeselectShoppableAdsto enable Apple Pay. See Step 8: Configure Apple Pay.
3. Add the Flutter PackageDirect link to 3. Add the Flutter Package
Add the mparticle_flutter_sdk package to your Flutter project:
flutter pub add mparticle_flutter_sdk
After adding the dependency, the following (or similar) lines are added to your pubspec.yaml:
dependencies:
mparticle_flutter_sdk: ^2.0.0
Import the package into your Dart code and get an instance of mParticle:
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';
MparticleFlutterSdk? mpInstance = await MparticleFlutterSdk.getInstance();
4. Identify the UserDirect link to 4. Identify the User
Call the identify method with a fresh identityRequest any time the user provides their email address after the SDK has initialized (for example, when they log in, create an account, or make a purchase). This ensures event data is attributed to the correct user.
Supported User IdentifiersDirect link to Supported User Identifiers
Show supported user identifiers
| Identifier | Type | Description |
|---|---|---|
email | string | Pass the customer's raw, unhashed email address. |
mobile_number | string | Pass the customer's phone number in E.164 format. |
customerId | string | Pass your internal customer/account identifier. Send on every screen for logged-in users. |
other | string | Pass a SHA-256-hashed email. Only use when the raw email cannot be provided — do not pass both email and other. |
other2 | string | Pass a SHA-256-hashed mobile number. Only use when the raw mobile number cannot be provided — do not pass both mobile_number and other2. |
To identify the user:
-
Create an
identityRequestobject to contain the user's identifiers. You should integrate the user's raw, unhashed email address into theemailfield. -
To set additional user attributes, use the
thensuccess handler on the identify call. If theidentityRequestsucceeds, any user attributes you set inside the handler are assigned to the identified user. -
After creating the
identityRequest, call the identify method, passing in the request object.For example, to identify a user named Jane Smith with the email address
j.smith@example.com, mobile number+13125551515, and customer IDcust_10482, you would use:Identify Jane Smithimport 'package:mparticle_flutter_sdk/identity/identity_type.dart';
import 'package:mparticle_flutter_sdk/identity/identity_api_result.dart';
import 'package:mparticle_flutter_sdk/identity/identity_api_error_response.dart';
// 1. Create the identityRequest object
var identityRequest = MparticleFlutterSdk.identityRequest;
// Preferred: pass the customer's raw, unhashed email.
// If you can only provide a SHA-256-hashed email, remove the Email line and use IdentityType.Other instead — do not pass both.
identityRequest.setIdentity(identityType: IdentityType.Email, value: 'j.smith@example.com');
identityRequest.setIdentity(identityType: IdentityType.Other, value: 'SHA-256 hashed email'); // only if raw email unavailable
// If you can only provide a SHA-256-hashed mobile number, use IdentityType.Other2 instead of MobileNumber — do not pass both.
identityRequest.setIdentity(identityType: IdentityType.Other2, value: 'SHA-256 hashed mobile number'); // only if raw mobile unavailable
identityRequest.setIdentity(identityType: IdentityType.MobileNumber, value: '+13125551515');
identityRequest.setIdentity(identityType: IdentityType.CustomerId, value: 'cust_10482');
// 2. User attributes are set in the success handler
// 3. Call the identify method
mpInstance?.identity
.identify(identityRequest: identityRequest)
.then(
(IdentityApiResult successResponse) {
successResponse.user.setUserAttribute('first_name', 'Jane');
successResponse.user.setUserAttribute('last_name', 'Smith');
},
onError: (error) {
var failureResponse = error as IdentityAPIErrorResponse;
print("Failure Response: $failureResponse");
}
);
5. Set User AttributesDirect link to 5. Set User Attributes
Set user attributes progressively as the user navigates your app, not just at checkout. The more attributes you set, the better Rokt can resolve the customer and deliver relevant offers.
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';
// Retrieve the current user. This will only succeed if you have identified the user during SDK initialization or by calling the identify method.
var currentUser = await mpInstance?.getCurrentUser();
// Once you have successfully set the current user to `currentUser`, you can set user attributes with:
currentUser?.setUserAttribute(key: 'custom-attribute-name', value: 'custom-attribute-value');
// Note: all user attributes (including list attributes and tags) must have distinct names.
// Rokt recommends setting as many of the following user attributes as possible:
currentUser?.setUserAttribute(key: 'first_name', value: 'John');
currentUser?.setUserAttribute(key: 'last_name', value: 'Doe');
// Phone numbers can be formatted either as '1234567890', or '+1 (234) 567-8901'
currentUser?.setUserAttribute(key: 'mobile', value: '3125551515');
currentUser?.setUserAttribute(key: 'age', value: '33');
currentUser?.setUserAttribute(key: 'gender', value: 'M');
currentUser?.setUserAttribute(key: 'city', value: 'Brooklyn');
currentUser?.setUserAttribute(key: 'state', value: 'NY');
currentUser?.setUserAttribute(key: 'zip', value: '123456');
currentUser?.setUserAttribute(key: 'dob', value: 'yyyymmdd');
currentUser?.setUserAttribute(key: 'title', value: 'Mr');
currentUser?.setUserAttribute(key: 'language', value: 'en');
currentUser?.setUserAttribute(key: 'lifetime_value', value: '52.25');
currentUser?.setUserAttribute(key: 'predicted_ltv', value: '136.23');
// You can create a user attribute to contain a list of values
var attributeList = <String>[];
attributeList.add('documentary');
attributeList.add('comedy');
attributeList.add('romance');
attributeList.add('drama');
currentUser?.setUserAttributeArray(key: 'favorite-genres', value: attributeList);
// To remove a user attribute, call removeUserAttribute and pass in the attribute name. All user attributes share the same key space.
currentUser?.removeUserAttribute(key: 'attribute-to-remove');
User AttributesDirect link to User Attributes
Set as many of the following as you can collect:
Show all user attributes
| Attribute | Type | Description |
|---|---|---|
first_name | string | Customer's first name. Used for personalization. |
last_name | string | Customer's last name. Used for personalization. |
mobile | string | Phone number formatted as 1112345678 or +1 (222) 345-6789. Used for identity resolution and relevance. |
age | integer | Customer's age. Alternate to dob. Used for eligibility and relevance. |
dob | string | Date of birth, yyyymmdd. Alternate to age. Used for eligibility and relevance. |
gender | string | Customer's gender. For example, M, F, Male, or Female. Used for relevance. |
title | string | Honorific. For example, Mr, Mrs, Ms. Used for personalization. |
language | string | ISO 639-1 language code associated with the purchase. Used for relevance. |
city | string | Billing city. Used for relevance. |
state | string | Billing state / province / region. Used for relevance and eligibility. |
zip | string | Full ZIP or postcode (US preference is ZIP+4). Used for identity resolution and relevance. |
country | string | ISO 3166-1 alpha-2 country code (e.g. US, GB, AU). Used for eligibility and relevance. |
new_customer | boolean | Whether this is a first-time buyer. Used for relevance. |
customer_type | string | Whether the user is authenticated (guest / logged_in). Used for relevance. |
loyalty_tier | string | Partner loyalty program tier. Used for relevance and eligibility. |
loyalty_id | string | Loyalty program member ID. Used for identity resolution. |
lifetime_value | decimal | Customer's cumulative purchase value, as a string (e.g. "52.25"). Used for relevance. |
predicted_ltv | decimal | Predicted total lifetime value, typically from a partner ML model. Distinct from lifetime_value. Used for relevance. |
subscription_status | string | Subscription state if applicable (active, trial, churned, paused, none). Used for relevance and eligibility. |
customer_segment | string | Partner internal segmentation (e.g. vip, at_risk, new, reactivated). Used for relevance. |
utm_source | string | Marketing attribution source. Used for relevance. |
utm_medium | string | Marketing attribution medium. Used for relevance. |
utm_campaign | string | Marketing attribution campaign. Used for relevance. |
All user attributes (including list attributes) must have distinct names.
6. Track Funnel EventsDirect link to 6. Track Funnel Events
Track screen views, account lifecycle events, commerce events, and custom events so Rokt can maintain identity continuity and understand where each customer is in their journey.
Screen ViewsDirect link to Screen Views
Call mpInstance?.logScreenEvent() with the name of the screen (e.g. 'homepage', 'product detail page'). Include any additional custom attributes in the event's customAttributes map.
import 'package:mparticle_flutter_sdk/events/screen_event.dart';
ScreenEvent screenEvent = ScreenEvent(eventName: 'homepage')
..customAttributes = {'custom-attribute': 'custom-value'};
mpInstance?.logScreenEvent(screenEvent);
Account Lifecycle EventsDirect link to Account Lifecycle Events
Log account lifecycle events when the user signs up, logs in, or logs out so Rokt can maintain identity continuity across sessions and devices. Signup and login events accept a method attribute describing how the user signed up or logged in.
Supported lifecycle event typesDirect link to Supported lifecycle event types
Show lifecycle event types
| Lifecycle Event Type | When to trigger | Supported method values |
|---|---|---|
sign_up | New account created | email, social, guest |
login | User logs in | email, social, sso |
logout | User logs out | Not applicable. |
Example lifecycle eventsDirect link to Example lifecycle events
import 'package:mparticle_flutter_sdk/events/event_type.dart';
import 'package:mparticle_flutter_sdk/events/mp_event.dart';
// Signup event
MPEvent signupEvent = MPEvent(
eventName: 'sign_up',
eventType: EventType.Other)
..customAttributes = {'method': 'email'};
mpInstance?.logEvent(signupEvent);
// Login event
MPEvent loginEvent = MPEvent(
eventName: 'login',
eventType: EventType.Other)
..customAttributes = {'method': 'email'};
mpInstance?.logEvent(loginEvent);
// Logout event
MPEvent logoutEvent = MPEvent(
eventName: 'logout',
eventType: EventType.Other);
mpInstance?.logEvent(logoutEvent);
Commerce EventsDirect link to Commerce Events
Commerce events carry product-level details for the user's journey. Trigger a separate commerce event for each product action the customer takes.
Investing in full commerce event coverage is one of the highest-leverage things you can do during your integration. Each event tells Rokt something different about where the customer is in their journey: a product view signals exploration, an add-to-cart signals consideration, a checkout start signals purchase intent, and a completed purchase confirms conversion. With a richer signal, Rokt can personalize offers more effectively, measure placement performance accurately, and attribute conversions to the right touchpoints. Doing this work during your initial integration also avoids a retrofit later. The signal compounds over time: each event Rokt receives adds context used to sharpen personalization, improve attribution accuracy, and better resolve and segment your customer base on future visits.
Commerce events are logged with CommerceEvent, using a ProductActionType that identifies the customer action (viewing a product, adding to cart, starting checkout, completing a purchase, etc.). The sections below list the supported action types and walk through assembling the event.
Product action typesDirect link to Product action types
Show all product action types
| Customer action | Product action constant |
|---|---|
| Product detail page viewed | ProductActionType.ViewDetail |
| Product clicked | ProductActionType.Click |
| Item added to cart | ProductActionType.AddToCart |
| Item removed from cart | ProductActionType.RemoveFromCart |
| Item added to wishlist | ProductActionType.AddToWishList |
| Item removed from wishlist | ProductActionType.RemoveFromWishlist |
| Checkout flow initiated | ProductActionType.Checkout |
| Checkout option selected | ProductActionType.CheckoutOption |
| Order confirmed | ProductActionType.Purchase |
| Order refunded | ProductActionType.Refund |
Tracking a commerce event requires three steps:
1. Define the productDirect link to 1. Define the product
Create a Product with the product's name, SKU, and price. Set additional fields as needed.
import 'package:mparticle_flutter_sdk/events/product.dart';
// Create an optional map of custom attributes for the product
final customAttributes = {
'ocean-view': 'true',
'balcony': 'false',
};
Product product = Product(
name: 'Double Room - Econ Rate',
sku: 'econ-1',
price: 100.00,
);
product.quantity = 4;
// Include the map of custom attributes
product.attributes = customAttributes;
2. Summarize the transactionDirect link to 2. Summarize the transaction
Create a TransactionAttributes object for ProductActionType.Purchase, ProductActionType.Checkout, and ProductActionType.CheckoutOption events. Include shipping and coupon code when applicable — order-level coupons belong here, not on individual products.
import 'package:mparticle_flutter_sdk/events/transaction_attributes.dart';
final TransactionAttributes transactionAttributes = TransactionAttributes(
transactionID: 'ORDER-12345',
revenue: 149.99,
tax: 12.50,
shipping: 5.99,
couponCode: 'SUMMER20',
);
3. Log the commerce eventDirect link to 3. Log the commerce event
Create a CommerceEvent with a product action constant from the table above, attach the transactionAttributes, and log it.
import 'package:mparticle_flutter_sdk/events/commerce_event.dart';
import 'package:mparticle_flutter_sdk/events/product_action_type.dart';
CommerceEvent event = CommerceEvent.withProduct(
productActionType: ProductActionType.Purchase,
product: product,
);
event.transactionAttributes = transactionAttributes;
// Optional custom attributes for the purchase event
event.customAttributes = {'sale': 'true'};
mpInstance?.logCommerceEvent(event);
The same structure applies to every product action constant — swap ProductActionType.Purchase for the action that matches the customer behavior you're logging. See the Product action types table for the full list.
Custom EventsDirect link to Custom Events
Track custom events using MPEvent, passing an event name, event type, and optional custom attributes.
Supported custom event typesDirect link to Supported custom event types
Show custom event types
| Type | Use for |
|---|---|
EventType.Navigation | User navigation flows and screen transitions within your app. |
EventType.Location | Location-based interactions and movements. |
EventType.Search | Search queries and search-related actions. |
EventType.Transaction | Financial transactions and purchase-related activity. |
EventType.UserContent | User-generated content like reviews, comments, or posts. |
EventType.UserPreference | User settings, preferences, and customization choices. |
EventType.Social | Social media interactions and sharing activities. |
EventType.Other | Anything that doesn't fit the categories above. |
Example custom eventDirect link to Example custom event
import 'package:mparticle_flutter_sdk/events/event_type.dart';
import 'package:mparticle_flutter_sdk/events/mp_event.dart';
MPEvent event = MPEvent(
eventName: 'Video Watched',
eventType: EventType.Navigation)
..customAttributes = {
'category': 'Destination Intro',
'title': 'Paris',
};
mpInstance?.logEvent(event);
7. Show a PlacementDirect link to 7. Show a Placement
Call selectPlacements on every payment and confirmation screen you want Rokt to render content on. Include one of the following page identifiers to specify the screen type and whether it's for testing or production:
stg.rokt.conf: A confirmation screen in a staging (or testing) environment.prod.rokt.conf: A confirmation screen in a production environment.stg.rokt.payments: A payments screen in a staging (or testing) environment.prod.rokt.payments: A payments screen in a production environment.
Placement AttributesDirect link to Placement Attributes
Pass these attributes in the attributes map of selectPlacements. Always supply the most recent value — attributes passed here override any earlier setUserAttribute calls.
Show all placement attributes
| Attribute | Type | Description |
|---|---|---|
email | string | Customer email (unhashed). Used for identity resolution. |
first_name | string | Customer first name. Used for personalization. |
last_name | string | Customer last name. Used for personalization. |
mobile | string | Customer mobile number in E.164 format. Used for identity resolution. |
confirmation_ref | string | Order / confirmation reference number. Used for relevance and deduplication. |
currency | string | Transaction currency (ISO 4217, e.g. USD, GBP, AUD). Used for relevance. |
country | string | ISO 3166-1 alpha-2 country code. Used for eligibility and relevance. |
language | string | Customer's preferred language (ISO 639-1). Used for relevance. |
total_price | decimal | Total cart value including tax and shipping. Used for relevance. |
amount | string | Cart subtotal before tax and shipping. Distinct from total_price. Used for relevance and Shoppable Ads. |
cart_item_count | integer | Number of items in the cart. Used for relevance. |
coupon_code | string | Promo code applied to the order, if any. Used for relevance. |
new_customer | boolean | Whether this is a first-time buyer. Used for relevance. |
customer_type | string | guest or logged_in. Used for relevance. |
lifetime_value | decimal | Customer's cumulative purchase value (e.g. "2340.00"). Used for relevance. |
subscription_status | string | Subscription state if applicable (active, trial, churned, paused, none). Used for relevance and eligibility. |
customer_segment | string | Partner internal segmentation (e.g. vip, at_risk, new, reactivated). Used for relevance. |
payment_type | string | Payment method selected (credit_card, paypal, apple_pay, etc.). Used for Pay+ eligibility and Shoppable Ads payment method prioritization. |
payment_service_provider | string | Payment services offered on the page (apple_pay, paypal, card). Used for Pay+ eligibility. |
ccbin | string | Credit card BIN (first 6 digits). Used for relevance. |
billing_address1 | string | Billing street address. Used for identity resolution and relevance. |
billing_address2 | string | Billing apartment / unit. Used for identity resolution. |
billing_city | string | Billing city. Used for relevance. |
billing_state | string | Billing state or province. Used for relevance. |
billing_zipcode | string | Billing ZIP / postcode. Used for identity resolution and relevance. |
shipping_method | string | Shipping method selected (standard, express, next_day). Used for relevance. |
shipping_address1 | string | Shipping street address. Used for relevance and Shoppable Ads order fulfillment. |
shipping_city | string | Shipping city. Used for relevance and Shoppable Ads order fulfillment. |
shipping_state | string | Shipping state or province. Used for relevance and Shoppable Ads order fulfillment. |
shipping_zipcode | string | Shipping ZIP or postcode. Used for relevance and Shoppable Ads order fulfillment. |
shipping_country | string | Shipping country (ISO 3166-1 alpha-2). Used for relevance and Shoppable Ads order fulfillment. |
ads_experience | string | Pass "shoppable" when deliberately selecting a Shoppable Ads experience. |
Overlay PlacementsDirect link to Overlay Placements
Overlay placements render on top of your confirmation screen in a Rokt-managed container, requiring no changes to your app's existing layout.
To insert an overlay placement, call selectPlacements once the confirmation screen loads:
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';
final attributes = {
// Identity
'email': 'j.smith@example.com',
'first_name': 'Jenny',
'last_name': 'Smith',
'mobile': '+13125551515',
// Transaction
'confirmation_ref': '54321',
'currency': 'USD',
'country': 'US',
'language': 'en',
'total_price': '149.99',
'cart_item_count': '2',
'coupon_code': 'SUMMER20',
// Customer context
'new_customer': 'false',
'customer_type': 'logged_in',
'lifetime_value': '2340.00',
'subscription_status': 'active',
'customer_segment': 'vip',
// Payment (include payment_type and payment_service_provider for Pay+)
'payment_type': 'credit_card',
'payment_service_provider': 'card',
'ccbin': '411112',
// Billing address
'billing_address1': '123 Main St',
'billing_city': 'Brooklyn',
'billing_state': 'NY',
'billing_zipcode': '11201',
// Shipping
'shipping_method': 'express',
'shipping_address1': '175 Varick St',
'shipping_city': 'New York',
'shipping_state': 'NY',
'shipping_zipcode': '10014',
'shipping_country': 'US',
};
final roktConfig = RoktConfig(
colorMode: ColorMode.light,
);
mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
roktConfig: roktConfig,
);
Embedded PlacementsDirect link to Embedded Placements
Embedded placements render inline at a fixed position in your app that you control (for example, above the payment options on a cart screen). Both Thanks and Pay+ use embedded placements, but Pay+ must use embedded placements.
Use the RoktLayout widget to embed a placement in your Flutter UI. The onLayoutCreated callback fires when the widget is created.
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';
final attributes = {
'email': 'j.smith@example.com',
'first_name': 'Jenny',
'last_name': 'Smith',
'billing_zipcode': '90210',
'confirmation_ref': '54321',
};
const RoktLayout(
placeholderName: 'RoktEmbedded1',
onLayoutCreated: () {
// Layout created
}
);
mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
);
For Pay+ placements, include payment_type and payment_service_provider in the selectPlacements call on each screen. payment_service_provider communicates what payment methods are available on the payment screen; payment_type communicates what method the user paid with.
Interstitial Placements (iOS Only)Direct link to Interstitial Placements (iOS Only)
Interstitial placements are rendered between the payment and confirmation screens, allowing customers to purchase additional products. Interstitial placements are used by Shoppable Ads.
Interstitial placements (Shoppable Ads) are supported on iOS only in the Flutter SDK. The Android path does not support interstitial placements.
Shoppable Ads require mparticle_flutter_sdk 2.0.0 or later and mParticle-Apple-SDK ~> 9.0. If you are still on 1.x, follow the SDK+ 2.0 migration guide before proceeding.
iOS native setupDirect link to iOS native setup
Add the Stripe payment extension to your iOS Podfile:
pod 'RoktStripePaymentExtension', '~> 0.1'
Register the payment extension in your AppDelegate.swift after SDK initialization:
import mParticle_Apple_SDK
import RoktStripePaymentExtension
// In application(_:didFinishLaunchingWithOptions:), after MParticle.sharedInstance().start(with: options)
if let stripeExt = RoktStripePaymentExtension(applePayMerchantId: "merchant.com.yourapp.rokt") {
MParticle.sharedInstance().rokt.registerPaymentExtension(stripeExt)
}
The Stripe publishable key is automatically provided from the mParticle dashboard configuration. You only need to provide the Apple Pay merchant ID.
You must call registerPaymentExtension after SDK initialization and before calling selectShoppableAds from your Dart code. If no payment extension is registered, selectShoppableAds will fire a PlacementFailure event.
Display Shoppable AdsDirect link to Display Shoppable Ads
Call selectShoppableAds from your Dart code once all required attributes are available. Shoppable Ads always display as an overlay — no embedded views are needed.
final attributes = {
'email': 'j.smith@example.com',
'first_name': 'Jenny',
'last_name': 'Smith',
'confirmation_ref': 'ORD-12345',
'amount': '52.25',
'currency': 'USD',
'payment_type': 'visa',
'shipping_address1': '123 Main St',
'shipping_city': 'New York',
'shipping_state': 'NY',
'shipping_zipcode': '10001',
'shipping_country': 'US',
};
mpInstance?.rokt.selectShoppableAds(
identifier: 'ConfirmationPage',
attributes: attributes,
);
Shoppable Ads events are delivered via the MPRoktEvents EventChannel — see the Events API section below.
Optional FunctionsDirect link to Optional Functions
| Function | Purpose |
|---|---|
Rokt.close() | Auto-close overlay placements. |
Additional ConfigurationDirect link to Additional Configuration
Pass optional parameters such as RoktConfig to customize the placement UI (e.g. dark/light mode, caching). Font file paths can also be supplied as a map of PostScript names to asset paths.
// If you want to use custom fonts for your placement, create a fontTypefaces map
final fontTypefaces = {'Arial-Bold': 'fonts/Arial-Bold.ttf'};
final roktConfig = RoktConfig(
colorMode: ColorMode.light,
);
mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
fontFilePathMap: fontTypefaces,
roktConfig: roktConfig,
);
If you want to update the identifier RoktExperience or embedded identifier RoktEmbedded1 with a different value, contact your Rokt account manager to ensure Rokt placements are configured consistently.
Events APIDirect link to Events API
The SDK provides placement lifecycle events as a stream through the MPRoktEvents EventChannel. Subscribe to this stream to respond to placement load state, engagement, failures, and Shoppable Ads purchase flows.
final EventChannel roktEventChannel = EventChannel('MPRoktEvents');
roktEventChannel.receiveBroadcastStream().listen((dynamic event) {
debugPrint('rokt_event: $event');
});
Standard eventsDirect link to Standard events
Show all standard events
| Event | Description | Params |
|---|---|---|
| ShowLoadingIndicator | Triggered before the SDK calls the Rokt backend. | |
| HideLoadingIndicator | Triggered when the SDK receives a success or failure from the Rokt backend. | |
| PlacementInteractive | Triggered when a placement has been rendered and is interactable. | identifier: String |
| PlacementReady | Triggered when a placement is ready to display but has not rendered content yet. | identifier: String |
| OfferEngagement | Triggered when the user engages with the offer. | identifier: String |
| PositiveEngagement | Triggered when the user positively engages with the offer. | identifier: String |
| FirstPositiveEngagement | Triggered when the user positively engages with the offer for the first time. | identifier: String, fulfillmentAttributes: FulfillmentAttributes |
| OpenUrl | Triggered when the user presses a URL that is configured to be sent to the partner app. | identifier: String, url: String |
| PlacementClosed | Triggered when a placement is closed by the user. | identifier: String |
| PlacementCompleted | Triggered when the offer progression reaches the end and no more offers are available to display. Also triggered when cache is hit but the retrieved placement will not be displayed as it has previously been dismissed. | identifier: String |
| PlacementFailure | Triggered when a placement could not be displayed due to some failure or when no placements are available to show. | identifier: String (optional) |
| EmbeddedSizeChanged | Triggered when an embedded placement's height changes. | identifier: String, selectedHeight: Double |
| CartItemInstantPurchase | Triggered when the catalog item purchase is initiated by the user. | identifier: String, catalogItemId: String, cartItemId: String, totalPrice: String, currency: String |
| CartItemInstantPurchaseInitiated | Purchase flow started — user tapped "Buy" (Shoppable Ads, iOS only). | identifier: String, catalogItemId: String, cartItemId: String |
| CartItemInstantPurchaseFailure | Purchase failed (Shoppable Ads, iOS only). | identifier: String, catalogItemId: String, cartItemId: String, error: String |
| CartItemDevicePay | Apple Pay / device payment triggered (Shoppable Ads, iOS only). | identifier: String, catalogItemId: String, cartItemId: String, paymentProvider: String |
| InstantPurchaseDismissal | User dismissed the purchase overlay (Shoppable Ads, iOS only). | identifier: String |
8. Configure Apple Pay (iOS Only)Direct link to 8. Configure Apple Pay (iOS Only)
Apple Pay is required for Shoppable Ads on iOS. If you are not using Shoppable Ads, skip this step.
Before registering a payment extension, you need to create an Apple Pay merchant ID, configure your Xcode project, and generate a Payment Processing Certificate.
Follow the steps in Apple Pay — iOS setup, then ensure your AppDelegate calls registerPaymentExtension after MParticle.sharedInstance().start() and before selectShoppableAds. The registration snippet is included in the initialization code above.
9. Test Your IntegrationDirect link to 9. Test Your Integration
To confirm the SDK initializes and events log correctly:
- Enable verbose SDK logging before initialization so you can see what's being sent.
- Build and run your app with the development environment set:
environment = .development(Swift) orMPEnvironmentDevelopment(Objective-C). - Trigger
selectPlacementson the screen where the placement should render and confirm the placement loads. - Verify events appear in your mParticle workspace's Live Stream, and confirm the identify call succeeds.
- Check the Xcode console for Rokt SDK log output.
// Enable mParticle debug logging at the Dart level
MparticleFlutterSdk.setLogLevel(LogLevel.verbose);
TroubleshootingDirect link to Troubleshooting
If the placement doesn't render or events don't appear, check the Xcode console for Rokt SDK errors. Common issues:
Initialization errorsDirect link to Initialization errors
- Confirm the
keyandsecretmatch the values from your Rokt account manager. - Confirm native SDK initialization runs before any
selectPlacementsorlogEventcall from your Dart code. - For Shoppable Ads on iOS, confirm
RoktStripePaymentExtensionis registered after SDK initialization and beforeselectShoppableAds.
Identity errorsDirect link to Identity errors
If the identify call's onError handler fires, inspect the IdentityAPIErrorResponse for the status code and retry the request according to your business logic. Without error handling you may see data consistency issues at scale.
Placement not renderingDirect link to Placement not rendering
- Confirm the placement
identifier(e.g.RoktExperience) matches what your Rokt account manager configured. - For embedded placements, confirm the embedded view identifier (e.g.
RoktEmbedded1) matches the layout configuration. - Check that the attributes map contains at least
email,first_name,last_name,billing_zipcode, andconfirmation_ref.
AppendixDirect link to Appendix
Appendix A: App ConfigurationDirect link to Appendix A: App Configuration
Applications can pass configuration settings through RoktConfig so the SDK uses your app's custom configuration instead of system defaults.
ColorMode objectDirect link to ColorMode object
| Value | Description |
|---|---|
light | Application is in Light Mode |
dark | Application is in Dark Mode |
system | Application defaults to System Color Mode |
final roktConfig = RoktConfig(
colorMode: ColorMode.light,
);
mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
roktConfig: roktConfig,
);
CacheConfig objectDirect link to CacheConfig object
| Parameter | Description |
|---|---|
cacheDurationInSeconds | Optional duration in seconds for which the Rokt SDK should cache the experience. Maximum allowed value is 90 minutes; default is 90 minutes if not provided or invalid. |
cacheAttributes | Optional attributes to be used as cache key. If null, all attributes sent in selectPlacements will be used as the cache key. |
// Cache the experience for 1200 seconds, using email and orderNumber as the cache key.
final roktConfig = RoktConfig(
cacheConfig: CacheConfig(
cacheDurationInSeconds: 1200,
cacheAttributes: {'email': 'j.smith@example.com', 'orderNumber': '123'},
),
);
mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
roktConfig: roktConfig,
);
Appendix B: SwiftUI Support with MPRoktLayoutDirect link to Appendix B: SwiftUI Support with MPRoktLayout
If your app is primarily written in SwiftUI, the MPRoktLayout component provides a more modern, declarative approach to integrating Rokt placements in your iOS app.
The MPRoktLayout class provides a SwiftUI-compatible way to display Rokt placements without manually calling selectPlacements, supporting both overlay and embedded placement types.
import SwiftUI
import mParticle_Apple_SDK
import mParticle_Rokt_Swift
struct OrderConfirmationView: View {
let attributes = [
"email": "test@gmail.com",
"first_name": "Jenny",
"last_name": "Smith",
"billing_zipcode": "07762",
"confirmation_ref": "54321"
]
@State private var sdkTriggered = true
var body: some View {
VStack(alignment: .leading) {
// Other UI components
Text("Order Confirmation")
.font(.title)
// Rokt placement using SwiftUI
MPRoktLayout(
sdkTriggered: $sdkTriggered,
identifier: "RoktExperience",
locationName: "RoktEmbedded1", // For embedded placements
attributes: attributes,
config: roktConfig, // Optional RoktConfig
onEvent: { roktEvent in
// Optional: Handle different event types see above
}
).roktLayout
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
}
| Parameter | Type | Description |
|---|---|---|
sdkTriggered | Bool | Controls when the placement should be triggered. |
identifier | String | The Rokt placement identifier (e.g., "RoktExperience"). |
locationName | String? | Optional location name for embedded placements (e.g., "RoktEmbedded1"). |
attributes | [String: String] | Dictionary of attributes to pass to the placement. |
config | RoktConfig? | Optional configuration object for color mode, caching, etc. |
onEvent | ((RoktEvent) -> Void)? | Optional callback to handle all placement events. |
Appendix C: Error HandlingDirect link to Appendix C: Error Handling
The IDSync API is intended to be central to your app's state and is designed to be fast and highly-available. Similar to how your app may prevent users from logging in, logging out, or modifying their state without an internet connection — treat these APIs as gating operations to maintain a consistent user state. The SDK will not retry API calls automatically, but provides callback APIs so you can do so according to your business logic.
If you do not implement error handling, you may see data consistency issues at scale.
import 'package:mparticle_flutter_sdk/identity/identity_api_result.dart';
import 'package:mparticle_flutter_sdk/identity/identity_api_error_response.dart';
mpInstance?.identity
.identify(identityRequest: identityRequest)
.then(
(IdentityApiResult successResponse) {
// Proceed with the identified user
},
onError: (error) {
var failureResponse = error as IdentityAPIErrorResponse;
// Inspect failureResponse.statusCode to determine the error type:
// - Check for network errors (device offline) and retry the request
// - Check for throttle errors (429) and retry with backoff
print('Identity error: $failureResponse');
}
);
Client-side error codesDirect link to Client-side error codes
The MPIdentityErrorResponseCode enum defines the following client-side codes:
| MPIdentityErrorResponseCode | Description |
|---|---|
MPIdentityErrorResponseCodeRequestInProgress | The IDSync HTTP request was not performed as there is already an IDSync HTTP request in progress. |
MPIdentityErrorResponseCodeClientSideTimeout | The IDSync HTTP request failed due to a TCP connection timeout. |
MPIdentityErrorResponseCodeClientNoConnection | The IDSync HTTP request failed due to lack of network coverage. |
MPIdentityErrorResponseCodeSSLError | The IDSync HTTP request failed due to an SSL configuration issue. |
MPIdentityErrorResponseCodeOptOut | The IDSync HTTP request was not performed due to the SDK being disabled due to opt-out. |
MPIdentityErrorResponseCodeUnknown | The IDSync HTTP request failed due to an unknown error. |
HTTP status codesDirect link to HTTP status codes
| Value | Description |
|---|---|
| 400 | The IDSync HTTP call failed due to an invalid request body. |
| 401 | The IDSync HTTP call failed due to an authentication error. Verify that your API key is correct. |
| 429 | The IDSync HTTP call was throttled and should be retried. |
| 5xx | The IDSync HTTP call failed due to an mParticle server-side issue. |
Appendix D: Passing Session ID from Web to NativeDirect link to Appendix D: Passing Session ID from Web to Native
When a user journey spans both web and native platforms, you can maintain a consistent Rokt session by passing the session ID from the Web SDK to the mParticle Flutter SDK. This is useful for hybrid flows where users complete an action in a WebView (such as a payment page) and return to the native app for confirmation.
Getting the session ID from Web SDKDirect link to Getting the session ID from Web SDK
After calling selectPlacements, the session ID is available on the selection context:
const selection = await launcher.selectPlacements({
identifier: "checkout",
attributes: {
email: "user@example.com",
// ... other attributes
}
});
const sessionId = await selection.context.sessionId;
Passing to native app via deep linkDirect link to Passing to native app via deep link
Pass the session ID to your native app using a deep link:
const deepLink = `myapp://confirmation?sessionId=${encodeURIComponent(sessionId)}`;
window.location.href = deepLink;
Setting the session ID on iOSDirect link to Setting the session ID on iOS
Extract the session ID from the deep link and pass it to the native mParticle SDK before calling selectPlacements. Add this to your AppDelegate.swift:
func handleDeepLink(url: URL) {
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
if let sessionId = components?.queryItems?.first(where: { $0.name == "sessionId" })?.value {
MParticle.sharedInstance().rokt.setSessionId(sessionId: sessionId)
}
// Proceed with your confirmation flow
}
NotesDirect link to Notes
- Call
setSessionIdbeforeselectPlacementsto ensure the session is used. - Empty strings are ignored and will not update the session.
- Always URL-encode the session ID when passing as a query parameter.
1. Add the Rokt SDK to Your Android AppDirect link to 1. Add the Rokt SDK to Your Android App
Update your gradle file to include the necessary dependencies for the SDK:
- build.gradle.kts
- build.gradle
dependencies {
implementation("com.mparticle:android-rokt-kit:5.77.0")
implementation("com.mparticle:android-core:5.77.0")
}
dependencies {
implementation "com.mparticle:android-rokt-kit:5.77.0"
implementation "com.mparticle:android-core:5.77.0"
}
Ensure your root Android Activity extends FlutterFragmentActivity:
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity : FlutterFragmentActivity()
2. Initialize the Rokt SDKDirect link to 2. Initialize the Rokt SDK
The Android SDK can be configured using an MParticleOptions object and a builder class in the onCreate() of the Application class. The mParticle Android SDK should be initialized before any other SDK API calls are made.
Make sure to replace your-key and your-secret with the key and secret provided by your dedicated Rokt account representative.
- Kotlin
- Java
import com.mparticle.MParticle
import com.mparticle.MParticleOptions
class YourApplicationClass : Application() {
override fun onCreate() {
super.onCreate()
// Identify the current user:
// If you do not have the user's email address, you can pass in a null value
val identifyRequest = IdentityApiRequest.withEmptyUser()
// If you're using an un-hashed email address, set it in 'email'.
.email("j.smith@example.com")
.build()
// If the user is identified with their email address, set additional user attributes.
val identifyTask = BaseIdentityTask()
.addSuccessListener { identityApiResult ->
val user = identityApiResult.user
user.setUserAttribute("example attribute key", "example attribute value")
}
val options: MParticleOptions = MParticleOptions.builder(this)
.credentials(
"your-key", // The key provided by your Rokt account representative
"your-secret" // The secret provided by your Rokt account representative
).environment(MParticle.Environment.Development) // Specify the data environment with environment:
// Set it to .development if you are still testing your integration.
// Set it to .production if your integration is ready for production data.
// The default is .autoDetect which attempts to detect the environment automatically
.build()
MParticle.start(options)
}
}
import com.mparticle.MParticle;
import com.mparticle.MParticleOptions;
public class YourApplicationClass extends Application {
@Override
public void onCreate() {
super.onCreate();
MParticleOptions options = MParticleOptions.builder(this)
.credentials(
"your-key", // The key provided by your Rokt account representative
"your-secret" // The secret provided by your Rokt account representative
).environment(MParticle.Environment.Development) // Specify the data environment with environment:
// Set it to .development if you are still testing your integration.
// Set it to .production if your integration is ready for production data.
// The default is .autoDetect which attempts to detect the environment automatically
.build();
// Identify the current user:
IdentityApiRequest identifyRequest = IdentityApiRequest.withEmptyUser()
// If you do not have the user's email address, you can pass in a null value
.email("j.smith@example.com").build();
// If the user is identified with their email address, set additional user attributes.
BaseIdentityTask identifyTask = new BaseIdentityTask()
.addSuccessListener(new TaskSuccessListener() {
@Override
public void onSuccess(IdentityApiResult identityApiResult) {
MParticleUser user = identityApiResult.getUser();
user.setUserAttribute("example attribute key", "example attribute value");
}
});
MParticle.start(options);
}
}
When inserting the initialization snippet, you will see customizable fields for:
-
Entering your Rokt key and secret.
Set
your-keyandyour-secretto the values provided by your Rokt account manager. -
Setting your data environment.
Set
environmenttoMParticle.Environment.Developmentwhile testing to route data to the Development environment, andMParticle.Environment.Productionto send live customer activity to Production. -
Identifying your user and setting attributes.
In
identifyRequest, pass the user's raw, un-hashed email. Once identified, use theaddSuccessListenercallback to set additional user attributes.noteAlways include
identifyRequestin the initialization snippet. If you don't have the user's email at initialization, passnullfor the email — the SDK will still initialize, and you can identify the user later via Step 4: Identify the User. See Appendix C: Error Handling for how to handle identity failures — without error handling you may see data consistency issues at scale.
3. Add the Flutter PackageDirect link to 3. Add the Flutter Package
Add the mparticle_flutter_sdk package to your Flutter project:
flutter pub add mparticle_flutter_sdk
After adding the dependency, the following (or similar) lines are added to your pubspec.yaml:
dependencies:
mparticle_flutter_sdk: ^2.0.0
Import the package into your Dart code and get an instance of mParticle:
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';
MparticleFlutterSdk? mpInstance = await MparticleFlutterSdk.getInstance();
4. Identify the UserDirect link to 4. Identify the User
Call the identify method with a fresh identityRequest any time the user provides their email address after the SDK has initialized (for example, when they log in, create an account, or make a purchase). This ensures event data is attributed to the correct user.
Supported User IdentifiersDirect link to Supported User Identifiers
Show supported user identifiers
| Identifier | Type | Description |
|---|---|---|
email | string | Pass the customer's raw, unhashed email address. |
mobile_number | string | Pass the customer's phone number in E.164 format. |
customerId | string | Pass your internal customer/account identifier. Send on every screen for logged-in users. |
other | string | Pass a SHA-256-hashed email. Only use when the raw email cannot be provided — do not pass both email and other. |
other2 | string | Pass a SHA-256-hashed mobile number. Only use when the raw mobile number cannot be provided — do not pass both mobile_number and other2. |
To identify the user:
-
Create an
identityRequestobject to contain the user's identifiers. You should integrate the user's raw, unhashed email address into theemailfield. -
To set additional user attributes, use the
thensuccess handler on the identify call. If theidentityRequestsucceeds, any user attributes you set inside the handler are assigned to the identified user. -
After creating the
identityRequest, call the identify method, passing in the request object.For example, to identify a user named Jane Smith with the email address
j.smith@example.com, mobile number+13125551515, and customer IDcust_10482, you would use:Identify Jane Smithimport 'package:mparticle_flutter_sdk/identity/identity_type.dart';
import 'package:mparticle_flutter_sdk/identity/identity_api_result.dart';
import 'package:mparticle_flutter_sdk/identity/identity_api_error_response.dart';
// 1. Create the identityRequest object
var identityRequest = MparticleFlutterSdk.identityRequest;
// Preferred: pass the customer's raw, unhashed email.
// If you can only provide a SHA-256-hashed email, remove the Email line and use IdentityType.Other instead — do not pass both.
identityRequest.setIdentity(identityType: IdentityType.Email, value: 'j.smith@example.com');
identityRequest.setIdentity(identityType: IdentityType.Other, value: 'SHA-256 hashed email'); // only if raw email unavailable
// If you can only provide a SHA-256-hashed mobile number, use IdentityType.Other2 instead of MobileNumber — do not pass both.
identityRequest.setIdentity(identityType: IdentityType.Other2, value: 'SHA-256 hashed mobile number'); // only if raw mobile unavailable
identityRequest.setIdentity(identityType: IdentityType.MobileNumber, value: '+13125551515');
identityRequest.setIdentity(identityType: IdentityType.CustomerId, value: 'cust_10482');
// 2. User attributes are set in the success handler
// 3. Call the identify method
mpInstance?.identity
.identify(identityRequest: identityRequest)
.then(
(IdentityApiResult successResponse) {
successResponse.user.setUserAttribute('first_name', 'Jane');
successResponse.user.setUserAttribute('last_name', 'Smith');
},
onError: (error) {
var failureResponse = error as IdentityAPIErrorResponse;
print("Failure Response: $failureResponse");
}
);
5. Set User AttributesDirect link to 5. Set User Attributes
Set user attributes progressively as the user navigates your app, not just at checkout. The more attributes you set, the better Rokt can resolve the customer and deliver relevant offers.
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';
// Retrieve the current user. This will only succeed if you have identified the user during SDK initialization or by calling the identify method.
var currentUser = await mpInstance?.getCurrentUser();
// Once you have successfully set the current user to `currentUser`, you can set user attributes with:
currentUser?.setUserAttribute(key: 'custom-attribute-name', value: 'custom-attribute-value');
// Note: all user attributes (including list attributes and tags) must have distinct names.
// Rokt recommends setting as many of the following user attributes as possible:
currentUser?.setUserAttribute(key: 'first_name', value: 'John');
currentUser?.setUserAttribute(key: 'last_name', value: 'Doe');
// Phone numbers can be formatted either as '1234567890', or '+1 (234) 567-8901'
currentUser?.setUserAttribute(key: 'mobile', value: '3125551515');
currentUser?.setUserAttribute(key: 'age', value: '33');
currentUser?.setUserAttribute(key: 'gender', value: 'M');
currentUser?.setUserAttribute(key: 'city', value: 'Brooklyn');
currentUser?.setUserAttribute(key: 'state', value: 'NY');
currentUser?.setUserAttribute(key: 'zip', value: '123456');
currentUser?.setUserAttribute(key: 'dob', value: 'yyyymmdd');
currentUser?.setUserAttribute(key: 'title', value: 'Mr');
currentUser?.setUserAttribute(key: 'language', value: 'en');
currentUser?.setUserAttribute(key: 'lifetime_value', value: '52.25');
currentUser?.setUserAttribute(key: 'predicted_ltv', value: '136.23');
// You can create a user attribute to contain a list of values
var attributeList = <String>[];
attributeList.add('documentary');
attributeList.add('comedy');
attributeList.add('romance');
attributeList.add('drama');
currentUser?.setUserAttributeArray(key: 'favorite-genres', value: attributeList);
// To remove a user attribute, call removeUserAttribute and pass in the attribute name. All user attributes share the same key space.
currentUser?.removeUserAttribute(key: 'attribute-to-remove');
User AttributesDirect link to User Attributes
Set as many of the following as you can collect:
Show all user attributes
| Attribute | Type | Description |
|---|---|---|
first_name | string | Customer's first name. Used for personalization. |
last_name | string | Customer's last name. Used for personalization. |
mobile | string | Phone number formatted as 1112345678 or +1 (222) 345-6789. Used for identity resolution and relevance. |
age | integer | Customer's age. Alternate to dob. Used for eligibility and relevance. |
dob | string | Date of birth, yyyymmdd. Alternate to age. Used for eligibility and relevance. |
gender | string | Customer's gender. For example, M, F, Male, or Female. Used for relevance. |
title | string | Honorific. For example, Mr, Mrs, Ms. Used for personalization. |
language | string | ISO 639-1 language code associated with the purchase. Used for relevance. |
city | string | Billing city. Used for relevance. |
state | string | Billing state / province / region. Used for relevance and eligibility. |
zip | string | Full ZIP or postcode (US preference is ZIP+4). Used for identity resolution and relevance. |
country | string | ISO 3166-1 alpha-2 country code (e.g. US, GB, AU). Used for eligibility and relevance. |
new_customer | boolean | Whether this is a first-time buyer. Used for relevance. |
customer_type | string | Whether the user is authenticated (guest / logged_in). Used for relevance. |
loyalty_tier | string | Partner loyalty program tier. Used for relevance and eligibility. |
loyalty_id | string | Loyalty program member ID. Used for identity resolution. |
lifetime_value | decimal | Customer's cumulative purchase value, as a string (e.g. "52.25"). Used for relevance. |
predicted_ltv | decimal | Predicted total lifetime value, typically from a partner ML model. Distinct from lifetime_value. Used for relevance. |
subscription_status | string | Subscription state if applicable (active, trial, churned, paused, none). Used for relevance and eligibility. |
customer_segment | string | Partner internal segmentation (e.g. vip, at_risk, new, reactivated). Used for relevance. |
utm_source | string | Marketing attribution source. Used for relevance. |
utm_medium | string | Marketing attribution medium. Used for relevance. |
utm_campaign | string | Marketing attribution campaign. Used for relevance. |
All user attributes (including list attributes) must have distinct names.
6. Track Funnel EventsDirect link to 6. Track Funnel Events
Track screen views, account lifecycle events, commerce events, and custom events so Rokt can maintain identity continuity and understand where each customer is in their journey.
Screen ViewsDirect link to Screen Views
Call mpInstance?.logScreenEvent() with the name of the screen (e.g. 'homepage', 'product detail page'). Include any additional custom attributes in the event's customAttributes map.
import 'package:mparticle_flutter_sdk/events/screen_event.dart';
ScreenEvent screenEvent = ScreenEvent(eventName: 'homepage')
..customAttributes = {'custom-attribute': 'custom-value'};
mpInstance?.logScreenEvent(screenEvent);
Account Lifecycle EventsDirect link to Account Lifecycle Events
Log account lifecycle events when the user signs up, logs in, or logs out so Rokt can maintain identity continuity across sessions and devices. Signup and login events accept a method attribute describing how the user signed up or logged in.
Supported lifecycle event typesDirect link to Supported lifecycle event types
Show lifecycle event types
| Lifecycle Event Type | When to trigger | Supported method values |
|---|---|---|
sign_up | New account created | email, social, guest |
login | User logs in | email, social, sso |
logout | User logs out | Not applicable. |
Example lifecycle eventsDirect link to Example lifecycle events
import 'package:mparticle_flutter_sdk/events/event_type.dart';
import 'package:mparticle_flutter_sdk/events/mp_event.dart';
// Signup event
MPEvent signupEvent = MPEvent(
eventName: 'sign_up',
eventType: EventType.Other)
..customAttributes = {'method': 'email'};
mpInstance?.logEvent(signupEvent);
// Login event
MPEvent loginEvent = MPEvent(
eventName: 'login',
eventType: EventType.Other)
..customAttributes = {'method': 'email'};
mpInstance?.logEvent(loginEvent);
// Logout event
MPEvent logoutEvent = MPEvent(
eventName: 'logout',
eventType: EventType.Other);
mpInstance?.logEvent(logoutEvent);
Commerce EventsDirect link to Commerce Events
Commerce events carry product-level details for the user's journey. Trigger a separate commerce event for each product action the customer takes.
Investing in full commerce event coverage is one of the highest-leverage things you can do during your integration. Each event tells Rokt something different about where the customer is in their journey: a product view signals exploration, an add-to-cart signals consideration, a checkout start signals purchase intent, and a completed purchase confirms conversion. With a richer signal, Rokt can personalize offers more effectively, measure placement performance accurately, and attribute conversions to the right touchpoints. Doing this work during your initial integration also avoids a retrofit later. The signal compounds over time: each event Rokt receives adds context used to sharpen personalization, improve attribution accuracy, and better resolve and segment your customer base on future visits.
Commerce events are logged with CommerceEvent, using a ProductActionType that identifies the customer action (viewing a product, adding to cart, starting checkout, completing a purchase, etc.). The sections below list the supported action types and walk through assembling the event.
Product action typesDirect link to Product action types
Show all product action types
| Customer action | Product action constant |
|---|---|
| Product detail page viewed | ProductActionType.ViewDetail |
| Product clicked | ProductActionType.Click |
| Item added to cart | ProductActionType.AddToCart |
| Item removed from cart | ProductActionType.RemoveFromCart |
| Item added to wishlist | ProductActionType.AddToWishList |
| Item removed from wishlist | ProductActionType.RemoveFromWishlist |
| Checkout flow initiated | ProductActionType.Checkout |
| Checkout option selected | ProductActionType.CheckoutOption |
| Order confirmed | ProductActionType.Purchase |
| Order refunded | ProductActionType.Refund |
Tracking a commerce event requires three steps:
1. Define the productDirect link to 1. Define the product
Create a Product with the product's name, SKU, and price. Set additional fields as needed.
import 'package:mparticle_flutter_sdk/events/product.dart';
// Create an optional map of custom attributes for the product
final customAttributes = {
'ocean-view': 'true',
'balcony': 'false',
};
Product product = Product(
name: 'Double Room - Econ Rate',
sku: 'econ-1',
price: 100.00,
);
product.quantity = 4;
// Include the map of custom attributes
product.attributes = customAttributes;
2. Summarize the transactionDirect link to 2. Summarize the transaction
Create a TransactionAttributes object for ProductActionType.Purchase, ProductActionType.Checkout, and ProductActionType.CheckoutOption events. Include shipping and coupon code when applicable — order-level coupons belong here, not on individual products.
import 'package:mparticle_flutter_sdk/events/transaction_attributes.dart';
final TransactionAttributes transactionAttributes = TransactionAttributes(
transactionID: 'ORDER-12345',
revenue: 149.99,
tax: 12.50,
shipping: 5.99,
couponCode: 'SUMMER20',
);
3. Log the commerce eventDirect link to 3. Log the commerce event
Create a CommerceEvent with a product action constant from the table above, attach the transactionAttributes, and log it.
import 'package:mparticle_flutter_sdk/events/commerce_event.dart';
import 'package:mparticle_flutter_sdk/events/product_action_type.dart';
CommerceEvent event = CommerceEvent.withProduct(
productActionType: ProductActionType.Purchase,
product: product,
);
event.transactionAttributes = transactionAttributes;
// Optional custom attributes for the purchase event
event.customAttributes = {'sale': 'true'};
mpInstance?.logCommerceEvent(event);
The same structure applies to every product action constant — swap ProductActionType.Purchase for the action that matches the customer behavior you're logging.
Custom EventsDirect link to Custom Events
Track custom events using MPEvent, passing an event name, event type, and optional custom attributes.
Supported custom event typesDirect link to Supported custom event types
Show custom event types
| Type | Use for |
|---|---|
EventType.Navigation | User navigation flows and screen transitions within your app. |
EventType.Location | Location-based interactions and movements. |
EventType.Search | Search queries and search-related actions. |
EventType.Transaction | Financial transactions and purchase-related activity. |
EventType.UserContent | User-generated content like reviews, comments, or posts. |
EventType.UserPreference | User settings, preferences, and customization choices. |
EventType.Social | Social media interactions and sharing activities. |
EventType.Other | Anything that doesn't fit the categories above. |
Example custom eventDirect link to Example custom event
import 'package:mparticle_flutter_sdk/events/event_type.dart';
import 'package:mparticle_flutter_sdk/events/mp_event.dart';
MPEvent event = MPEvent(
eventName: 'Video Watched',
eventType: EventType.Navigation)
..customAttributes = {
'category': 'Destination Intro',
'title': 'Paris',
};
mpInstance?.logEvent(event);
7. Show a PlacementDirect link to 7. Show a Placement
Call selectPlacements on every payment and confirmation screen you want Rokt to render content on. Include one of the following page identifiers to specify the screen type and whether it's for testing or production:
stg.rokt.conf: A confirmation screen in a staging (or testing) environment.prod.rokt.conf: A confirmation screen in a production environment.stg.rokt.payments: A payments screen in a staging (or testing) environment.prod.rokt.payments: A payments screen in a production environment.
Placement AttributesDirect link to Placement Attributes
Pass these attributes in the attributes map of selectPlacements. Always supply the most recent value — attributes passed here override any earlier setUserAttribute calls.
Show all placement attributes
| Attribute | Type | Description |
|---|---|---|
email | string | Customer email (unhashed). Used for identity resolution. |
first_name | string | Customer first name. Used for personalization. |
last_name | string | Customer last name. Used for personalization. |
mobile | string | Customer mobile number in E.164 format. Used for identity resolution. |
confirmation_ref | string | Order / confirmation reference number. Used for relevance and deduplication. |
currency | string | Transaction currency (ISO 4217, e.g. USD, GBP, AUD). Used for relevance. |
country | string | ISO 3166-1 alpha-2 country code. Used for eligibility and relevance. |
language | string | Customer's preferred language (ISO 639-1). Used for relevance. |
total_price | decimal | Total cart value including tax and shipping. Used for relevance. |
amount | string | Cart subtotal before tax and shipping. Distinct from total_price. Used for relevance. |
cart_item_count | integer | Number of items in the cart. Used for relevance. |
coupon_code | string | Promo code applied to the order, if any. Used for relevance. |
new_customer | boolean | Whether this is a first-time buyer. Used for relevance. |
customer_type | string | guest or logged_in. Used for relevance. |
lifetime_value | decimal | Customer's cumulative purchase value (e.g. "2340.00"). Used for relevance. |
subscription_status | string | Subscription state if applicable (active, trial, churned, paused, none). Used for relevance and eligibility. |
customer_segment | string | Partner internal segmentation (e.g. vip, at_risk, new, reactivated). Used for relevance. |
payment_type | string | Payment method selected (credit_card, paypal, apple_pay, etc.). Used for Pay+ eligibility. |
payment_service_provider | string | Payment services offered on the page (apple_pay, paypal, card). Used for Pay+ eligibility. |
ccbin | string | Credit card BIN (first 6 digits). Used for relevance. |
billing_address1 | string | Billing street address. Used for identity resolution and relevance. |
billing_address2 | string | Billing apartment / unit. Used for identity resolution. |
billing_city | string | Billing city. Used for relevance. |
billing_state | string | Billing state or province. Used for relevance. |
billing_zipcode | string | Billing ZIP / postcode. Used for identity resolution and relevance. |
shipping_method | string | Shipping method selected (standard, express, next_day). Used for relevance. |
shipping_address1 | string | Shipping street address. Used for relevance. |
shipping_city | string | Shipping city. Used for relevance. |
shipping_state | string | Shipping state or province. Used for relevance. |
shipping_zipcode | string | Shipping ZIP or postcode. Used for relevance. |
shipping_country | string | Shipping country (ISO 3166-1 alpha-2). Used for relevance. |
Overlay PlacementsDirect link to Overlay Placements
Overlay placements render on top of your confirmation screen in a Rokt-managed container, requiring no changes to your app's existing layout.
To insert an overlay placement, call selectPlacements once the confirmation screen loads:
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';
final attributes = {
// Identity
'email': 'j.smith@example.com',
'first_name': 'Jenny',
'last_name': 'Smith',
'mobile': '+13125551515',
// Transaction
'confirmation_ref': '54321',
'currency': 'USD',
'country': 'US',
'language': 'en',
'total_price': '149.99',
'cart_item_count': '2',
'coupon_code': 'SUMMER20',
// Customer context
'new_customer': 'false',
'customer_type': 'logged_in',
'lifetime_value': '2340.00',
'subscription_status': 'active',
'customer_segment': 'vip',
// Payment (include payment_type and payment_service_provider for Pay+)
'payment_type': 'credit_card',
'payment_service_provider': 'card',
'ccbin': '411112',
// Billing address
'billing_address1': '123 Main St',
'billing_city': 'Brooklyn',
'billing_state': 'NY',
'billing_zipcode': '11201',
// Shipping
'shipping_method': 'express',
'shipping_address1': '175 Varick St',
'shipping_city': 'New York',
'shipping_state': 'NY',
'shipping_zipcode': '10014',
'shipping_country': 'US',
};
final roktConfig = RoktConfig(
colorMode: ColorMode.light,
);
mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
roktConfig: roktConfig,
);
Embedded PlacementsDirect link to Embedded Placements
Embedded placements render inline at a fixed position in your app that you control (for example, above the payment options on a cart screen). Both Thanks and Pay+ use embedded placements, but Pay+ must use embedded placements.
Use the RoktLayout widget to embed a placement in your Flutter UI. The onLayoutCreated callback fires when the widget is created.
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';
final attributes = {
'email': 'j.smith@example.com',
'first_name': 'Jenny',
'last_name': 'Smith',
'billing_zipcode': '90210',
'confirmation_ref': '54321',
};
const RoktLayout(
placeholderName: 'RoktEmbedded1',
onLayoutCreated: () {
// Layout created
}
);
mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
);
For Pay+ placements, include payment_type and payment_service_provider in the selectPlacements call on each screen. payment_service_provider communicates what payment methods are available on the payment screen; payment_type communicates what method the user paid with.
Interstitial placements (Shoppable Ads) are not supported on Android in the Flutter SDK. Interstitial placements are available on iOS only.
Optional FunctionsDirect link to Optional Functions
| Function | Purpose |
|---|---|
Rokt.close() | Auto-close overlay placements. |
Additional ConfigurationDirect link to Additional Configuration
Pass optional parameters such as RoktConfig to customize the placement UI (e.g. dark/light mode, caching). Font file paths can also be supplied as a map of PostScript names to asset paths.
// If you want to use custom fonts for your placement, create a fontTypefaces map
final fontTypefaces = {'Arial-Bold': 'fonts/Arial-Bold.ttf'};
final roktConfig = RoktConfig(
colorMode: ColorMode.light,
);
mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
fontFilePathMap: fontTypefaces,
roktConfig: roktConfig,
);
If you want to update the identifier RoktExperience or embedded identifier RoktEmbedded1 with a different value, contact your Rokt account manager to ensure Rokt placements are configured consistently.
Events APIDirect link to Events API
The SDK provides placement lifecycle events as a stream through the MPRoktEvents EventChannel. Subscribe to this stream to respond to placement load state, engagement, and failures.
final EventChannel roktEventChannel = EventChannel('MPRoktEvents');
roktEventChannel.receiveBroadcastStream().listen((dynamic event) {
debugPrint('rokt_event: $event');
});
Standard eventsDirect link to Standard events
Show all standard events
| Event | Description | Params |
|---|---|---|
| ShowLoadingIndicator | Triggered before the SDK calls the Rokt backend. | |
| HideLoadingIndicator | Triggered when the SDK receives a success or failure from the Rokt backend. | |
| PlacementInteractive | Triggered when a placement has been rendered and is interactable. | identifier: String |
| PlacementReady | Triggered when a placement is ready to display but has not rendered content yet. | identifier: String |
| OfferEngagement | Triggered when the user engages with the offer. | identifier: String |
| PositiveEngagement | Triggered when the user positively engages with the offer. | identifier: String |
| FirstPositiveEngagement | Triggered when the user positively engages with the offer for the first time. | identifier: String, fulfillmentAttributes: FulfillmentAttributes |
| OpenUrl | Triggered when the user presses a URL that is configured to be sent to the partner app. | identifier: String, url: String |
| PlacementClosed | Triggered when a placement is closed by the user. | identifier: String |
| PlacementCompleted | Triggered when the offer progression reaches the end and no more offers are available to display. Also triggered when cache is hit but the retrieved placement will not be displayed as it has previously been dismissed. | identifier: String |
| PlacementFailure | Triggered when a placement could not be displayed due to some failure or when no placements are available to show. | identifier: String (optional) |
| EmbeddedSizeChanged | Triggered when an embedded placement's height changes. | identifier: String, selectedHeight: Double |
| CartItemInstantPurchase | Triggered when the catalog item purchase is initiated by the user. | identifier: String, catalogItemId: String, cartItemId: String, totalPrice: String, currency: String |
8. Test Your IntegrationDirect link to 8. Test Your Integration
To confirm the SDK initializes and events log correctly:
- Enable verbose SDK logging before initialization so you can see what's being sent.
- Build and run your app with the development environment set:
MParticle.Environment.Development. - Trigger
selectPlacementson the screen where the placement should render and confirm the placement loads. - Verify events appear in your mParticle workspace's Live Stream, and confirm the identify call succeeds.
- Check Android Studio's Logcat for Rokt SDK log output.
// Enable mParticle debug logging at the Dart level
MparticleFlutterSdk.setLogLevel(LogLevel.verbose);
TroubleshootingDirect link to Troubleshooting
If the placement doesn't render or events don't appear, check Android Studio's Logcat for Rokt SDK errors. Common issues:
Initialization errorsDirect link to Initialization errors
- Confirm the
your-keyandyour-secretcredentials match the values from your Rokt account manager. - Confirm native SDK initialization runs before any
selectPlacementsorlogEventcall from your Dart code. - Confirm your root Activity extends
FlutterFragmentActivity.
Identity errorsDirect link to Identity errors
If the identify call's onError handler fires, inspect the IdentityAPIErrorResponse for the status code and retry the request according to your business logic. Without error handling you may see data consistency issues at scale.
Placement not renderingDirect link to Placement not rendering
- Confirm the placement
identifier(e.g.RoktExperience) matches what your Rokt account manager configured. - For embedded placements, confirm the embedded view identifier (e.g.
RoktEmbedded1) matches the layout configuration. - Check that the attributes map contains at least
email,first_name,last_name,billing_zipcode, andconfirmation_ref.
AppendixDirect link to Appendix
Appendix A: App ConfigurationDirect link to Appendix A: App Configuration
Applications can pass configuration settings through RoktConfig so the SDK uses your app's custom configuration instead of system defaults.
ColorMode objectDirect link to ColorMode object
| Value | Description |
|---|---|
light | Application is in Light Mode |
dark | Application is in Dark Mode |
system | Application defaults to System Color Mode |
final roktConfig = RoktConfig(
colorMode: ColorMode.light,
);
mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
roktConfig: roktConfig,
);
EdgeToEdgeDisplayDirect link to EdgeToEdgeDisplay
| Value | Description |
|---|---|
true (default) | Application supports Edge to Edge display mode |
false | Application does not support Edge to Edge display mode |
When building the native RoktConfig on Android, call edgeToEdgeDisplay(true) on the RoktConfig.Builder to enable edge-to-edge mode:
import com.mparticle.MParticle
import com.mparticle.rokt.RoktConfig
val roktConfig = RoktConfig.Builder()
.edgeToEdgeDisplay(true)
.build()
MParticle.getInstance()?.Rokt()?.selectPlacements(
identifier = "RoktExperience",
attributes = attributes,
config = roktConfig
)
CacheConfig objectDirect link to CacheConfig object
| Parameter | Description |
|---|---|
cacheDurationInSeconds | Optional duration in seconds for which the Rokt SDK should cache the experience. Maximum allowed value is 90 minutes; default is 90 minutes if not provided or invalid. |
cacheAttributes | Optional attributes to be used as cache key. If null, all attributes sent in selectPlacements will be used as the cache key. |
// Cache the experience for 1200 seconds, using email and orderNumber as the cache key.
final roktConfig = RoktConfig(
cacheConfig: CacheConfig(
cacheDurationInSeconds: 1200,
cacheAttributes: {'email': 'j.smith@example.com', 'orderNumber': '123'},
),
);
mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
roktConfig: roktConfig,
);
Appendix B: Jetpack Compose Support with RoktLayoutDirect link to Appendix B: Jetpack Compose Support with RoktLayout
For screens implemented using Jetpack Compose, the SDK provides the RoktLayout component, enabling a modern, declarative integration of Rokt placements within Android applications.
The RoktLayout class offers a Compose-compatible interface for displaying Rokt placements, allowing developers to use Compose API syntax without the need to manually invoke selectPlacements. It supports Overlay, BottomSheet, and Embedded placement types.
import com.mparticle.kits.RoktLayout
import com.mparticle.MpRoktEventCallback
import com.mparticle.UnloadReasons
@Composable
fun MainScreen(modifier: Modifier = Modifier) {
Column(
modifier = modifier
.background(Color.LightGray)
.padding(8.dp),
) {
val attributes = mapOf(
"email" to "j.smith@example.com",
"firstname" to "Jenny",
"lastname" to "Smith",
"mobile" to "(323) 867-5309",
"postcode" to "90210",
"country" to "US"
)
val callbacks = object : MpRoktEventCallback {
override fun onLoad() = println("View loaded")
override fun onUnload(reason: UnloadReasons) = println("View unloaded due to: $reason")
override fun onShouldShowLoadingIndicator() = println("Show loading indicator")
override fun onShouldHideLoadingIndicator() = println("Hide loading indicator")
}
val roktConfig = RoktConfig.Builder()
.colorMode(RoktConfig.ColorMode.DARK)
.cacheConfig(CacheConfig(
cacheDurationInSeconds = 1200,
cacheAttributes = mapOf("email" to "j.smith@example.com")
))
.build()
RoktLayout(
sdkTriggered = true,
identifier = "RoktExperience",
attributes = attributes,
location = "Location1",
modifier = Modifier
.fillMaxWidth()
.background(Color.Black),
mpRoktEventCallback = callbacks,
config = roktConfig
)
}
}
| Parameter | Type | Description |
|---|---|---|
sdkTriggered | Boolean | Controls when the placement should be triggered. |
identifier | String | The identifier of the Rokt view/experience (e.g., "RoktExperience"). |
location | String? | Optional location name for embedded placements (e.g., "Location1"). |
attributes | Map<String, String> | Map of attributes to pass to the placement. |
modifier | Modifier | Compose Modifier to customize layout, styling, and UI behavior. |
callbacks | MpRoktEventCallback | Optional callback to handle placement events (load, unload, loading state). |
Appendix C: Error HandlingDirect link to Appendix C: Error Handling
The IDSync API is intended to be central to your app's state and is designed to be fast and highly-available. Similar to how your app may prevent users from logging in, logging out, or modifying their state without an internet connection — treat these APIs as gating operations to maintain a consistent user state. The SDK will not retry API calls automatically, but provides callback APIs so you can do so according to your business logic.
If you do not implement error handling, you may see data consistency issues at scale.
import 'package:mparticle_flutter_sdk/identity/identity_api_result.dart';
import 'package:mparticle_flutter_sdk/identity/identity_api_error_response.dart';
mpInstance?.identity
.identify(identityRequest: identityRequest)
.then(
(IdentityApiResult successResponse) {
// Proceed with the identified user
},
onError: (error) {
var failureResponse = error as IdentityAPIErrorResponse;
// Inspect failureResponse.statusCode to determine the error type:
// - Check for network errors (device offline) and retry the request
// - Check for throttle errors (429) and retry with backoff
print('Identity error: $failureResponse');
}
);
The SDK returns IdentityApi.UNKNOWN_ERROR for client-side issues including device out of coverage, client-side timeout, or invalid identity requests. Check for THROTTLE_ERROR (HTTP 429) and retry with backoff when encountered.
Appendix D: Passing Session ID from Web to NativeDirect link to Appendix D: Passing Session ID from Web to Native
When a user journey spans both web and native platforms, you can maintain a consistent Rokt session by passing the session ID from the Web SDK to the mParticle Flutter SDK. This is useful for hybrid flows where users complete an action in a WebView (such as a payment page) and return to the native app for confirmation.
Getting the session ID from Web SDKDirect link to Getting the session ID from Web SDK
After calling selectPlacements, the session ID is available on the selection context:
const selection = await launcher.selectPlacements({
identifier: "checkout",
attributes: {
email: "user@example.com",
// ... other attributes
}
});
const sessionId = await selection.context.sessionId;
Passing to native app via deep linkDirect link to Passing to native app via deep link
Pass the session ID to your native app using a deep link:
const deepLink = `myapp://confirmation?sessionId=${encodeURIComponent(sessionId)}`;
window.location.href = deepLink;
Setting the session ID on AndroidDirect link to Setting the session ID on Android
Extract the session ID from the deep link and pass it to the native mParticle SDK before calling selectPlacements. Add this to your MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
intent.data?.getQueryParameter("sessionId")?.let { sessionId ->
MParticle.getInstance()?.Rokt()?.setSessionId(sessionId)
}
// Proceed with your confirmation flow
}
NotesDirect link to Notes
- Call
setSessionIdbeforeselectPlacementsto ensure the session is used. - Empty strings are ignored and will not update the session.
- Always URL-encode the session ID when passing as a query parameter.
1. Initialize the Rokt SDKDirect link to 1. Initialize the Rokt SDK
Include the SDK initialization script on every page of your site. Browser caching means the SDK loads from cache on subsequent pages rather than re-fetching.
- Single-page Applications (SPA): Insert the script into the
<head>of your mainindex.html, or wherever your content is rendered. - Multi-page Applications (MPA): Place the script in your primary shared layout file. If you don't use a template-based rendering system, add it to each HTML file.
First-Party Domain ConfigurationDirect link to First-Party Domain Configuration
Using a first-party domain when integrating the SDK into your site ensures that the Rokt SDK uses your own domain when making calls to Rokt's API, providing your customers with a seamless experience and minimizing the risk of blocked content.
To learn how to configure a first-party domain for your SDK integration, see First Party Domain Integration.
SDK Initialization ScriptDirect link to SDK Initialization Script
- Replace
"YOUR_API_KEY"with the API key provided by your dedicated Rokt team. - Set
DOMAINto the subdomain you created during your first-party domain configuration. This is optional: if you leave the default DOMAIN setting, requests will be routed throughapps.rokt-api.com.
<script type="text/javascript">
// Enter your Rokt API key
const API_KEY = "YOUR_API_KEY";
// Enter your custom subdomain if you are using a first-party domain configuration (optional)
const ROKT_DOMAIN = "https://apps.rokt-api.com";
window.mParticle = {
config: {
// Set the data environment:
// Set isDevelopmentMode to true if you are still testing your integration.
// Set isDevelopmentMode to false if your integration is ready for production data.
isDevelopmentMode: true,
// Identify the current user:
// If you do not have the user's email address, you can pass in a null value
identifyRequest: {
userIdentities: {
// If you're using an un-hashed email address, set it in 'email' (preferred).
email: 'j.smith@example.com',
// If you're using a hashed email address, set it in 'other' instead of `email`.
other: 'sha256 hashed email goes here',
// Customer phone number in E.164 format.
mobile_number: '+13125551515',
// Partner's internal customer/account identifier (if the user is logged in).
customerid: 'cust_10482'
}
},
// If the user is identified with their email address, set additional user attributes.
identityCallback: function(result) {
if (result.getUser()) {
result.getUser().setUserAttribute('attribute_key', 'attribute_value');
}
}
}
};
// Load the SDK
(function(e) { window.mParticle = window.mParticle || {}; window.mParticle.EventType = { Unknown: 0, Navigation: 1, Location: 2, Search: 3, Transaction: 4, UserContent: 5, UserPreference: 6, Social: 7, Other: 8, Media: 9 }; window.mParticle.eCommerce = { Cart: {} }; window.mParticle.Identity = {}; window.mParticle.Rokt = {}; window.mParticle.config = window.mParticle.config || {}; window.mParticle.config.rq = []; window.mParticle.config.snippetVersion = 2.8; window.mParticle.ready = function(e) { window.mParticle.config.rq.push(e); }; ["endSession", "logError", "logBaseEvent", "logEvent", "logForm", "logLink", "logPageView", "setSessionAttribute", "setAppName", "setAppVersion", "setOptOut", "setPosition", "startNewSession", "startTrackingLocation", "stopTrackingLocation"].forEach(function(e) { window.mParticle[e] = function() { var t = Array.prototype.slice.call(arguments); t.unshift(e); window.mParticle.config.rq.push(t); }; }); ["setCurrencyCode", "logCheckout"].forEach(function(e) { window.mParticle.eCommerce[e] = function() { var t = Array.prototype.slice.call(arguments); t.unshift("eCommerce." + e); window.mParticle.config.rq.push(t); }; }); ["identify", "login", "logout", "modify"].forEach(function(e) { window.mParticle.Identity[e] = function() { var t = Array.prototype.slice.call(arguments); t.unshift("Identity." + e); window.mParticle.config.rq.push(t); }; }); ["selectPlacements","hashAttributes","hashSha256","setExtensionData","use","getVersion","terminate","onShoppableAdsReady"].forEach(function(e) { window.mParticle.Rokt[e] = function() { var t = Array.prototype.slice.call(arguments); t.unshift("Rokt." + e); window.mParticle.config.rq.push(t); }; }); var t = window.mParticle.config.isDevelopmentMode ? 1 : 0, n = "?env=" + t, a = window.mParticle.config.dataPlan; if (a) { var o = a.planId, r = a.planVersion; o && (r && (r < 1 || r > 1e3) && (r = null), n += "&plan_id=" + o + (r ? "&plan_version=" + r : "")); } var i = window.mParticle.config.versions, s = []; i && Object.keys(i).forEach(function(e) { s.push(e + "=" + i[e]); }); var c = document.createElement("script"); c.type = "text/javascript"; c.async = !0; window.ROKT_DOMAIN = ROKT_DOMAIN || 'https://apps.rokt-api.com'; mParticle.config.domain = ROKT_DOMAIN.split('//')[1]; c.src = ROKT_DOMAIN + "/js/v2/" + e + "/app.js" + n + "&" + s.join("&"); c.onerror = function() { var u = ["https://apps.","rokt","ecommerce",".com"].join(""); window.ROKT_DOMAIN = u; mParticle.config.domain = u.split("//")[1]; var d = document.createElement("script"); d.type = "text/javascript"; d.async = !0; d.src = u + "/js/v2/" + e + "/app.js" + n + "&" + s.join("&"); var f = document.getElementsByTagName("script")[0]; f.parentNode.insertBefore(d, f); }; var l = document.getElementsByTagName("script")[0]; l.parentNode.insertBefore(c, l); })(API_KEY);
</script>
The initialization script includes the following configuration settings:
isDevelopmentModeDirect link to isDevelopmentMode
Set isDevelopmentMode to true while testing your integration to collect "development" data. When you are ready to go live, set it to false to collect and send production data to Rokt.
identifyRequestDirect link to identifyRequest
The SDK allows you to identify the current user by including their email address at the time the SDK is initialized. Rokt recommends using your customer's raw (unhashed) email address. Include mobile_number and customerid when available — more signals improve identity resolution.
identityCallbackDirect link to identityCallback
Use the identityCallback to set additional user attributes once the user is identified. If you don't have the user's email at initialization, set email to null — the SDK will still initialize, and you can identify the user later via Step 2: Identify the User.
2. Identify the UserDirect link to 2. Identify the User
Call mParticle.Identity.identify with a fresh identifyRequest any time the user provides their email address after the SDK has initialized (for example, when they log in, create an account, or make a purchase). This ensures that event data is attributed to the correct user.
Supported User IdentifiersDirect link to Supported User Identifiers
Show supported user identifiers
| Field | Type | Description |
|---|---|---|
email | string | Use email to integrate the customer's raw, unhashed email address. |
other | string | Use other to integrate a SHA-256-hashed email address. Only use this when the raw email cannot be provided. |
mobile_number | string | Use mobile_number to integrate the customer's phone number in E.164 format (e.g. +13125551515). |
customerid | string | Use customerid to integrate your own internal customer/account identifier. Send on every page for logged-in users. |
To identify the user:
-
Create an
identifyRequestobject to contain the user's identifiers. Integrate the user's raw, unhashed email address into theemailfield. -
To set additional user attributes, create an
identityCallback. If theidentifyRequestsucceeds, any user attributes you set inside the callback are assigned to the identified user. -
After creating the
identifyRequestand theidentityCallback, send them to Rokt using themParticle.Identity.identifymethod.For example, to identify a user named Jane Smith with the email address
j.smith@example.com, mobile number+13125551515, and customer IDcust_10482, you would use:Identify Jane Smith// 1. Create the identifyRequest object
const identifyRequest = {
userIdentities: {
email: 'j.smith@example.com',
// If you are passing a hashed email address, set it inside the 'other' field
other: 'SHA-256 hashed email address',
mobile_number: '+13125551515',
customerid: 'cust_10482'
}
};
// 2. User attributes are set using identityCallback
const identityCallback = function(result) {
if (result.getUser()) {
result.getUser().setUserAttribute('first_name', 'Jane');
result.getUser().setUserAttribute('last_name', 'Smith');
}
};
// 3. Call the identify method, including the identifyRequest object and identityCallback
mParticle.Identity.identify(identifyRequest, identityCallback);
3. Set User AttributesDirect link to 3. Set User Attributes
Set user attributes progressively as the user navigates your site, not just at checkout. The more attributes you set, the better Rokt can resolve the customer and deliver relevant offers.
// To retrieve the current user, call getCurrentUser.
const currentUser = mParticle.Identity.getCurrentUser();
// Once you have successfully set the current user to a const called `currentUser`, you can set user attributes with:
currentUser.setUserAttribute("first_name", "Jane");
currentUser.setUserAttribute("last_name", "Smith");
currentUser.setUserAttribute("mobile", "+13125551515");
currentUser.setUserAttribute("birth_year", 1990);
currentUser.setUserAttribute("gender", "F");
// Address attributes (collect the billing address at checkout)
currentUser.setUserAttribute("billing_address1", "123 Main St");
currentUser.setUserAttribute("billing_address2", "Apt 4B");
currentUser.setUserAttribute("billing_city", "Brooklyn");
currentUser.setUserAttribute("billing_state", "NY");
currentUser.setUserAttribute("billing_zipcode", "11201");
currentUser.setUserAttribute("country", "US");
// Lifecycle and loyalty attributes
currentUser.setUserAttribute("customer_type", "logged_in");
currentUser.setUserAttribute("new_customer", false);
currentUser.setUserAttribute("loyalty_tier", "gold");
currentUser.setUserAttribute("loyalty_id", "LOY-7781");
currentUser.setUserAttribute("lifetime_value", 2340.00);
currentUser.setUserAttribute("customer_segment", "vip");
// Marketing attribution
currentUser.setUserAttribute("utm_source", "google");
currentUser.setUserAttribute("utm_medium", "cpc");
currentUser.setUserAttribute("utm_campaign", "spring_sale");
// To set a list attribute, set the value of the attribute to an array of strings. For example:
currentUser.setUserAttribute("favorite_genres", ["documentary", "comedy", "romance", "drama"]);
// To remove a user attribute, call removeUserAttribute and pass in the attribute name. All user attributes share the same key space.
currentUser.removeUserAttribute("attribute_to_remove");
User AttributesDirect link to User Attributes
Set as many of the following as you can collect:
Show all user attributes
| Field | Type | Description |
|---|---|---|
first_name | string | Customer's first name. Used for personalization. |
last_name | string | Customer's last name. Used for personalization. |
mobile | string | Phone number formatted as 1112345678 or +1 (222) 345-6789. Used for identity resolution and relevance. |
birth_year | integer | Customer's birth year (e.g. 1990). Preferred date-of-birth field. Alternates: dob (yyyymmdd), age. Used for eligibility and relevance. |
dob | string | Date of birth, yyyymmdd. Alternate to birth_year. Used for eligibility and relevance. |
age | integer | Customer's age. Alternate to birth_year. Used for eligibility and relevance. |
gender | string | Customer's gender. For example, M, F, Male, or Female. Used for relevance. |
title | string | Honorific. For example, Mr, Mrs, Ms. Used for personalization. |
language | string | ISO 639-1 language code associated with the purchase. Used for relevance. |
billing_address1 | string | Street address (e.g. 123 Main St). Used for identity resolution and relevance. |
billing_address2 | string | Apartment/unit (e.g. Apt 4B). Used for identity resolution. |
billing_city | string | Billing city. Used for relevance. |
billing_state | string | Billing state / province / region. Used for relevance and eligibility. |
billing_zipcode | string | Full ZIP or postcode (US preference is ZIP+4). Used for identity resolution and relevance. |
country | string | ISO 3166-1 alpha-2 country code (e.g. US, GB, AU). Used for eligibility and relevance. |
new_customer | boolean | Whether this is a first-time buyer (true / false). Used for relevance. |
customer_type | string | Whether the user is authenticated (guest / logged_in). Used for relevance. |
loyalty_tier | string | Partner loyalty program tier. Used for relevance and eligibility. |
loyalty_id | string | Loyalty program member ID. Used for identity resolution. |
lifetime_value | decimal | Customer's cumulative purchase value (e.g. 2340.00). Used for relevance. |
predicted_ltv | decimal | Predicted total lifetime value. Distinct from lifetime_value. Used for relevance. |
subscription_status | string | Subscription state if applicable (active, trial, churned, paused, none). Used for relevance and eligibility. |
customer_segment | string | Partner internal segmentation (e.g. vip, at_risk, new, reactivated). Used for relevance. |
utm_source | string | Marketing attribution source. Used for relevance. |
utm_medium | string | Marketing attribution medium. Used for relevance. |
utm_campaign | string | Marketing attribution campaign. Used for relevance. |
utm_content | string | Marketing attribution content variant. Used for relevance. |
utm_term | string | Marketing attribution term / keyword. Used for relevance. |
referrer | string | Referring URL — intent signal. Used for relevance. |
acquisition_channel | string | How the customer was originally acquired. Used for relevance. |
All user attributes (including list attributes and tags) must have distinct names.
4. Track Funnel EventsDirect link to 4. Track Funnel Events
Track page views, account lifecycle events, commerce events, and custom events so Rokt can maintain identity continuity and understand where each customer is in their journey.
Page ViewsDirect link to Page Views
Call logPageView() after the SDK has initialized to log page navigation.
Page view event attributesDirect link to Page view event attributes
Show page view event attributes
| Field | Type | Description |
|---|---|---|
screen_name | string | Last segment of the URL path (e.g. /products/shoes → shoes). Defaults to home if the path is empty. |
page_type | string | Type of page being viewed: home, PLP, PDP, cart, checkout, confirmation. |
url | string | Full URL of the current page. |
title | string | Page title (from document.title). |
site_section | string | Top-level site section (e.g. mens, womens, support). |
referring_page | string | Referring URL captured from document.referrer. |
Example page view eventDirect link to Example page view event
// Wait for the SDK to be fully loaded before logging the event
window.mParticle.ready(function() {
mParticle.logPageView(
"page view",
{
"screen_name": location.pathname.split("/").filter(Boolean).pop() || "home",
"page_type": "PDP",
"url": window.location.toString(),
"title": document.title,
"site_section": "mens",
"referring_page": document.referrer
}
);
});
Account Lifecycle EventsDirect link to Account Lifecycle Events
Log account lifecycle events when the user signs up, logs in, or logs out so Rokt can maintain identity continuity across sessions and devices.
Supported lifecycle event typesDirect link to Supported lifecycle event types
Show lifecycle event types
| Lifecycle Event Type | When to trigger | Supported method values |
|---|---|---|
sign_up | New account created | email, social, guest |
login | User logs in | email, social, sso |
logout | User logs out | Not applicable. |
Example lifecycle eventsDirect link to Example lifecycle events
// Signup event
mParticle.logEvent("sign_up", mParticle.EventType.Other, { method: "email" });
// Login event
mParticle.logEvent("login", mParticle.EventType.Other, { method: "email" });
// Logout event
mParticle.logEvent("logout", mParticle.EventType.Other);
Commerce EventsDirect link to Commerce Events
Commerce events carry product-level details for the user's journey. Trigger a separate commerce event for each product action the customer takes.
Investing in full commerce event coverage is one of the highest-leverage things you can do during your integration. Each event tells Rokt something different about where the customer is in their journey: a product view signals exploration, an add-to-cart signals consideration, a checkout start signals purchase intent, and a completed purchase confirms conversion. With a richer signal, Rokt can personalize offers more effectively, measure placement performance accurately, and attribute conversions to the right touchpoints.
Three event types (PLP impressions, cart page views, and site searches) are logged using dedicated methods. All other commerce events use the logProductAction method.
Product listing page (PLP) or category page viewDirect link to Product listing page (PLP) or category page view
Log each visible product as a product impression using mParticle.eCommerce.logImpression. Pass all products visible on the page in a single call.
var product = mParticle.eCommerce.createProduct('Product A', 'SKU-001', 29.99, null, null, 'Shoes', 'BrandX', 1);
mParticle.eCommerce.logImpression(
{ Name: 'Mens Running Shoes', Products: [product] },
{ currency: 'USD' }
);
Cart page viewDirect link to Cart page view
mParticle.logEvent(
"view_cart",
mParticle.EventType.Other,
{
cart_item_count: 2,
total_price: 149.99,
currency: "USD",
coupon_code: "SUMMER20",
cart_items: [
{ cart_item_id: "SKU-001", product_sku: "SKU-001", product_name: "Product A", item_price: 99.99, quantity: 1 }
]
}
);
Site searchDirect link to Site search
mParticle.logEvent(
"search",
mParticle.EventType.Search,
{ search_string: "blue running shoes", result_count: 24 }
);
Standard commerce eventsDirect link to Standard commerce events
Standard commerce events are logged with logProductAction, using a ProductActionType that identifies the customer action.
Product action typesDirect link to Product action types
Show all product action types
| Customer action | Product action type | Product-level fields | Transaction-level fields |
|---|---|---|---|
| Product detail page viewed | ViewDetail | product_sku, product_name, item_price | currency, list_name |
| Item added to cart | AddToCart | product_sku, quantity, item_price | currency, coupon_code |
| Item removed from cart | RemoveFromCart | product_sku, quantity | currency |
| Checkout flow initiated | Checkout | Full cart_items array | total_price, cart_item_count, currency, coupon_code |
| Order confirmed | Purchase | Full cart_items array | order_id, total_price, total_tax, shipping, coupon_code, currency |
| Order refunded | Refund | product_sku, quantity for refunded lines | order_id, total_price, currency |
Cart itemsDirect link to Cart items
cart_items is a JSON array of cart-line objects. Send a real JSON array — do not stringify it.
Show all cart item fields
| Field | Type | Description |
|---|---|---|
cart_item_id | string | Stable partner-side cart-line identifier. |
product_sku | string | Product SKU / stock identifier. |
product_name | string | Product display name. |
product_category | string | Product category / taxonomy leaf. |
product_brand | string | Product brand. |
product_variant | string | Variant identifier (size, color, etc.). |
item_price | decimal | Per-unit price at event time. |
unit_price | decimal | Per-unit list price pre-discount. Omit if equal to item_price. |
quantity | integer | Units in this line. |
currency | string | ISO 4217 code. Omit if matches the top-level currency. |
coupon_code | string | Coupon applied to this line (if any). |
product_position | integer | 1-indexed rank of the product within a list or search results. |
1. Define the productDirect link to 1. Define the product
var product1 = mParticle.eCommerce.createProduct(
'Double Room - Econ Rate', // Name
'econ-1', // SKU
100.00, // Price
4, // Quantity
'variant', // Variant
'room', // Category
'lodge-o-rama', // Brand
'banner', // Position
null, // Coupon code
{ 'ocean-view': true, 'balcony': false }
);
2. Summarize the transactionDirect link to 2. Summarize the transaction
var transactionAttributes = {
Id: 'ORDER-12345',
Revenue: 149.99,
Tax: 12.50,
Shipping: 5.99,
Coupon: 'SUMMER20'
};
3. Log the commerce eventDirect link to 3. Log the commerce event
mParticle.eCommerce.logProductAction(
mParticle.ProductActionType.Purchase,
[product1],
{ 'sale': true },
null,
transactionAttributes
);
Multi-product exampleDirect link to Multi-product example
const product1 = mParticle.eCommerce.createProduct('Product A', 'SKU-001', 99.99, 1);
product1.Category = 'Electronics';
product1.Brand = 'BrandX';
product1.Variant = 'red-L';
product1.Attributes = {
unit_price: 109.99,
coupon_code: 'LINE10'
};
const product2 = mParticle.eCommerce.createProduct('Product B', 'SKU-002', 24.99, 2);
product2.Category = 'Accessories';
mParticle.eCommerce.logProductAction(
mParticle.ProductActionType.Purchase,
[product1, product2],
{ channel: 'web' },
null,
{
Id: 'ORDER-12345',
Revenue: 149.97,
Tax: 12.50,
Shipping: 5.99,
Coupon: 'SUMMER20'
}
);
Custom EventsDirect link to Custom Events
Track custom events with logEvent, passing an event name, event type, and attributes object.
mParticle.logEvent(
'event-name',
mParticle.EventType.Other,
{
'custom-attribute-name': 'custom-attribute-value'
}
);
5. Show a PlacementDirect link to 5. Show a Placement
Call selectPlacements on every payment and confirmation page you want Rokt to render content on. Include one of the following page identifiers to specify the page type and whether it's for testing or production:
stg.rokt.conf: A confirmation page in a staging (or testing) environment.prod.rokt.conf: A confirmation page in a production environment.stg.rokt.payments: A payments page in a staging (or testing) environment.prod.rokt.payments: A payments page in a production environment.
Placement AttributesDirect link to Placement Attributes
Include all of the following attributes when inserting overlay, embedded, or interstitial placements. Attributes passed in selectPlacements override any earlier values set via setUserAttribute.
Show all placement attributes
| Field | Type | Description |
|---|---|---|
email | string | Customer email address (unhashed). Used for identity resolution and Shoppable Ads order confirmation. |
first_name | string | Customer first name. Used for personalization and Shoppable Ads order fulfillment. |
last_name | string | Customer last name. Used for personalization and Shoppable Ads order fulfillment. |
mobile | string | Customer mobile number (E.164 format, e.g. +13125551515). Used for identity resolution and Shoppable Ads. |
confirmationref | string | Order / confirmation reference number. Used for relevance, deduplication, and Shoppable Ads order reconciliation. |
currency | string | Transaction currency (ISO 4217, e.g. USD, GBP, AUD, JPY). Used for relevance and Shoppable Ads. |
country | string | ISO 3166-1 alpha-2 country code. Used for eligibility and relevance. |
language | string | Customer's preferred language (ISO 639-1, e.g. en, de, fr). Used for relevance. |
total_price | decimal | Total cart value including tax and shipping. Used for relevance. |
amount | decimal | Cart subtotal before tax and shipping. Distinct from total_price. Required for Pay+ on the payments page; also used by Shoppable Ads. |
cart_item_count | integer | Number of items in cart. Used for relevance. |
cartItems | array | Structured array of cart-line objects. See Cart items under Commerce Events. Used for relevance. |
coupon_code | string | Promo code applied, if any. Used for relevance. |
new_customer | boolean | Whether this is a first-time buyer. Used for relevance. |
customer_type | string | Whether the user is authenticated (guest / logged_in). Used for relevance. |
lifetime_value | decimal | Customer cumulative purchase value. Used for relevance. |
subscription_status | string | Subscription state if applicable (active, trial, churned, paused, none). Used for relevance and eligibility. |
customer_segment | string | Partner internal segmentation (vip, at_risk, new, reactivated). Used for relevance. |
payment_type | string | Payment method selected (credit_card, paypal, apple_pay, gift_card). Used for Pay+ eligibility and Shoppable Ads payment method prioritization. |
payment_service_provider | string | Comma-separated list of payment methods accepted on the page. Used for Pay+ eligibility. |
ccbin | string | Credit card BIN (first 6 digits). Used for relevance. |
shipping_method | string | Shipping method selected (standard, express, next_day). Used for relevance. |
shipping_address1 | string | Shipping street address. Used for relevance and Shoppable Ads order fulfillment. |
shipping_city | string | Shipping city. Used for relevance and Shoppable Ads order fulfillment. |
shipping_state | string | Shipping state / region. Used for relevance and Shoppable Ads order fulfillment. |
shipping_zipcode | string | Shipping ZIP / postcode. Used for relevance and Shoppable Ads order fulfillment. |
shipping_country | string | Shipping country (ISO 3166-1 alpha-2). Used for relevance and Shoppable Ads order fulfillment. |
billing_address1 | string | Billing street address. Used for identity resolution and relevance. |
billing_address2 | string | Billing apartment/unit. Used for identity resolution. |
billing_city | string | Billing city. Used for relevance. |
billing_state | string | Billing state / region. Used for relevance. |
billing_zipcode | string | Billing ZIP / postcode. Used for identity resolution, relevance, and Shoppable Ads. |
Overlay PlacementsDirect link to Overlay Placements
Overlay placements render on top of your confirmation page in a Rokt-managed container, requiring no changes to your page's DOM.
window.mParticle.ready(async function () {
const selection = await window.mParticle.Rokt.selectPlacements({
identifier: "yourPageIdentifier",
attributes: {
// Identity
"email": "j.smith@example.com",
"first_name": "Jenny",
"last_name": "Smith",
"mobile": "+13125551515",
// Transaction
"confirmationref": "54321",
"currency": "USD",
"country": "US",
"language": "en",
"total_price": 149.99,
"cart_item_count": 2,
"coupon_code": "SUMMER20",
// Customer context
"new_customer": false,
"customer_type": "logged_in",
"lifetime_value": 2340.00,
"subscription_status": "active",
"customer_segment": "vip",
// Payment (include payment_type and payment_service_provider for Pay+)
"payment_type": "credit_card",
"payment_service_provider": "card",
"ccbin": "411112",
// Billing address
"billing_address1": "123 Main St",
"billing_address2": "Apt 4B",
"billing_city": "Brooklyn",
"billing_state": "NY",
"billing_zipcode": "11201",
// Shipping
"shipping_method": "express",
"shipping_address1": "175 Varick St",
"shipping_city": "New York",
"shipping_state": "NY",
"shipping_zipcode": "10014",
"shipping_country": "US",
// Cart contents — send a real JSON array, not a stringified blob.
"cartItems": [
{
"cart_item_id": "SKU-001",
"product_sku": "SKU-001",
"product_name": "Product A",
"product_category": "Electronics",
"product_brand": "BrandX",
"item_price": 99.99,
"quantity": 1
},
{
"cart_item_id": "SKU-002",
"product_sku": "SKU-002",
"product_name": "Product B",
"product_category": "Accessories",
"item_price": 24.99,
"quantity": 2
}
]
}
});
});
Embedded PlacementsDirect link to Embedded Placements
Embedded placements render inline at a fixed position in your page that you control (for example, above the payment options on a cart page). Both Thanks and Pay+ use embedded placements, but Pay+ must use embedded placements.
To insert an embedded placement, add a <div> with the container ID provided by your Rokt account manager at the position where you want the placement to render:
<div id="rokt-{container-name}"></div>
Then call selectPlacements with the corresponding page identifier:
window.mParticle.ready(async function () {
const selection = await window.mParticle.Rokt.selectPlacements({
identifier: "prod.rokt.{page}",
attributes: {
// Pass the same attribute set described in Placement Attributes above
}
});
// For SPA navigations, close the placement when the customer leaves the page.
if (selection) {
selection.close();
}
});
If you are using Pay+, you must close your placement after the user navigates away to prevent it from lingering on back-navigation.
Interstitial PlacementsDirect link to Interstitial Placements
Interstitial placements are rendered between the payment and confirmation pages, allowing customers to purchase additional products. Interstitial placements are used by Shoppable Ads.
Interstitial placements require two pieces on the confirmation page: the <rokt-thank-you> wrapper that defines what to swap out, and a selectPlacements call that requests the offer.
First, wrap your confirmation page content within the <rokt-thank-you> tag:
<body>
<!-- Your header -->
<rokt-thank-you id="rokt-thank-you">
<!-- Your confirmation page content -->
</rokt-thank-you>
<!-- Your footer -->
</body>
Then call selectPlacements with the confirmation-page identifier:
window.mParticle.ready(async function () {
await window.mParticle.Rokt.selectPlacements({
identifier: "prod.rokt.conf",
attributes: {
// Pass the same attribute set described in Placement Attributes above
}
});
});
<rokt-thank-you> attributesDirect link to rokt-thank-you-attributes
Show <rokt-thank-you> attributes
| Attribute | Description | Default |
|---|---|---|
loader | Optional URL to a loading-indicator GIF displayed while Rokt selects a placement for the confirmation page. | Rokt loading indicator |
fallback-timeout | Duration in milliseconds before placement selection times out and the native confirmation page renders. | 5000 |
partner-opt-in | Force-enable the Interstitial experience. Usage: <rokt-thank-you partner-opt-in>. | — |
partner-opt-out | Force-skip the Interstitial experience. Usage: <rokt-thank-you partner-opt-out>. | — |
6. Subscribe to Placement EventsDirect link to 6. Subscribe to Placement Events
The SDK emits events throughout the placement lifecycle. Subscribe to these events to run custom logic when a placement is ready, when a customer engages with a placement, or when an interstitial placement wrapper transitions between states.
Subscribe to Placement Lifecycle EventsDirect link to Subscribe to Placement Lifecycle Events
window.mParticle.ready(async function () {
const selection = await window.mParticle.Rokt.selectPlacements({
// add attributes
});
// Listen for when the placement becomes interactive/ready to display
selection.on('PLACEMENT_INTERACTIVE').subscribe(() => {
// Logic to run after Placement has become interactive
});
// Listen for when user engages positively or negatively with an offer
selection.on('OFFER_ENGAGEMENT').subscribe(function () {
// Logic to run after offer is engaged with
});
});
Subscribe to Interstitial Lifecycle EventsDirect link to Subscribe to Interstitial Lifecycle Events
The <rokt-thank-you> element emits lifecycle events you can subscribe to for custom behavior. Register listeners with window.mParticle.Rokt.onShoppableAdsReady().
Show <rokt-thank-you> lifecycle events
| Event | Emitted when |
|---|---|
THANK_YOU_ELEMENT_LOADING_INITIATED | The <rokt-thank-you> element enters its loading state. |
THANK_YOU_ELEMENT_COMPLETE | The <rokt-thank-you> element renders the partner confirmation content. |
// Register listeners before mParticle.ready() so events are never missed.
window.mParticle.Rokt.onShoppableAdsReady(() => {
window.RoktThankYouElement.on('THANK_YOU_ELEMENT_LOADING_INITIATED').subscribe(() => {
// Triggered when the Thank You element enters its loading state
});
window.RoktThankYouElement.on('THANK_YOU_ELEMENT_COMPLETE').subscribe(() => {
// Triggered when the Thank You element renders the partner confirmation
});
});
window.mParticle.ready(() => {
// Standard mParticle initialization continues here
});
7. AppendixDirect link to 7. Appendix
Close a PlacementDirect link to Close a Placement
In single-page apps, call .close() on the placement object after the user navigates away so the placement doesn't linger on back-navigation.
selection.close();
If you are using Pay+, you must close your placement after the user navigates away.
Additional Functionality via ExtensionsDirect link to Additional Functionality via Extensions
Some features require extensions. Enable them by calling mParticle.Rokt.use() before selectPlacements(). For example, to display upsell placements on a Thank You page, enable the ThankYouJourney extension first:
window.mParticle.ready(async function() {
// Enable the necessary extension prior to selecting placements
await window.mParticle.Rokt.use("ThankYouJourney");
const selection = await mParticle.Rokt.selectPlacements({
identifier: "yourPageIdentifier",
attributes: {
"email": "j.smith@example.com"
// Any additional user attributes you want to pass to Rokt
},
});
})
Passing Additional Integration Launcher OptionsDirect link to Passing Additional Integration Launcher Options
Configure optional behavior by setting window.mParticle.config.launcherOptions in the initialization script:
// Include this as part of the initialization script in step 1 above
window.mParticle.config.launcherOptions = {
noFunctional: true,
noTargeting: true,
// See all optional launcher options that can be set below
};
Manage customer cookie preferencesDirect link to Manage customer cookie preferences
| Parameter | Type | Default |
|---|---|---|
noFunctional | boolean | false |
Set to true to prevent Rokt from using first-party tracking IDs when the customer has opted out of functional cookies.
| Parameter | Type | Default |
|---|---|---|
noTargeting | boolean | false |
Set to true to prevent Rokt from using cross-site tracking IDs for the session when the customer has opted out of targeting cookies.
Measure page load performance in single-page appsDirect link to Measure page load performance in single-page apps
| Parameter | Type | Default |
|---|---|---|
pageInitTimestamp | Date | PerformanceNavigationTiming.responseStart |
When the launcher initializes on a virtual page in an SPA, pass the timestamp of when that page was initialized so Rokt can measure load performance relative to the page that triggered it.
Link customer activity with a Rokt session IDDirect link to Link customer activity with a Rokt session ID
| Parameter | Type | Default |
|---|---|---|
sessionId | string | — |
If you've generated a Rokt session ID from a prior backend interaction, pass it here so Rokt can pair it with front-end activity.
Customize how links open in your experienceDirect link to Customize how links open in your experience
| Parameter | Type | Default |
|---|---|---|
overrideLinkNavigation | boolean | false |
When set to true, Rokt stops handling link openings directly and instead emits a LINK_NAVIGATION_REQUEST partner event.
8. Test Your IntegrationDirect link to 8. Test Your Integration
To confirm the SDK initializes and events log correctly:
-
Open a new browser window.
-
Open your browser's developer tools panel (right-click on your screen and click Inspect).
-
From the developer tools panel, go to the Network tab and type
experiencesinto the filter bar. -
Navigate to the site and page where you integrated the SDK.
noteMake sure you open the developer tools panel before navigating to your site to ensure the
/experiencescall is recorded by the browser. -
In the Network tab, you should see at least one
/experiencesrequest. This indicates that the Web SDK loaded successfully. -
Click the
/experiencesrequest (it should have a status of 200). Check the Payload/Request tab to verify the data being shared with Rokt.noteDuring testing, you might see another
/experiencescall with a 204 status. Make sure you are performing the check on the call with a 200 status.
TroubleshootingDirect link to Troubleshooting
If your integration isn't working, check the Console tab in your browser's developer tools for Rokt SDK errors.
Syntax errorsDirect link to Syntax errors
Make sure you are not missing any commas in your integration code. If the file where you placed the Web SDK has an error, it should be logged in the console.
Incorrect:
email: ''
mobile_number: '',
Correct:
email: '',
mobile_number: '',
Initialization errorsDirect link to Initialization errors
- Make sure the SDK initialization script has been placed on the correct page.
- If you integrated using a tag manager, make sure you configured your tag triggers so that initialization loads on the right pages, and that your
selectPlacementstags are firing after the SDK has initialized.