Getting started
This guide mints an identity token from your backend and wires it into each Messaging SDK. Read the identity tokens overview first for the flow and the security model.
Before you start
- You need an Ada API key for your backend. The key must never reach a browser or mobile app.
- You need the Ada
end_user_idof the person to identify. Create end users, or look them up by your ownexternal_id, with the End Users API.
Optional handoff details
Only your server can send verified_email and name when it mints an identity token.
Use an email address whose ownership your system has verified.
Ada links to or creates a Zendesk user from the email. A wrong email links the conversation to another person’s Zendesk user.
Verified email linking needs an external_id on the end user.
Create or look up the end user with an external_id through the End Users API.
Without an external_id, Zendesk Messaging handoffs ignore the Ada identity token, verified_email, and name.
When the mint request includes verified_email, Zendesk Messaging handoffs use it to link to or create your Zendesk end user.
Ada uses this order:
- Use the Zendesk end user with the same
external_idas the Platform API identity mapping. - Otherwise, link exactly one Zendesk end user with a matching primary email.
- If no match exists, create a Zendesk end user with the name and verified email.
Ada uses name from the mint request first, then the end user’s profile first_name and last_name.
Ada trims the profile names and joins them with a space.
See Authenticate end users for the full matching rules.
Ada carries the values encrypted in the token.
Ada stores the values encrypted on the session’s end user. Ada uses them only in the first 7 days after the exchange. Ada deletes them after the first Zendesk Messaging handoff uses them and Sunshine initialization succeeds. If no handoff uses them, Ada deletes them at the next handoff or token exchange after the 7 days end.
Session refresh does not extend this window.
Without verified_email or name, mint, exchange, and handoff keep their existing behavior.
If Sunshine initialization fails, Ada keeps the values for a retry. A new exchange replaces the previous linking values, including an exchange on another device. Expired sessions cannot supply these values.
When the exchanged token has decrypted claims, Ada updates jwt_email and jwt_name for display.
A missing or empty value clears its previous display copy only if that copy still matches the value Ada wrote.
Ada updates name only when it is empty or still equals the previous token’s name. It never writes email from these claims.
When Ada clears the linking values, including when it detects expiry, it also clears display copies that still match the values Ada wrote.
Without claims, exchange clears the previous claims and display copies that still match the values Ada wrote.
It does not use the profile name for display.
These display copies do not supply identity.
For validation, name fallback, and dashboard behavior, see Verified handoff details.
Step 1: Mint a token from your backend
Call POST /v2/auth/tokens/ with the end user’s id. Authenticate with your API key as a Bearer token:
A successful response returns 201 with the token:
expires_in is in seconds. The token expires 15 minutes after minting and can be exchanged exactly once.
Mint on demand, when your client is about to start or reset a chat session. Good mint points are sign-in and page load, always on your backend. Do not mint tokens in advance or cache them. Requests are rate limited per AI Agent; the limits are sized for one mint per end user opening chat. The Auth Tokens API reference documents the endpoint schema, error codes, and rate limits.
Step 2: Pass the token to the Web SDK
Deliver the token to your page over HTTPS, then pass it as identityToken:
The same setting works with adaEmbed.start() on the module-script path, and on window.adaSettings for pages that still configure through the global.
The SDK exchanges the token when the end user engages with the chat, before it restores any saved conversation state. An end user who never opens the chat never triggers the exchange.
Step 3: Handle exchange failures
Subscribe to the identity events on your host page:
A failed exchange does not block the conversation. The session falls back to the normal anonymous path, so the end user can still chat.
Every exchange attempt consumes the token, even when the attempt fails afterward. To retry identification, mint a fresh token. Never reuse one.
Step 4: Re-identify or switch users
Pass a new token to reset() when the signed-in user changes, or to retry after an expired token:
Rules:
- A full
reset()without a replacement token discards any token that has not finished exchanging. The old identified session cannot be re-adopted. reset({ resetChatHistory: false })preserves the current session, and with it any pending token.- When the end user signs out of your product, call
reset()so the next session starts anonymously.
Mobile SDKs
Each mobile SDK accepts the token at initialization and requires the Messaging runtime. The SDK injects the token into the WebView before any page script runs. The token never appears in a URL, and the runtime deletes it from the page after one read. A remount needs a freshly minted token.
iOS
Set identityToken at initialization. See the iOS SDK reference for details.
Android
See the Android SDK reference for details.
React Native
Fetch the token before you mount the view. A token set after mount only applies on the next document load. See the React Native guide for details.
Identify one user across two devices
One identity gives one conversation on every device and browser. This walkthrough signs the same end user in on a laptop browser and on a phone app.
Device 1: the laptop browser
- The end user signs in to your site. Your backend verifies them with your normal logic.
- Your backend mints a token for their
end_user_id, as in Step 1, and delivers it to the page. - The page passes the token as
identityToken:
When the end user opens the chat, the SDK exchanges the token and the identified conversation starts. Suppose they send “Where is my order?” and then close the laptop.
Device 2: the phone app
- The end user opens your mobile app and signs in. Your backend verifies them again.
- Your backend mints a second token for the same
end_user_id. The first token is spent, so this device needs its own mint. - The app passes the new token at initialization. React Native is shown here. iOS uses the
identityTokeninitializer parameter, and Android usesSettings.Builder.identityToken.
The exchange resolves to the same end user, and the phone restores the same conversation before the chat opens. “Where is my order?” and the AI Agent’s reply are already in the transcript. While both devices stay open, live updates flow to both over the same realtime channel. The phone’s exchange does not sign the laptop out; both hold live identified sessions.
Never send the laptop’s token to the phone. Tokens are single use, so the server rejects a replayed token and that session falls back to anonymous. Mint a fresh token on your backend for every device, at sign-in or page-load time.
This flow is verified end-to-end against a live environment on every change: two devices, two freshly minted tokens, one shared conversation.
Security checklist
- Mint only from your backend, with your API key kept server-side.
- Deliver tokens to clients over HTTPS only.
- Never place a token in a URL, query parameter, or deep link.
- Never log tokens on the server or the client.
- Mint a fresh token per attempt. Tokens are single use and expire in 15 minutes.