> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom event best practices

> Leverage your Custom Events in OneSignal: shape their properties so Journeys, Segments, and Conversion Metrics can use them, personalize messages with event properties, and see how one event can trigger, target, and measure at the same time.

Send and leverage Custom Events in OneSignal. This page shows how to shape event properties so every OneSignal feature can read them, and how one event can do several jobs at once. For sending and limits, see [Custom events](./custom-events).

## Prerequisites

* **A paid plan.** Custom Events and custom Conversion Metrics are available on all paid plans.
* **Custom Events flowing into OneSignal** from the SDK (`OneSignal.User.trackEvent`), the API, or an integration such as Segment or Amplitude. See [Send Custom Events to OneSignal](./custom-events#send-custom-events-to-onesignal).

## Make the most of your events and event properties

Use each Custom Event to trigger Journeys, build Segments, and measure conversions. The table shows where you set up each job and what the event needs.

| Job                  | Where you set it up                                   | What the event needs                                                                                                                      |
| -------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Trigger a Journey    | Journey entry rules, exit rules, and Wait Until steps | An event name. Add properties to filter Journey entry or personalize the messages.                                                        |
| Build a Segment      | **Audience > Segments**, Custom Event filter          | An event name, with [storage](./custom-event-storage) turned on. Add properties to target a subset of the people who performed the event. |
| Measure a conversion | **Data > Events & conversions > Conversion Metrics**  | An event name to count. To total a value such as revenue, add a numeric property and turn on **Track a value for each event**.            |

## Shape properties for how you will use them

Name each event for the action your customer took, and put the details of that action in event properties. For example, send the SKU as a property: `purchase_completed` with `"sku": "SKU-4412"`. Don't add it to the name, as in `purchase_completed_SKU-4412`, because every product then creates a new event name. See [Name events so you don't reach the limit](./custom-events#name-events-so-you-dont-reach-the-limit).

Event properties can be used for different actions:

| Use                                                                                       | Example                                                  |
| ----------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| Filter (Segment filters, Journey entry filters, Wait Until conditions)                    | `plan: "pro"`, `category: "shoes"`, `order_number: 1`    |
| Personalize messages (see [Custom Event personalization](./personalization-custom-event)) | `product_name: "Blue Sweater"`, `image_url`, `deep_link` |
| Measure a conversion value (must be a number)                                             | `total: 84.5`                                            |

Follow these rules so filters and metrics behave the way you expect:

* **Send numbers as numbers.** Segment filters skip a number sent as a string, so a `total` of `"84.5"` never matches `greater than 50`. Conversion Metrics only offer number-typed properties for value tracking.
* **Filter strings match exactly and are case sensitive.** `"Apple Pay"` and `"apple_pay"` are different values. Use lowercase values from a set you control.
* **Use the same property names on every event.** Send `product_id` on every commerce event, so the same filters and metrics work across all of them.

## Event examples

See how these event examples can perform multiple jobs within OneSignal. Use an event for one job or for all of them.

Send an example as an item in the `events` array of the [Create custom events API](/reference/create-custom-events), or pass its name and properties to `trackEvent` in the SDK.

### Purchase completed

```json JSON theme={null}
{
  "name": "purchase_completed",
  "external_id": "user_12345",
  "properties": {
    "order_id": "ord_98213",
    "cart_id": "cart_5541",
    "total": 84.5,
    "currency": "USD",
    "category": "shoes",
    "order_number": 1,
    "items": [
      {
        "name": "Trail Runner",
        "sku": "TR-220",
        "price": 84.5
      }
    ]
  }
}
```

* **Trigger** an onboarding series for first-time buyers. Start a post-purchase Journey when `purchase_completed` arrives with `order_number` equal to 1.
* **Segment** big spenders. Target people who performed `purchase_completed` in the last 90 days with a `total` over 100.
* **Measure** the revenue your messages drive. Create a Conversion Metric on `purchase_completed` and turn on **Track a value for each event** for `total`. Your message, template, and Journey reports then show the purchase revenue each message drove.
* **Personalize** the order confirmation with the product they bought. For example: "Thanks for your order. Your Trail Runner ships soon."

### Checkout started

```json JSON theme={null}
{
  "name": "checkout_started",
  "external_id": "user_12345",
  "properties": {
    "cart_id": "cart_5541",
    "cart_total": 129.0,
    "currency": "USD",
    "item_count": 2
  }
}
```

* **Trigger** a cart-recovery Journey. Start the Journey when `checkout_started` arrives, then wait up to 1 hour for `purchase_completed`. People who don't buy in that hour get a reminder.
* **Segment** high-value shoppers. Target people who performed `checkout_started` in the last 7 days with a `cart_total` over 75.
* **Measure** checkouts. Create a Conversion Metric on `checkout_started` to see which campaigns get people to checkout. Track a value for `cart_total` to see how much cart value your messages drive.
* **Personalize** the reminder with the size of their cart. For example: "You left 2 items in your cart."

### Signup completed

```json JSON theme={null}
{
  "name": "signup_completed",
  "external_id": "user_12345",
  "properties": {
    "plan": "trial",
    "signup_method": "google"
  }
}
```

* **Trigger** separate onboarding for trial and paid users. Start each onboarding Journey when `signup_completed` arrives, and filter entry on `plan`.
* **Segment** trial users. Target people who performed `signup_completed` in the last 7 days with `plan` set to `trial`.
* **Measure** signups. Create a Conversion Metric on `signup_completed` to see which acquisition messages drive signups.
* **Personalize** the welcome message by plan. For example, trial users see "Your 14-day trial has started."

### Level completed

```json JSON theme={null}
{
  "name": "level_completed",
  "external_id": "user_12345",
  "properties": {
    "level": 5,
    "stars": 3,
    "duration_seconds": 212
  }
}
```

* **Trigger** milestone rewards. Start a Journey when a player completes level 1 (`level_completed` with `level` equal to 1). Then add a Wait Until step for each milestone at levels 5, 10, and 20, each followed by a reward message. See [Progressive journeys](./journeys-examples#progressive-journeys-event-driven).
* **Segment** advanced players. Target players who performed `level_completed` in the last 30 days with a `level` of 10 or higher, and send them offers for your most committed players.
* **Measure** re-engagement. Create a Conversion Metric on `level_completed` to see which messages bring players back.
* **Personalize** the reward with the level and stars they earned. For example: "Level 5 cleared with 3 stars!"

### Subscription cancelled

```json JSON theme={null}
{
  "name": "subscription_cancelled",
  "external_id": "user_12345",
  "properties": {
    "plan": "pro",
    "reason": "too_expensive",
    "months_active": 14
  }
}
```

* **Trigger** a win-back Journey. Start the Journey when `subscription_cancelled` arrives.
* **Segment** recently cancelled users. Target people who performed `subscription_cancelled` in the last 30 days. Use this Segment in a Journey [Yes/No branch](./journeys-actions#yesno-branch) to skip promotional steps for them.
* **Measure** recovered revenue. Track the resubscription, not the cancellation. Create a Conversion Metric on `subscription_started`, turn on **Track a value for each event** for its `price` property, and set the metric as the [Message Goal](./goals#set-a-goal-against-a-conversion-metric) on your win-back messages.
* **Personalize** the offer by cancellation reason. For example, users who cancelled over price see "Here's 30% off your next 3 months."

## FAQ

### Should this be a Custom Event or a Tag?

If it describes a customer action, or happened at a moment in time, send a Custom Event. If it describes a customer attribute, send it as a Tag. A purchase is a Custom Event. A customer's favorite team is a Tag. Custom Events are more powerful than Tags, and OneSignal recommends using them over Tags in most cases. See [Tags vs Custom Events](./custom-events#tags-vs-custom-events).

### Can one Segment filter combine properties from two different events?

No. Property filters apply to a single event occurrence. To target people who did one thing and another, add a second Custom Event filter to the Segment. To target people who did one thing with two matching properties, add both properties to the same filter and choose **With all of the following properties**.

### Can Journey exit rules filter on event properties?

No. Exit rules match on the event name only, so any occurrence of that event exits the user. To act on specific property values, filter the entry rule or a Wait Until condition instead.

## Related pages

<Columns cols={2}>
  <Card title="Custom events" icon="bolt" href="./custom-events">
    Send events, verify them, and use them across OneSignal.
  </Card>

  <Card title="Custom event storage and retention" icon="database" href="./custom-event-storage">
    Turn on storage and set retention per event.
  </Card>

  <Card title="Segmentation" icon="filter" href="./segmentation#custom-event-filters">
    Build Segments with Custom Event filters.
  </Card>

  <Card title="Conversion metrics" icon="arrow-trend-up" href="./conversion-metrics">
    Measure the conversions and revenue your messages drive.
  </Card>
</Columns>
