Custom credential provider
Override the SDK's default credential source to supply API keys from environment variables, a secrets vault, or any runtime-resolved credential store.
By default, the Convai Unity SDK reads the API key and server URL from ConvaiSettings.asset, stored in Assets/Resources/. Some deployment contexts require credentials to come from elsewhere — a CI environment variable, a secrets manager, or a per-tenant configuration service.
Prerequisites
A working Convai scene with a
ConvaiManagercomponent on a GameObjectThe synchronous example (below) creates a subclass of
ConvaiManager— add the new component to that same GameObject and remove the originalConvaiManagercomponent. The asynchronous examples callConvaiManager.ActiveManagerfrom a plain component instead and need no subclass.
If you have not set up a scene yet, see Getting Started first.
How credentials flow through the SDK
When the runtime builds, ConvaiBootstrapConfigSnapshot captures the API key and server URL as an immutable pair. Once built, these values are exposed to modules and internal services via ICredentialProvider:
public interface ICredentialProvider
{
bool HasValidCredentials { get; }
string GetApiKey();
string GetServerUrl();
void Refresh();
}GetApiKey() and GetServerUrl() are called at connect time — not on every frame. HasValidCredentials gates connection attempts: if it returns false, the SDK will not attempt to connect. Refresh() is called when the SDK detects a credential-related error and wants the provider to reload from its source.
You do not implement ICredentialProvider directly. You supply credential values when building the runtime, and the SDK creates the provider internally from those values.
When a credential must be resolved asynchronously — a token fetched from your backend right before a connection attempt — the SDK resolves it through a second, additive interface, IAsyncCredentialProvider. Its EnsureCredentialsAsync(CancellationToken) method is awaited on the connect path, before GetApiKey() is read, so the SDK never needs an async ConvaiManager lifecycle hook for this case. You do not implement this interface directly either — see the asynchronous examples below and Write a custom token provider for the supported ways to supply a credential that must be fetched at connect time.
Provide custom credentials
Override CreateRuntimeBuilder() on a ConvaiManager subclass and call builder.UseConfig() with a ConvaiBootstrapConfigSnapshot constructed from your credential source. Always call base.CreateRuntimeBuilder() first — it handles platform-specific transport selection, event system setup, and other wiring you do not need to replicate. Calling UseConfig() afterward overrides only the credential snapshot.
In your Hierarchy, find the GameObject that has ConvaiManager on it. Add EnvironmentCredentialManager as a new component, then remove the original ConvaiManager component. The subclass inherits all ConvaiManager functionality — nothing else in the scene needs to change.
ConvaiBootstrapConfigSnapshot parameters
ConvaiBootstrapConfigSnapshot is immutable — all values are set at construction and cannot change after the runtime starts.
apiKey
string
—
Required. Your Convai API key.
serverUrl
string
—
Required. Convai realtime server URL.
connectionType
ConvaiConnectionType
Audio
Whether to connect with audio-only or audio + video.
serverEndpoint
ConvaiServerEndpoint
Connect
Server endpoint variant. Leave as default unless directed otherwise.
connectionTimeoutSeconds
float
30f
Timeout before a connect attempt is considered failed.
globalLogLevel
LogLevel
Info
Initial SDK log level. Can be changed at runtime via ConvaiSettings.
enableSessionResume
bool
true
Whether the SDK should attempt to resume previous sessions.
maxRetryAttempts
int
3
Maximum reconnection attempts before giving up.
ConvaiBootstrapConfigSnapshot is captured at startup. If your credential source issues short-lived tokens, the SDK cannot automatically rotate them mid-session. Design your token lifetime to exceed the longest expected session, or disconnect and reconnect to apply a refreshed token.
Never log or serialize your API key to Unity's Console or a log file. ConvaiBootstrapConfigSnapshot intentionally omits the API key from its ToString() output.
Usage examples
Example 1: Environment variable with local fallback
Shown above in Provide custom credentials. Best for CI/CD pipelines and Docker-based deployments where secrets are injected as environment variables.
Example 2: Secrets vault fetch before startup
Some deployments pull credentials from a secrets service at launch. CreateRuntimeBuilder() runs synchronously inside ConvaiManager.Awake(), before any async code can complete, so a ConvaiManager subclass cannot await the vault call there. Resolve the credential asynchronously in a plain component instead, then pass the resolved value straight to ConvaiManager.ActiveManager.ConnectWithAuthTokenAsync() — the same explicit-credential connect path documented in Connect with an existing auth token. This requires Auth Token mode selected in Project Settings; see Configure Auth Token mode.
No ConvaiManager subclass is required — ConnectWithAuthTokenAsync accepts the resolved credential directly for that one connection attempt.
Example 3: Per-tenant credentials from a config service
Multi-tenant deployments where each customer has a different credential can resolve it from a tenant config endpoint before connecting, then pass the resolved value straight to ConnectWithAuthTokenAsync().
As with the vault example, this requires Auth Token mode selected in Project Settings. If every connection in the scene should resolve the tenant credential automatically without touching call sites, register an IConvaiAuthTokenProvider instead — see Write a custom token provider.
Troubleshooting
Cannot start: adapter not initialized. in Console
StartRuntimeAsync() was called before ConvaiManager.Awake() finished building the runtime and adapter — for example, a custom script called it directly
Let ConvaiManager's built-in lifecycle call StartRuntimeAsync(). Do not invoke it manually before Start().
Session connects but Convai returns auth error immediately
Empty or incorrect API key passed to snapshot
Log the resolved key length (not the value) to confirm it was populated before build.
IsValid returns false on config snapshot
apiKey or serverUrl is null or empty
Add a null check and fallback in your resolve methods.
ConvaiSettings.Instance is null in builds
ConvaiSettings.asset not present in Assets/Resources/
Only use ConvaiSettings.Instance as a fallback in editor/dev; never as the sole source in production builds.
Next steps
Custom identity providerCustom persistence providerLast updated
Was this helpful?