# Identify users with String UID (/en/realtime-media/iot/build/authenticate-and-secure-channels/string-uid)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

Starting with v1.9.5, IoT SDK supports User Account-based identity, so you can identify a device or user with a string instead of an integer UID. Use this when your application already maintains string-based user accounts, for example an email address or a device serial number, and you want to reuse the same identifier in Agora channels instead of mapping it to an integer UID yourself.

<CalloutContainer type="info">
  <CalloutDescription>
    The first time a new user account is used, the SDK requests a server-side mapping from the string account to an integer UID, which can add a small amount of latency to that user's initial join.
  </CalloutDescription>
</CalloutContainer>

## Prerequisites

In order to follow this procedure you must have:

* Implemented the basic IoT SDK functionality. See [Build from scratch](../../build-from-scratch.mdx).

## Enable String UID

Set `use_string_uid` to `true` in `rtc_service_option_t` before you initialize the SDK:

```cpp
rtc_service_option_t service_opt = {
    .use_string_uid = true
};
int rval = agora_rtc_init(appid, &event_handler, &service_opt);
if (rval < 0) {
    printf("Failed to initialize Agora SDK, reason: %s\n", agora_rtc_err_2_str(rval));
    return -1;
}
```

Once you enable String UID, every client in the channel must join using a user account. You cannot mix integer UID and String UID clients in the same channel.

## Join a channel with a user account

Create a connection, then call `agora_rtc_join_channel_with_user_account` instead of `agora_rtc_join_channel`:

```cpp
connection_id_t conn_id = 0;
const char *user_account = "xxxx";

rval = agora_rtc_create_connection(&conn_id);
if (rval < 0) {
    printf("Failed to create connection, reason: %s\n", agora_rtc_err_2_str(rval));
    return -1;
}

rval = agora_rtc_join_channel_with_user_account(conn_id, "channel-xxx", user_account, token, &channel_opt);
if (rval < 0) {
    printf("Failed to join channel, reason: %s\n", agora_rtc_err_2_str(rval));
    return -1;
}
```

## Look up user information

Once a connection has joined the channel, retrieve information about a peer using either their user account or their integer UID:

* `agora_rtc_get_user_info_by_user_account`: look up a remote user's information by their user account.
* `agora_rtc_get_user_info_by_uid`: look up a remote user's information by their integer UID.

## Handle user account events

Register handlers for the following callbacks to track user account join, leave, and update events:

```cpp
static void __on_join_channel_success(connection_id_t conn_id, uint32_t uid, int elapsed)
{
LOGI("[conn-%u] Join channel success, uid=%u, elapsed=%dms", conn_id, uid, elapsed);
}

static void __on_user_joined_with_user_account(connection_id_t conn_id, const user_info_t *user, int elapsed_ms)
{
LOGI("[conn-%u] Remote user account %s (uid=%u) joined, elapsed=%dms", conn_id, user->user_account, user->uid, elapsed_ms);
}

static void __on_user_offline_with_user_account(connection_id_t conn_id, const user_info_t *user, int reason)
{
LOGI("[conn-%u] Remote user account %s (uid=%u) left, reason=%d", conn_id, user->user_account, user->uid, reason);
}

static void __on_user_info_updated(connection_id_t conn_id, const user_info_t *user)
{
LOGI("[conn-%u] User account %s (uid=%u) info updated", conn_id, user->user_account, user->uid);
}
```

* `on_join_channel_success`: the local user account joined successfully.
* `on_user_joined_with_user_account`: a remote user account joined the channel.
* `on_user_offline_with_user_account`: a remote user account left the channel.
* `on_user_info_updated`: a user's account information changed.

## Sample code

The IoT SDK package includes a complete String UID example. See the full implementation in `hello_rtsa.c`:

```
├── agora_rtsa_sdk  # Agora SDK libraries and header files
└── example
    └── hello_rtsa
        └── hello_rtsa.c  # Join a channel with String UID
```

## Reference

* [agora\_rtc\_join\_channel\_with\_user\_account](https://api-ref.agora.io/en/iot-sdk/linux/1.x/agora__rtc__api_8h.html)
* [agora\_rtc\_get\_user\_info\_by\_user\_account](https://api-ref.agora.io/en/iot-sdk/linux/1.x/agora__rtc__api_8h.html)
* [agora\_rtc\_get\_user\_info\_by\_uid](https://api-ref.agora.io/en/iot-sdk/linux/1.x/agora__rtc__api_8h.html)
* [on\_user\_joined\_with\_user\_account](https://api-ref.agora.io/en/iot-sdk/linux/1.x/structagora__rtc__event__handler__t.html)
* [on\_user\_offline\_with\_user\_account](https://api-ref.agora.io/en/iot-sdk/linux/1.x/structagora__rtc__event__handler__t.html)
* [on\_user\_info\_updated](https://api-ref.agora.io/en/iot-sdk/linux/1.x/structagora__rtc__event__handler__t.html)
