Custom identity provider
Implement a custom end-user identity provider to tie Convai's memory and MAU tracking to your own auth system, learner records, or kiosk login flow.
Convai's long-term memory, MAU (Monthly Active User) tracking, and end-user management features depend on a stable, consistent identifier for each user. For most training simulations and interactive experiences, you will want to replace the default device-based ID with one that is meaningful to your application — a user ID from your auth system, a learner record number, or any stable string that uniquely identifies one person across sessions and devices.
Prerequisites
A working Convai scene with a
ConvaiManagercomponentThe Long-Term Memory feature enabled on your characters for per-user memory to be visible
Your own user login or identity system to provide the stable user ID
If you do not have a user login system yet, the default device-based ID is sufficient — return here once auth is in place.
Identity provider interfaces
Two interfaces control how the SDK identifies the current user.
IEndUserIdentityProvider
The primary interface. The SDK calls GetEndUserId() once per ConnectAsync() and sends the result to Convai as the end-user identifier.
public interface IEndUserIdentityProvider
{
string GetEndUserId();
}Requirements for the returned string:
Must be non-null and non-empty. An empty string causes a failed connect.
Must be stable: the same user on the same device (or across devices) must return the same ID across sessions.
Must be unique per user. Shared IDs corrupt long-term memory across users.
If two distinct users resolve to the same ID, their long-term memory entries merge silently. There is no error — the data is simply wrong. Ensure your ID source is globally unique across your entire user base.
IEndUserMetadataProvider
Optional. Supply additional key-value metadata sent to Convai with the connect request. Use it to pass display names, role codes, department IDs, or any context that should accompany the user record.
The dictionary can be empty but must not be null. Values must be JSON-serializable primitives (string, int, float, bool). Non-serializable values are silently dropped.
Default behavior
DeviceEndUserIdProvider is the SDK's default. Its behavior differs by context:
Player build (Android, iOS, PC, etc.)
SystemInfo.deviceUniqueIdentifier with persisted GUID fallback
Stable per device; resets on OS reinstall or device wipe
Unity Editor
GUID stored in PlayerPrefs under key convai.end_user_id
Stable per Editor install; resets if PlayerPrefs are cleared
Replace the default when:
Your application has its own login system and sessions must follow the user, not the device.
Multiple learners share a single device (kiosk mode, shared lab machines).
You need cross-device continuity (mobile + desktop).
Compliance requires user IDs to match your own system of record.
Implement an identity provider
Register the provider
Identity providers can be registered in two ways depending on whether you also need to override other builder settings.
Direct setters (simpler)
Call SetEndUserIdentityProvider() and SetEndUserMetadataProvider() on ConvaiManager.ActiveManager before the first ConnectAsync() call. These setters work at any point in the scene lifecycle as long as a connection has not yet been established.
Do not call ConnectAsync() before your identity provider is set. If ConvaiManager is configured to connect automatically on Start (ConnectOnStart = true), disable that option and trigger the connect manually after login completes. Connecting before the provider is set causes the default device-based ID to be used, silently associating the session with the wrong identity.
CreateRuntimeBuilder override
Use this approach when you are also customizing other builder settings (credentials, persistence, modules) and want all customization in one place.
Usage examples
Example 1: Training platform with learner records
A corporate safety training platform identifies each employee by their LMS learner ID. Memory of past sessions (topics covered, mistakes made) persists across simulation runs.
Register via manager.SetEndUserIdentityProvider(new LmsIdentityProvider(lmsSession)) before connecting.
Example 2: Shared kiosk with PIN login
A hospital training kiosk is shared by multiple residents. Each resident logs in with a PIN, interacts with a simulated patient, then logs out. The next resident gets a clean session tied to their own identity.
On logout: disconnect from Convai, update ActiveResidentId, then reconnect for the next resident.
Example 3: Cross-device continuity for mobile + desktop
A learner starts a compliance training session on their phone and continues on a desktop workstation. Both devices resolve to the same stable user ID from your backend auth system, so Convai's memory follows the user regardless of which device they connect from.
Register after token validation: manager.SetEndUserIdentityProvider(new BackendAuthIdentityProvider(jwtSubClaim));
Troubleshooting
Long-term memory does not persist across sessions
Identity changes between sessions
Log the resolved ID before connecting to confirm it is stable across runs.
Two users share the same memory
Two different users resolve to the same ID
Ensure your ID source is globally unique across your entire user base.
Connect fails immediately after setting identity provider
GetEndUserId() threw an exception or returned an empty string
Wrap GetEndUserId() in a try-catch during development; log the exception message.
NullReferenceException in SetEndUserIdentityProvider
ConvaiManager.ActiveManager is null — manager Awake has not run yet
Call the setter in Start() or later, never in Awake().
Memory accumulates from a previous tester/device
DeviceEndUserIdProvider was active before the custom provider was registered
Clear the convai.end_user_id PlayerPrefs key in the Editor and reconnect.
Next steps
Long-term memoryCustom credential providerLast updated
Was this helpful?