Tracking In-app Events

Tracking In-app Events

Singular can collect data about in-app events to help analyze the performance of your campaigns and measure KPIs. For example, your organization may want to collect data about user logins, registrations, tutorial completions, or leveling up in a gaming app.

Standard Events and Attributes

Singular supports a variety of standard events. These commonly used events are often supported by ad networks for reporting and optimization. Another advantage is that when you use standard event names, Singular recognizes them automatically and adds them to the Events list without you having to define them manually. We recommend using standard events whenever possible.

The list of events sent to Singular (with the accompanying attributes) should be compiled by the UA/marketing/business team based on your organization's marketing KPIs. The business team can follow the guide at How to Track In-App Events: Guide For Singular Attribution Customers.

With each event you track, you can pass various attributes. See the recommended standard attributes per event.

Sending Events

In your code, send events to Singular using the eventJSON or event methods (we recommend eventJSON for readability).

Custom Event Limitations:

  • We highly recommend passing event names and attributes in English to guarantee compatibility with third-party partners and analytics solutions if you plan to use them.
  • Event names are limited to 32 ASCII characters. Strings in non-ASCII characters have to be under 32 bytes once converted to UTF-8.
  • Attributes and values are limited to 500 ASCII characters.

Singular.eventJSON Method

Report a user event to Singular with additional information in JSONObject format.

Signatures

Singular.eventJSON(String name, JSONObject args)
Note: 'args' is a JSONObject containing one or more key-value pairs. The key is a string and the value can be any type that's allowed as a JSONObject value.

Usage Examples

JavaKotlin
// Example 1:
// Send the standard event sng_tutorial_complete with the
// recommended standard attributes

JSONObject att = new JSONObject();
try {
    att.put(Attributes.sngAttrContent.toString(), "Telugu");
    att.put(Attributes.sngAttrContentId.toString(), 32);
    att.put(Attributes.sngAttrContentType.toString(), "video");
    att.put(Attributes.sngAttrSuccess.toString(), 92);
} catch (JSONException e) {
    e.printStackTrace(); // Or log the exception

}
Singular.eventJSON(Events.sngTutorialComplete.toString(), att);

// Example 2:
// Send a custom event named "bonus_points_earned" with custom attributes
JSONObject att = new JSONObject();
try {
    att.put("Points", 500);
    att.put("score", 650);
} catch (JSONException e) {
    e.printStackTrace(); // Or log the exception

}
Singular.eventJSON("Bonus Points Earned", att);

Singular.event Method

Report a user event to Singular with or without additional information.

Signatures

Singular.event(String eventName)
Singular.event(String eventName, Object... args)

Note: 'args' is one or more key-value pairs (see the example below). The key is a string and the value can be any type that's allowed as a JSONObject value (i.e., JSONObject, JSONArray, String, Boolean, Integer, Long, Double or NULL).

The 'args' list must contain an even number of elements or the event will be rejected by Singular.

Usage Examples

JavaKotlin
// Example 1:
// Send the standard event "Subscribe" (sng_subscribe) without any attributes
Singular.event(Events.sngSubscribe.toString());

// Example 2:
// Send the standard event "sng_tutorial_complete" with the 
//recommended standard attributes
Singular.event(Events.sngTutorialComplete.toString(),
    Attributes.sngAttrContent.toString(), "Spanish",
    Attributes.sngAttrContentId.toString(), 52,
    Attributes.sngAttrContentType.toString(), "video",
    Attributes.sngAttrSuccess.toString(), 46
);

// Example 3:
// Send a custom event named "SignUp" without any custom attributes
Singular.event("SignUp");

// Example 4:
// Send a custom event named "bonus_points_earned" with a custom attribute
Singular.event("Bonus Points Earned", "Points", 500);

Tracking In-app Revenue

Singular captures revenue events from in-app purchases (IAP), subscriptions, and custom revenue to measure campaign performance and return on ad spend (ROAS). The revenue data becomes available through three key channels:

  • Interactive reports in the Singular dashboard
  • Detailed export logs and ETL data destinations for custom analysis
  • Real-time postbacks to external platforms

This comprehensive revenue tracking enables data-driven decisions about marketing spend and campaign optimization while providing flexibility in how you consume and analyze the data.

Revenue Event Limitations
  • If Custom Revenue Event Names are used the Custom Revenue Event Names are limited to 32 ASCII characters. For non-ASCII characters, the limit is 32 bytes once converted to UTF-8.
  • Event attribute names and attribute values are limited to 500 ASCII characters.
  • Currency codes must be ALL CAPS and adhere to the three-letter ISO 4217 currency code:

    USD, EUR, INR

Best Practice

  • Singular recommends passing events using Singular's standard event and attribute naming convention.
  • If Custom Revenue Event Names are used they should be sent in English to improve compatibility with Ad Network postbacks.
  • Revenue Events should only be sent to Singular when the Revenue Amount is greater than or less than 0.

Non-Subscription In-App Purchase

To report revenue events to Singular, pass the Purchase object received from the Google Billing Library into the revenue or customRevenue SDK methods. This has two advantages:

  • Singular gets all the details of the transaction, which enriches your Singular reports.
  • Singular gets the transaction receipt from Google which can be used to validate the transaction in the context of fighting in-app fraud.

Notes:

  • customRevenue allows you to pass a custom event name, so that you'll be able to view revenue in Singular reports broken down by the different types of revenue events.
  • Any revenue reported in a different currency will be auto-converted to your organization's preferred currency, as set in your Singular account.

revenue Method

Send a revenue event to Singular with the Purchase object.

Signatures

Singular.revenue(String currency, double amount, Object purchase)

Usage Examples

JavaKotlin
Singular.revenue("USD", 5.50, purchase);

customRevenue Method

Send a revenue event to Singular with a custom event name and the Purchase object.

Signatures

Singular.customRevenue(String eventName, String currency, double amount, Object purchase)

Usage Examples

JavaKotlin
Singular.customRevenue("MyCustomRevenue", "USD", 5.50, purchase);

Subscription Revenue

Tracking Subscriptions:

Singular enables you to track your subscriptions and renewals within your app, providing insights into user behavior and revenue generation. Review our comprehensive guide on how to implement subscription events using the Singular SDK. [Subscription Event Technical Implementation Guide]


Custom Revenue without Purchase Validation

While we strongly recommend reporting revenue events the way described above, you can also use revenue and customRevenue without passing the purchase object. Instead, you pass the currency and amount of the transaction, and optional product details.

The customRevenue method also lets you pass a custom event name.

Note that if you use these methods, Singular does not get the transaction receipt and cannot validate the transaction.

revenue Method

Send a revenue event to Singular with the revenue amount, currency, and optional details.

Signatures

Singular.revenue(String currency, double amount)
Singular.revenue(String currency, double amount, String productSKU, String productName, String productCategory, int productQuantity, double productPrice)
Singular.revenue(String currency, double amount, Map<String, Object> attributes)

Usage Examples

JavaKotin

Without Product Details

Singular.revenue("USD", 5.50);

With Product Details

Singular.revenue("EUR", 5.00, "SKU1928375", "Reservation Fee", "Fee" , 1, 5.00);

With Product Details in an Attribute Map

Map<string, object="Object"> attributes = new HashMap<>();
attributes.put("product_id", "com.app.premium");
attributes.put("transaction_id", "T12345");
attributes.put("quantity", 1);
attributes.put("is_trial", false);

// Call the revenue method
Singular.revenue("USD", 9.99, attributes);

customRevenue Method

Send custom revenue events to Singular by specifying the event name, revenue amount, currency code, and any additional transaction attributes. Singular processes these events to track in-app revenue.

Signatures

Singular.customRevenue(String eventName, String currency, double amount)
Singular.customRevenue(String eventName, String currency, double amount, String productSKU, String productName, String productCategory, int productQuantity, double productPrice)
Singular.customRevenue(String eventName, String currency, double amount, Map<String, Object> attributes)

Usage Examples

JavaKotin

Without Product Details

Singular.customRevenue("MyCustomRevenue", "USD", 5.50);

With Product Details

Singular.customRevenue("MyCustomRevenue", "EUR", 5.00, "SKU1928375", "Reservation Fee", "Fee" , 1, 5.00);

With Product Details in an Attribute Map

Map<string, object="Object"> attributes = new HashMap<>();
attributes.put("product_id", "com.app.premium");
attributes.put("transaction_id", "T12345");
attributes.put("quantity", 1);
attributes.put("is_trial", false);

// Call the revenue method
Singular.customRevenue("MyCustomRevenue", "USD", 9.99, attributes);

Hybrid Event Tracking (Advanced)

Singular recommends sending all events and revenue through the Singular SDK integrated into your app. However, Singular can collect events and revenue from other sources.

Any event NOT sent from the Singular SDK must comply with Singular's Server-to-Server Event documentation requirements and provide the matching device identifier to correctly attribute an event.

Important:

Discrepancies will occur if device identifiers used on Server-to-Server event requests do not have a matching device identifier in Singular. Be aware of the following possibilities:

  • If an event request is received "before" the Singular SDK has recorded the device identifier, from an App Session, then the event request will be considered the "first session" for the unknown device, and Singular will attribute the device as an organic attribution.
  • If the Singular SDK did record a device identifier, but the Singular SDK identifier differs from the device identifier specified in the Server-to-Server Event request then the event will be attributed incorrectly.

Hybrid Event Tracking Guides

Sending Events from an Internal Server

Singular can collect data about revenue from your Server to help analyze the performance and ROI of your campaigns.

Requirements:

  • From an in-app Registration or Login Event, capture and pass the device identifiers and store this data with the User ID on your server. Because device identifiers may change for a user, be sure to update the identifiers when a user generates an app session. This guarantees the server-side event will be attributed to the correct device.
  • Server-side events are platform specific and should only be sent with the device identifier matching the device platform (e.g., IDFA or IDFV for iOS devices).
  • You can use the Singular Internal BI postback mechanism to push an event in real time to your internal endpoint so that you can update the data set on the server side. See the Internal BI Postback FAQ.
  • Review the "Tracking Revenue" section in the Server-to-Server Integration guide for details.

Sending Events from a Revenue Provider

Third-party providers like RevenueCat or adapty can provide Purchase and Subscription Revenue to Singular.

Follow the links below for details on how to enable these partners.


Sending Events from Segment

To enable Segment to send events to Singular, in parallel with the Singular SDK, you must add a "Cloud-Mode" Destination in Segment. Follow our guide HERE.