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

# Handle an event-based stat change

> Use XBOX services API (XSAPI) code to track event-based stat changes and clean up handlers by using the Real-Time Activity (RTA) service.

This topic provides example code for handling an event-based stat change. The examples are C++ code fragments that use the flat C API of the XBOX services API (XSAPI). XSAPI delivers the stat updates through the Real-Time Activity (RTA) service and manages the RTA subscriptions for you.

## Before you begin

The code fragments share one scope and assume the following:

* `xboxLiveContext` is an `XblContextHandle` for the signed-in user. To create one, call [XblContextCreateHandle](https://docs.xbox.com/reference/live/xsapi-c/xbox_live_context_c/functions/xblcontextcreatehandle.md).
* `xboxUserId` is the `uint64_t` XBOX user ID (XUID) of the player whose stats you want updates for.
* `scid` is a `const char*` that contains the Service Configuration ID (SCID) for your title.
* `TotalPuzzlesSolved` is an example stat name. Replace it with the name of an event-based stat that's configured for your title.
* `LogToScreen` is a `printf`-style logging function in your app.

**To get notifications about event-based stat changes**

1. [Add a stat-changed handler.](#add-a-stat-changed-handler)
2. [Track the stats that you want updates for.](#track-the-stats-that-you-want-updates-for)

**To clean up**

1. [Stop tracking stats.](#stop-tracking-stats)
2. [Remove a stat-changed handler.](#remove-a-stat-changed-handler)

## Add a stat-changed handler

Register an event handler for statistic change notifications by using the following example code.
The event handler receives an [XblStatisticChangeEventArgs](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/structs/xblstatisticchangeeventargs.md) object. If *xboxLiveContext* or the handler is null, `XblUserStatisticsAddStatisticChangedHandler` returns 0 and doesn't register the handler.

```cpp theme={null}
void* context{ nullptr };
XblFunctionContext statisticChangedFunctionContext = XblUserStatisticsAddStatisticChangedHandler(
    xboxLiveContext,
    [](XblStatisticChangeEventArgs eventArgs, void* context) 
    {
        // Handle stat change. 
        LogToScreen("Statistic changed callback: stat changed (%s = %s)",
            eventArgs.latestStatistic.statisticName, 
            eventArgs.latestStatistic.value); 
    },
    context
);

if (statisticChangedFunctionContext == 0)
{
    LogToScreen("XblUserStatisticsAddStatisticChangedHandler failed.");
}
```

## Track the stats that you want updates for

Your handler receives updates only for stats that you track. Call [XblUserStatisticsTrackStatistics](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/functions/xbluserstatisticstrackstatistics.md) with the users and stat names that you want updates for. You can change the set of tracked stats at any time, independently of your handlers.

```cpp theme={null}
const char* statisticNames[] = { "TotalPuzzlesSolved" };

HRESULT hr = XblUserStatisticsTrackStatistics(
    xboxLiveContext,
    &xboxUserId,
    1,
    scid,
    statisticNames,
    _countof(statisticNames)
);

if (FAILED(hr))
{
    LogToScreen("XblUserStatisticsTrackStatistics failed: 0x%08X", static_cast<unsigned int>(hr));
}
```

> [!NOTE]
>
> `XblUserStatisticsSubscribeToStatisticChange` and `XblUserStatisticsUnsubscribeFromStatisticChange` are deprecated. They still work, but they'll be removed in a future release, and depending on your compiler settings, calls to them can produce deprecation warnings. Use `XblUserStatisticsTrackStatistics` and `XblUserStatisticsStopTrackingStatistics` instead.

## Stop tracking stats

When you no longer need updates for specific stats, call [XblUserStatisticsStopTrackingStatistics](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/functions/xbluserstatisticsstoptrackingstatistics.md) with the same users, SCID, and stat names that you tracked.

```cpp theme={null}
hr = XblUserStatisticsStopTrackingStatistics(
    xboxLiveContext,
    &xboxUserId,
    1,
    scid,
    statisticNames,
    _countof(statisticNames)
);

if (FAILED(hr))
{
    LogToScreen("XblUserStatisticsStopTrackingStatistics failed: 0x%08X", static_cast<unsigned int>(hr));
}
```

Alternatively, to stop updates for all the stats that you track for a set of users, call [XblUserStatisticsStopTrackingUsers](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/functions/xbluserstatisticsstoptrackingusers.md) instead of `XblUserStatisticsStopTrackingStatistics`.

```cpp theme={null}
hr = XblUserStatisticsStopTrackingUsers(
    xboxLiveContext,
    &xboxUserId,
    1
);

if (FAILED(hr))
{
    LogToScreen("XblUserStatisticsStopTrackingUsers failed: 0x%08X", static_cast<unsigned int>(hr));
}
```

XSAPI counts tracking requests. If you track the same stat for a user more than once, call a stop-tracking function the same number of times to stop the updates.

## Remove a stat-changed handler

Remove an event handler for statistic change notifications by using the following example code.

```cpp theme={null}
XblUserStatisticsRemoveStatisticChangedHandler(
    xboxLiveContext,
    statisticChangedFunctionContext
);
```

## See also

* [Programming the Real-Time Activity (RTA) service](https://docs.xbox.com/services/xbox-services/fundamentals/rta/how-to/live-programming-rta.md)
* [XblStatisticChangeEventArgs](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/structs/xblstatisticchangeeventargs.md)
* [XblUserStatisticsAddStatisticChangedHandler](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/functions/xbluserstatisticsaddstatisticchangedhandler.md)
* [XblUserStatisticsTrackStatistics](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/functions/xbluserstatisticstrackstatistics.md)
* [XblUserStatisticsStopTrackingStatistics](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/functions/xbluserstatisticsstoptrackingstatistics.md)
* [XblUserStatisticsStopTrackingUsers](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/functions/xbluserstatisticsstoptrackingusers.md)
* [XblUserStatisticsRemoveStatisticChangedHandler](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/functions/xbluserstatisticsremovestatisticchangedhandler.md)


## Related topics

- [XblUserStatisticsAddStatisticChangedHandler](https://docs.xbox.com/reference/live/xsapi-c/user_statistics_c/functions/xbluserstatisticsaddstatisticchangedhandler.md)
- [Getting event-based stats](https://docs.xbox.com/services/xbox-services/player-data/stats-leaderboards/event-based/how-to/live-getting-eb-stat.md)
- [Portal configuration of event-based Stats](https://docs.xbox.com/services/xbox-services/player-data/stats-leaderboards/event-based/config/live-stats-eb-portal.md)
- [Event-based Stats & Leaderboards example code (contents)](https://docs.xbox.com/services/xbox-services/player-data/stats-leaderboards/event-based/how-to/live-statslb-eb-howto-nav.md)
- [Event-based Stats and leaderboards portal config (contents)](https://docs.xbox.com/services/xbox-services/player-data/stats-leaderboards/event-based/config/live-statslb-eb-config-nav.md)
