Unity SDK - Tracking In-app Events

Tracking In-App Events

Track in-app events to analyze campaign performance and measure key performance indicators (KPIs) such as user logins, registrations, tutorial completions, or progression milestones.

Standard Events and Attributes

Using Standard Events

Singular supports standard events that are recognized by ad networks for reporting and optimization. Use standard event names whenever possible for automatic recognition and simplified setup.

Your UA, marketing, or business team should compile the list of events based on your organization's marketing KPIs. Reference the guide How to Track In-App Events: Guide For Singular Attribution Customers for planning.

Each event supports various attributes. See the recommended standard attributes per event for implementation details.


Sending Events

Event Implementation Guidelines

Send events to Singular using the Event() method with optional attributes for enriched data.

  • Standard Events: Use the event's Unity name from the standard events list, e.g., Events.sngLogin
  • Custom Events: For events unique to your app that don't match standard events, use any descriptive string that complies with the character limitations

Custom Event Limitations:

  • Language: Pass event names and attributes in English to ensure compatibility with third-party partners and analytics solutions
  • Event Names: Limited to 32 ASCII characters. Non-ASCII strings must be under 32 bytes when converted to UTF-8
  • Attributes and Values: Limited to 500 ASCII characters

Event Method

Report user events with or without additional information using variable arguments or Dictionary format.

Method Signatures:

public static void Event(string name)
public static void Event(string name, params object[] args)
public static void Event(Dictionary<string, object> args, string name)

Note: When using the params object[] args signature, the args list must contain an even number of elements (key-value pairs) or the event will be rejected. When passing dictionaries, values must be one of these types: string, int, long, float, double, null, ArrayList, Dictionary<string, object>

Usage Examples

C#
// Example 1: Standard event without attributes
SingularSDK.Event(Events.sngLogin);

// Example 2: Standard event with recommended attributes (key-value pairs)
SingularSDK.Event(Events.sngTutorialComplete,
    Attributes.sngAttrContent, "Unity Basics",
    Attributes.sngAttrContentId, 32,
    Attributes.sngAttrContentType, "video",
    Attributes.sngAttrSuccess, "yes"
);

// Example 3: Standard event with attributes using Dictionary
Dictionary<string, object> attributes = new Dictionary<string, object>()
{
    [Attributes.sngAttrContent] = "Unity Basics",
    [Attributes.sngAttrContentId] = 32,
    [Attributes.sngAttrContentType] = "video",
    [Attributes.sngAttrSuccess] = "yes"
};
SingularSDK.Event(attributes, Events.sngTutorialComplete);

// Example 4: Custom event without attributes
SingularSDK.Event("SignUp");

// Example 5: Custom event with custom attributes
SingularSDK.Event("Bonus Points Earned", "Points", 500, "Level", 5);

Tracking In-App Revenue

Track revenue from in-app purchases (IAP), subscriptions, and custom revenue sources to measure campaign performance and return on ad spend (ROAS).

Revenue data flows through three channels:

  • Interactive Reports: View revenue metrics in the Singular dashboard
  • Export Logs: Access detailed ETL data for custom analysis
  • Real-Time Postbacks: Send revenue events to external platforms

Revenue Event Limitations:

  • Event Names: Custom revenue event names are limited to 32 ASCII characters (or 32 bytes for non-ASCII when converted to UTF-8)
  • Attributes: Event attribute names and values are limited to 500 ASCII characters
  • Currency Codes: Must be ALL CAPS and follow the three-letter ISO 4217 standard (e.g., USD, EUR, INR)

Note: Revenue in different currencies is automatically converted to your organization's preferred currency set in your Singular account.

Best Practices

  • Standard Naming: Use Singular's standard event and attribute naming convention
  • Language: Send custom revenue event names in English for improved ad network postback compatibility
  • Non-Zero Amounts: Only send revenue events when the amount is greater than or less than 0

Unity IAP Integration

In-App Purchase with Unity IAP

Pass Unity's IAP Purchase or Order object to the InAppPurchase() method for enriched reporting and transaction validation.

Benefits:

  • Rich Data: Singular receives complete transaction details for comprehensive reports
  • Fraud Prevention: Transaction receipts enable validation to combat in-app fraud

Unity IAP Version Compatibility:

  • Unity IAP v5: Uses the new Unity Purchasing API with Google Play Billing Library 7+. Compatible with Unity 2021.3 LTS and later. Use InAppPurchase(Order) methods
  • Unity IAP v4: Uses the older Unity IAP API with Google Play Billing Library 6. Compatible with Unity 2018.4 LTS through 2020.3 LTS. Use InAppPurchase(Product) methods

InAppPurchase Method (Unity IAP v5)

Send IAP events using Unity IAP v5's Order object for automatic validation and enriched data.

Method Signatures:

public static void InAppPurchase(Order order)
public static void InAppPurchase(Order order, Dictionary<string, object> attributes)
public static void InAppPurchase(Order order, bool isRestored)
public static void InAppPurchase(Order order, string eventName, Dictionary<string, object> attributes)

Usage Examples

C#
// Example 1: IAP with order object only
SingularSDK.InAppPurchase(order);

// Example 2: IAP with order and additional attributes
Dictionary<string, object> attr = new Dictionary<string, object>()
{
    ["promo_code"] = "SUMMER2025",
    ["user_tier"] = "premium"
};
SingularSDK.InAppPurchase(order, attr);

// Example 3: IAP with restored transaction flag
SingularSDK.InAppPurchase(order, true);

// Example 4: IAP with custom event name and attributes
Dictionary<string, object> attr = new Dictionary<string, object>()
{
    ["subscription_tier"] = "gold",
    ["billing_period"] = "monthly"
};
SingularSDK.InAppPurchase(order, "PremiumSubscription", attr);

InAppPurchase Method (Unity IAP v4)

Send IAP events using Unity IAP v4's Product object for automatic validation and enriched data.

Method Signatures:

public static void InAppPurchase(Product product, Dictionary<string, object> attributes, bool isRestored = false)
public static void InAppPurchase(string eventName, Product product, Dictionary<string, object> attributes, bool isRestored = false)
public static void InAppPurchase(IEnumerable<Product> products, Dictionary<string, object> attributes, bool isRestored = false)
public static void InAppPurchase(string eventName, IEnumerable<Product> products, Dictionary<string, object> attributes, bool isRestored = false)

Usage Examples

C#
// Example 1: IAP with single product, no extra attributes
SingularSDK.InAppPurchase(myProduct, null);

// Example 2: IAP with single product and attributes
Dictionary<string, object> attr = new Dictionary<string, object>()
{
    ["promo_code"] = "SUMMER2025",
    ["user_tier"] = "premium"
};
SingularSDK.InAppPurchase(myProduct, attr);

// Example 3: IAP with custom event name
SingularSDK.InAppPurchase("PremiumUpgrade", myProduct, null);

// Example 4: IAP with list of products
SingularSDK.InAppPurchase(myProductList, null);

// Example 5: IAP with list of products and custom event name
SingularSDK.InAppPurchase("BundlePurchase", myProductList, null);

Custom Revenue without Purchase Validation

Manual Revenue Tracking

Track revenue by passing currency, amount, and optional product details without the Purchase or Order object. Note that this method does not provide transaction receipts for validation.

Important: When using these methods, Singular cannot validate transactions. We strongly recommend using the Unity IAP methods described above whenever possible.


Revenue Method

Send revenue events with currency, amount, and optional product details.

Method Signatures:

public static void Revenue(string currency, double amount)
public static void Revenue(string currency, double amount, string productSKU, string productName, string productCategory, int productQuantity, double productPrice)
public static void Revenue(string currency, double amount, Dictionary<string, object> attributes)

Usage Examples

C#
// Example 1: Revenue without product details
SingularSDK.Revenue("USD", 1.99);

// Example 2: Revenue with product details
SingularSDK.Revenue("USD", 4.99, "coin_package_abc123", "Coin Pack 5", "Bundles", 1, 4.99);

// Example 3: Revenue with attributes dictionary
Dictionary<string, object> attributes = new Dictionary<string, object>()
{
    ["productSKU"] = "coin_package_abc123",
    ["productName"] = "Coin Pack 5",
    ["productCategory"] = "Bundles",
    ["productQuantity"] = 2,
    ["productPrice"] = 4.99,
    ["transaction_id"] = "T12345"
};
SingularSDK.Revenue("USD", 9.98, attributes);

CustomRevenue Method

Send custom revenue events with a specified event name, currency, amount, and optional transaction attributes.

Method Signatures:

public static void CustomRevenue(string eventName, string currency, double amount)
public static void CustomRevenue(string eventName, string currency, double amount, string productSKU, string productName, string productCategory, int productQuantity, double productPrice)
public static void CustomRevenue(string eventName, string currency, double amount, Dictionary<string, object> attributes)

Usage Examples

C#
// Example 1: Custom revenue without product details
SingularSDK.CustomRevenue("MyCustomRevenue", "USD", 9.99);

// Example 2: Custom revenue with product details
SingularSDK.CustomRevenue("MyCustomRevenue", "USD", 50.50, "abc123", "Premium Item", "Virtual Goods", 2, 25.50);

// Example 3: Custom revenue with attributes dictionary
Dictionary<string, object> attributes = new Dictionary<string, object>()
{
    ["productSKU"] = "premium_bundle_xyz",
    ["productName"] = "Premium Bundle",
    ["productCategory"] = "Bundles",
    ["productQuantity"] = 1,
    ["productPrice"] = 99.99,
    ["discount_applied"] = true
};
SingularSDK.CustomRevenue("PremiumBundlePurchase", "USD", 99.99, attributes);

Hybrid Event Tracking (Advanced)

Send all events and revenue through the Singular SDK integrated into your app for optimal attribution. However, Singular can collect events from other sources when necessary.

Events sent outside the Singular SDK must comply with Singular's Server-to-Server Event documentation and provide matching device identifiers for correct attribution.

Important:

Discrepancies occur when device identifiers in server-to-server requests don't match identifiers recorded by the Singular SDK:

  • Early Events: If an event arrives before the Singular SDK records the device identifier, the event becomes the "first session" for an unknown device, resulting in organic attribution
  • Mismatched Identifiers: If the Singular SDK recorded a different device identifier than the one in the server-to-server request, the event will be attributed incorrectly

Hybrid Event Tracking Guides

Sending Events from an Internal Server

Collect revenue data from your internal server to analyze campaign performance and ROI.

Requirements:

  • Capture Device Identifiers: During in-app registration or login events, capture and pass device identifiers, then store this data with the User ID on your server. Update identifiers when users generate new app sessions to ensure correct attribution
  • Platform-Specific Identifiers: Send server-side events with the device identifier matching the platform (e.g., IDFA or IDFV for iOS devices, GAID for Android devices)
  • Real-Time Updates: Use the Singular Internal BI postback mechanism to push events in real-time to your endpoint. See the Internal BI Postback FAQ
  • Implementation Details: Review the "Tracking Revenue" section in the Server-to-Server Integration guide

Sending Events from a Revenue Provider

Integrate third-party revenue providers like RevenueCat or adapty to send purchase and subscription revenue to Singular.

Supported Providers:


Sending Events from Segment

Enable Segment to send events to Singular in parallel with the Singular SDK by adding a "Cloud-Mode" destination in Segment.

Follow the implementation guide Singular-Segment Integration for detailed setup instructions.