# Tracking events

Track custom and predefined events from your app, website, server, or messages.

All events are recorded for analytics and reporting. To use a custom or predefined event for audience targeting, automation triggers, or [Goals](https://www.airship.com/docs/reference/glossary/#goals), add it to your project. See [Adding events to your project](https://www.airship.com/docs/guides/audience/events/adding/).

No setup is required for default events. The Airship SDKs and system record them automatically, so you can go straight to [targeting your audience](https://www.airship.com/docs/guides/audience/events/targeting/).

## Track events from the SDKs

Use the Airship SDKs to track custom and predefined events as users navigate your app or website. The SDKs automatically batch and send events in the background. Tracking these events requires the Analytics flag in Privacy Manager. See [SDK data collection](https://www.airship.com/docs/reference/data-collection/sdk-data-collection/) for mobile and [Data Collection](https://www.airship.com/docs/developer/sdk-integration/web/data-collection/) for the Web SDK.

### Custom event templates

For common account, media, and retail actions, use the ready-made templates in the [custom events](https://www.airship.com/docs/sdk-topics/custom-events/) SDK documentation. The following examples use the retail template to track a `purchased` predefined event.


#### iOS Swift


```swift
var retailEvent = CustomEvent(
    retailTemplate: .purchased,
    properties: CustomEvent.RetailProperties(
        id: "12345",
        category: "mens shoes",
        eventDescription: "Low top",
        isLTV: true,
        brand: "SpecialBrand",
        isNewItem: true
    )
)
retailEvent.eventValue = 99.99
retailEvent.transactionID = "13579"
retailEvent.track()
```



#### Android Kotlin


```kotlin
customEvent(
    type = RetailEventTemplate.Type.Purchased,
    properties = RetailEventTemplate.Properties(
        id = "12345",
        category = "mens shoes",
        eventDescription = "Low top",
        brand = "SpecialBrand",
        isNewItem = true
    )
) {
    setEventValue(99.99)
    setTransactionId("13579")
}.track()
```



#### Android Java


```java
RetailEventTemplate.newPurchasedTemplate()
    .setCategory("mens shoes")
    .setId("12345")
    .setDescription("Low top")
    .setValue(99.99)
    .setTransactionId("13579")
    .setBrand("SpecialBrand")
    .setNewItem(true)
    .createEvent()
    .track();
```



#### Web


```js
new sdk.CustomEvent.templates.retail.PurchasedEvent(99.99, {
    id: "12345",
    category: "mens shoes",
    description: "Low top",
    brand: "SpecialBrand",
    new_item: true,
}, "13579").track()
```




### Custom events by name

To track an action that does not have a predefined event, create a custom event by name. You can set properties and a numeric value.


#### iOS Swift


```swift
var event = CustomEvent(name: "used_feature", value: 1.0)
event.setProperty(string: "onboarding", forKey: "feature_name")
event.track()
```



#### Android Kotlin


```kotlin
customEvent("used_feature") {
    setEventValue(1.0)
    addProperty("feature_name", "onboarding")
}.track()
```



#### Android Java


```java
CustomEvent.newBuilder("used_feature")
    .setEventValue(1.0)
    .addProperty("feature_name", "onboarding")
    .build()
    .track();
```



#### Web


```js
new sdk.CustomEvent("used_feature", 1.0, {
    feature_name: "onboarding"
}).track()
```




### Custom events for Message Center and landing pages

Include the following HTML in a [Message Center](https://www.airship.com/docs/guides/features/messaging/message-center/) message or [landing page](https://www.airship.com/docs/guides/features/messaging/landing-pages/) to emit a custom event from a button. The example creates a `buy-button` that emits `clicked_button-Buy_Now` with a value of `10.99`. It also sets `interaction_type` to `ua_landing_page` and `interaction_id` to the page URL when `getMessageId()` returns nothing, which indicates a landing page. In Message Center, the SDK sets those fields automatically.

**Emit a custom event from a Message Center or landing page button**

```html
<html>
    <head>
        <title>Store</title>
        <script>
            document.addEventListener('ualibraryready', onUAReady)

            function onUAReady() {
              // Name buttons below
              // The output variable is used for debugging - comment out if needed
              var buy_button = document.querySelector('[name=buy-button]')
                , output = document.querySelector('[name=ua-attributes]')

              // For debugging - can be commented out
              // Write all the results of all getters
              output.innerHTML += 'ATTRIBUTES \n'
              output.innerHTML += '---------- \n'
              output.innerHTML += 'User Id:' + UAirship.getUserId() +
               '\n Device Model: ' + UAirship.getDeviceModel() +
               '\n Message Id: ' + UAirship.getMessageId() +
               '\n Message Title: ' + UAirship.getMessageTitle() +
               '\n Message Sent Date: ' + UAirship.getMessageSentDate() +
               '\n Message Sent Date MS: ' + UAirship.getMessageSentDateMS() +
               '\n\n'

              // Enable buttons once the ualibrary is up and running on the page
              buy_button.disabled = false

              // Listen for taps/clicks
              buy_button.addEventListener('click', onclick)
            }

            function onclick(ev) {
              // The output variable is used for debugging - comment out if needed
              var output = document.querySelector('[name=ua-custom-event-info]')
                , message_id = UAirship.getMessageId()

              var custom_event_object = {}
                , el = ev.currentTarget

              // get value and name from the element
              custom_event_object.event_value = el.getAttribute('data-event-value')
              custom_event_object.event_name = el.getAttribute('data-event-name')

              if(!UAirship.getMessageId()) {
                 // If we can't get a messageId, then we must be in a web
                 // view, which, in this case, implies we are on a landing
                 // page.

                 custom_event_object.interaction_type = 'ua_landing_page'
                 custom_event_object.interaction_id = '' + window.location
              }

              // For debugging - can be commented out
              output.innerHTML += 'Sending Event: \n' +
                JSON.stringify(custom_event_object, null, 4) + '\n'

              //Send the event to the SDK
              UAirship.runAction('add_custom_event_action', custom_event_object, ready)

              function ready(error, result) {
                if(error) {
                  // For debugging - can be commented out
                  output.innerHTML += 'Woops! ' +
                    error.message + '\n'

                  return
                }
                // For debugging - can be commented out
                output.innerHTML += 'Success! The server responded:\n' +
                   JSON.stringify(result, null, 4) + '\n'
              }
            }
        </script>
    </head>
    <body>
       <!-- CUSTOMIZE EVENT DATA FOR BUTTON js is looking for data-event-name and data-event-value -->
      <button name="buy-button" data-event-name="clicked_button-Buy_Now" data-event-value="10.99" disabled>
          Buy Now
      </button>
      <!-- START EVENT DATA OUTPUT FOR DEBUGGING COMMENT OUT IF NEEDED-->
      <pre name="ua-attributes">
      </pre>
      <pre name="ua-custom-event-info">
      </pre>
      <!-- END EVENT DATA OUTPUT FOR DEBUGGING -->
    </body>
</html>
```


### Inject the Airship JavaScript interface for custom events

For a WebView outside Message Center, inject the Airship JavaScript interface so the page can emit custom events.

> **Important:** Only load the Airship JavaScript interface in WebViews that display content from trusted sources and only link to other trusted sources. The interface runs Airship actions and exposes information about the application.


#### iOS

On iOS, add the interface to any `WKWebView` whose navigation delegate is an instance of [NativeBridge](https://urbanairship.github.io/ios-library/v20/AirshipCore/documentation/airshipcore/nativebridge)
. Custom WebViews can also implement the [NativeBridgeExtensionDelegate](https://urbanairship.github.io/ios-library/v20/AirshipCore/documentation/airshipcore/nativebridgeextensiondelegate)
 to extend the JavaScript environment or respond to SDK-defined JavaScript commands.

**Add NativeBridge to a WKWebView**

```swift
self.nativeBridge = NativeBridge()
self.nativeBridge.nativeBridgeExtensionDelegate = self.nativeBridgeExtension
self.nativeBridge.forwardNavigationDelegate = self
webView.navigationDelegate = self.nativeBridge
```


Optionally, enable `UAirship.close()` by having the controller implement the `close` method in the `NativeBridgeDelegate` protocol.

**Implement close for UAirship.close()**

```swift
func close() {
  // Close the current window
}
```


The [URLAllowList](https://urbanairship.github.io/ios-library/v20/AirshipCore/documentation/airshipcore/airshipurlallowlist)
 controls which URLs the Airship SDK is able to act on. As of SDK 17, all URLs are allowed by default. See [URL allowlist](https://www.airship.com/docs/developer/sdk-integration/apple/installation/advanced-integration/#url-allowlist) in *Advanced Integration* for the Apple SDKs.

#### Android and Fire OS

On Android and Fire OS, enable JavaScript and set the client to an instance of `UAWebViewClient`.

**Add UAWebViewClient to a WebView**

```java
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new UAWebViewClient())
```


The [UrlAllowList](https://www.airship.com/docs/reference/libraries/android-kotlin/latest/urbanairship-core/com.urbanairship/-url-allow-list)
 controls which URLs the Airship SDK is able to act on. As of SDK 17, all URLs are allowed by default. See [URL allowlist](https://www.airship.com/docs/developer/sdk-integration/android/installation/advanced-integration/#url-allowlist) in *Advanced Integration* for Android.

## Track events using the Custom Events API

Use the [Custom Events API](https://www.airship.com/docs/developer/rest-api/ua/operations/custom-events/) to submit custom and predefined events from your server or an external system. These are also called server-side events. Common uses include CRM, POS, and partner integrations, and tracking events for email, SMS, and open channels.

Include the event `name` and associate it with a [channel](https://www.airship.com/docs/reference/glossary/#channel_term) ID or [named user](https://www.airship.com/docs/reference/glossary/#named_user) ID. A channel association applies to that channel only. A named user association attributes the event across the contact's channels. You can also include a value, properties, and interaction metadata.

**Example custom event associated with a named user**

```json
[
   {
      "occurred": "2026-05-02T02:31:22",
      "user": {
         "named_user_id": "hugh.manbeing"
      },
      "body": {
         "name": "purchased",
         "value": 239.85,
         "transaction": "886f53d4-3e0f-46d7-930e-c2792dac6e0a",
         "interaction_id": "your.store/us/en_us/pd/shoe/pid-11046546/pgid-10978234",
         "interaction_type": "url",
         "properties": {
            "description": "Sneaker purchase",
            "brand": "Victory Sneakers",
            "colors": [
             "red",
             "blue"
            ],
            "items": [
               {
                  "text": "New Line Sneakers",
                  "price": "$ 79.95"
               },
               {
                  "text": "Old Line Sneakers",
                  "price": "$ 79.95"
               },
               {
                  "text": "Blue Line Sneakers",
                  "price": "$ 79.95"
               }
            ],
            "name": "Hugh Manbeing",
            "userLocation": {
               "state": "CO",
               "zip": "80202"
            }
         },
         "session_id": "22404b07-3f8f-4e42-a4ff-a996c18fa9f1"
      }
   }
]
```


## Track events from message interaction

Track custom events when users interact with [Scenes](https://www.airship.com/docs/reference/glossary/#scene), [push notifications](https://www.airship.com/docs/reference/glossary/#push_notification), or [in-app messages](https://www.airship.com/docs/reference/glossary/#in_app_message), without writing custom event tracking code in your app or website.

You can select an existing event or name a new one. You can also assign an event value and string, number, or boolean properties for filtering. To use properties, define the event and its properties in your project in advance. See [Adding events to your project](https://www.airship.com/docs/guides/audience/events/adding/).

Use this procedure after selecting an action for a message, button, image, or screen:

1. Select **Configure options**.
1. Under **Options**, select **Emit custom event** and search for an event. If no result is found, select **Use \<event name>** to add the event to your project.
1. (Optional) Set an event value and/or specify property values to filter by in segments and triggers:
   1. Select **Add event properties**, then:
      * For a value, select **Add event value** and enter a numeric value for the event.
      * For properties, select **Add property**, then **Search for properties**, and then search for a string, number, or boolean event property and enter or select a value.
   1. Select **Save**.

See the following sections for where the option is available.

### Scenes

For Scenes, emit an event when a user interacts with a button, image, or screen. The option is available when configuring an action for the following:

* [Button or Button Group element](https://www.airship.com/docs/guides/messaging/editors/scenes/elements/#button-or-button-group)
* [Media element](https://www.airship.com/docs/guides/messaging/editors/scenes/elements/#media)
* [Screen](https://www.airship.com/docs/guides/messaging/editors/scenes/screens/#add-an-action)

### Push notification and in-app messages

(iOS SDK 20+) (Android SDK 20+)

For push notifications and in-app messages, emit an event when a user interacts with the message or a button. The option is available when configuring an action for the following:

* [Push notifications](https://www.airship.com/docs/guides/messaging/messages/content/app/push-notifications/#creating-content)
* [In-app messages](https://www.airship.com/docs/guides/messaging/messages/content/app/in-app-messages/#creating-content)
* [Buttons in message content](https://www.airship.com/docs/guides/messaging/messages/buttons/#add-buttons-to-message-content)

For the Push API, use the [add_custom_event](https://www.airship.com/docs/developer/rest-api/ua/schemas/push/#actionsobject) action to emit on user interaction.
