---
metadata:
  - name: generator
    content: Diplodoc Platform v5.66.1
alternate:
  - https://appmetrica.yandex.by/docs/en/data-collection/custom-events.md
  - https://appmetrica.yandex.by/docs/ru/data-collection/custom-events.md
  - https://appmetrica.yandex.by/docs/zh/data-collection/custom-events.md
  - href: https://appmetrica.yandex.by/docs/en/data-collection/custom-events.md
    type: text/markdown
    title: Markdown version
  - href: https://appmetrica.yandex.by/docs/en/llms.txt?revision=r22076204
    rel: describedby
---
> **Documentation Index:** Fetch the complete configuration index at https://appmetrica.yandex.by/docs/en/llms.txt?revision=r22076204

# Custom events

{% note info %}

Custom events are free within 100 million per month. A larger limit is available for an additional fee.

The limit is shared across all apps of the organization. [Choose a plan and increase the limit](https://appmetrica.yandex.by/docs/en/common/pricing/ru-currency.md).

{% endnote %}

Custom events are events you create for actions specific to your app. They are also called client or user events. For example, you can use them to study the use of a feature, a button click, or a transition to a specific screen.

AppMetrica doesn't determine the meaning of such actions automatically. You need to choose the event name, parameters, and the moment of sending, and then pass the task of collecting them to the developer.

## How to set up custom event collection {#setup}

An analyst or product manager describes which actions need to be measured, passes the task to the developer, and checks the result after setup.

![Steps for setting up custom event collection](../../_images/custom-events-steps-horizontal-en.png){style="border: solid 1px #cccccc; max-width: 100%;"}

### 1. Define the task {#step-task}

Formulate the question you want to answer with events. For example: which product categories do users add to favorites most often? Choose the actions that will help you get the answer.

### 2. Describe the events and parameters {#step-describe}

Create a markup — a list of events with the rules for sending them. For each event, specify:

- **Name and purpose**. What action the event records and what analysis it is needed for.
- **Moment of sending**. Under what condition the action is considered completed: for example, when a product is successfully added to favorites.
- **Parameters**. What action details will be needed in the report. For each parameter, specify the name, value type, and possible values.
- **Expected number of sends**. For example, one event for each successful product addition to favorites.

{% cut "Example of markup for an online store" %}

**Task**: find out which product categories are added to favorites most often.

**Event**: `product_added_to_favorites`.

**When to send**: once after a product is successfully added to favorites. If the addition failed or the product is already in favorites, the event is not sent.

**Parameters**:

- `product_id` — product identifier, string. For example, `sneakers_042`.
- `category` — product category, string. For example, `shoes`, `clothing`, or `accessories`.
- `source` — where the product was added from, string: `catalog` — from the catalog or `product_card` — from the product card.

**How to check**: add sneakers to favorites from the product card. The expected result is one `product_added_to_favorites` event with the parameters `product_id: sneakers_042`, `category: shoes`, and `source: product_card`.

{% endcut %}

This is an example of markup: you choose the names of events, parameters, and their values for your app.

### 3. Pass the task to the developer {#step-developer}

Pass the markup and examples of actions for verification. Agree on where each action is recorded — in the app or on the server — and in which version of the app or server service the sending will appear. Ask the developer to notify you when the setup can be checked.

Technical instructions for the developer are collected below.

{% note info %}

The markup describes what action and at what moment needs to be recorded. The developer adds the sending to the app or server and transfers the parameters according to the agreed rules.

{% endnote %}

{% cut "For the developer: setting up sending and event parameters" %}

Download the instructions for the developer (TXT): {% file src="../../_assets/instructions/custom-developer-en.txt" name="custom-developer-en.txt" type="text/plain; charset=utf-8" %}

#### How to send via the SDK {#send-via-sdk}

The developer adds an SDK method call to the place in the code where the selected action occurs. Use the instructions for the platform:

- [Android](https://appmetrica.yandex.by/docs/en/sdk/android/analytics/android-operations.md#report-event)
- [iOS](https://appmetrica.yandex.by/docs/en/sdk/ios/analytics/ios-operations.md#report-event)
- [Flutter](https://appmetrica.yandex.by/docs/en/sdk/flutter/analytics/flutter-operations.md#report-event)
- [React Native](https://appmetrica.yandex.by/docs/en/sdk/react-native/analytics/react-native-operations.md#report-event)
- [Unity](https://appmetrica.yandex.by/docs/en/sdk/unity/analytics/unity-operations.md#report-event)

#### How to send from the server {#send-from-server}

If the action information is available on the server, use [event upload via the Post API](https://appmetrica.yandex.by/docs/en/mobile-api/post/post-import-events.md). Data is transferred via an HTTP request and linked to the profile or device identifier previously transferred via the SDK.

Before setup, check the [upload restrictions](https://appmetrica.yandex.by/docs/en/mobile-api/post/restrictions.md). Post API data is synchronized once every four hours — take this into account when checking.

#### Event nesting levels {#level}

To send an event with nested parameters, pass a `key:value` pair. In the interface, `key` and `value` are considered nesting levels.

![key-value](../../_images/levels.png){style="border: solid 1px #cccccc; max-width: 800px;"}

{% note info %}

AppMetrica allows you to pass nested parameters in an event that can have multiple levels.

{% endnote %}

When passing parameters in JSON format, each new object in the value indicates a new nesting level, for example:

```
{
"param1":"1",  // nesting level 1
"param2":"abc",
"param3": { 
	"paramLevel2": "2", // nesting level 2
	"param2Level2": {
		"paramLevel3": "3", // nesting level 3
		"param2Level3":{
			"level": "4" // nesting level 4
      }
    }
  }
}
```

The AppMetrica web interface displays up to five nesting levels for events. If an event has six or more levels, the top five are shown in the report.

{% note info %}

You can use the [Reporting API](https://appmetrica.yandex.by/docs/en/mobile-api/stat/intro.md) to get up to ten event nesting levels.

{% endnote %}

#### Interpretation of numeric and string values {#value}

In the AppMetrica interface, the values `{"count" : 3}` and `{"count" : "3"}` are interpreted the same way. However, when exporting data using the [Reporting API](https://appmetrica.yandex.by/docs/en/mobile-api/stat/intro.md) or [Logs API](https://appmetrica.yandex.by/docs/en/mobile-api/logs/about.md), the parameter is exported in the form in which it was sent to the server.

If the same event is passed multiple times with different numeric parameter values, the parameter values are not aggregated in the web interface. Each value is recorded and calculated separately.

{% note info %}

You can use the [Reporting API](https://appmetrica.yandex.by/docs/en/mobile-api/stat/intro.md) to export additional fields: the total and average of all numeric values.

{% endnote %}

#### Partially matched nested events {#similar}

You can pass different parameter values with the same event at all times.

If the server receives events with repeated parameters, their values are accumulated, and the report displays the count of each passed variant.

If the server receives events with repeated parameters but different nesting depths, their values are accumulated based on the repeated parameters.

For example, the first event has two nesting levels:

```
{
    "param1": "param2"
}
```

The second one has three nesting levels:

```
{
    "param1": {
        "param2": "value"
    }
}
```

In the web interface, these events are displayed as a tree view:

![tree view](../../_images/example.png){style="border: solid 1px #cccccc; max-width: 800px;"}

Events are counted using the following algorithm:

1. The event is recorded, along with two of its sublevels. 1 is added to each parameter.
1. 1 is added to the event name and three of its sublevels.

{% endcut %}

### 4. Check event collection {#step-check}

After setup, perform the prepared test actions in the agreed app version. Open the [Events](https://appmetrica.yandex.by/docs/en/mobile-reports/events-report.md) report and check:

- Whether the event with the name from the markup appeared.
- Whether the required parameters are transferred and whether their values match the performed action.
- Whether the number of events matches the expected number of sends.

Repeat the check with other parameter values. If the result differs from the markup, pass the developer a description of the action, the expected result, and what you saw in the report. After the fix, repeat the check. When sending via the Post API, keep in mind that events are synchronized once every four hours.

### 5. Use events in analysis {#step-analyze}

After checking, use the events and their parameters in the Events report. To analyze the sequence of actions and find the stages where users stop, set up a [funnel](https://appmetrica.yandex.by/docs/en/mobile-reports/funnels-report.md).

## How events are counted {#accounting}

Custom events consume the organization's quota. Sending with parameters counts as one event regardless of the number of parameters and nesting depth. Current terms are given in the [limit description](https://appmetrica.yandex.by/docs/en/troubleshooting/limit-events.md), and optimization recommendations are in the article [How to save on events](https://appmetrica.yandex.by/docs/en/data-collection/save-on-events.md).

<!-- source: en/_includes/feedback-button.md -->
If you didn't find the answer you were looking for, you can use the feedback form to submit your question. Please describe the problem in as much detail as possible. Attach a screenshot if possible.

<a href="../troubleshooting/feedback-new">
  <span class="button">Contact support</span>
</a>

<a href="../troubleshooting/feedback-docs">
  <span class="button">Suggest an improvement for documentation</span>
</a>
<!-- endsource: en/_includes/feedback-button.md -->
