> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ada.cx/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ada.cx/_mcp/server.

# Getting started

The Auth Tokens API mints a single-use identity token for an existing end user. Your backend mints the token, your client passes it to the Messaging SDK, and the SDK exchanges it automatically. This page walks through the mint request and the handoff to the SDK.

For the full flow and the security model, see the [Auth Tokens API overview](/reference/auth-tokens/overview).

## Before you begin

* An [API token](/reference/introduction/authentication), kept on your backend
* The Ada `end_user_id` of the person to identify. Create end users, or look them up by your own `external_id`, with the [End Users API](/reference/end-users/overview).

## Step 1: Mint an identity token

Call `POST /v2/auth/tokens/` from your backend with the end user's id:

```bash
curl -X POST https://EXAMPLE.ada.support/api/v2/auth/tokens/ \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "end_user_id": "6657912fd012e36f8bdde124",
    "verified_email": "Ada.Lovelace@example.com",
    "name": "Ada Lovelace"
  }'
```

The optional `verified_email` must be an address whose ownership your server has verified.
The optional `name` supplies the end user's name for Zendesk Messaging handoffs.
Only your server sends these values.

> **Warning**
>
> Ada links to or creates a Zendesk user from the email.
> A wrong email links the conversation to another person's Zendesk user.
>
> [Read all risks](/docs/handoffs/zendesk/zendesk-messaging#authenticate-end-users)

Ada trims both fields before validation.
The email must be valid and at most 254 characters; the name must be a string of at most 255 characters.
Omit either field if you do not need it.

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.

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.
See [Optional verified details](/reference/auth-tokens/overview#optional-verified-details) for value lifetime, deletion, and dashboard display.

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:

1. Use the Zendesk end user with the same `external_id` as the Platform API identity mapping.
2. Otherwise, link exactly one Zendesk end user with a matching primary email.
3. 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.
If Sunshine initialization fails, Ada keeps the values for a retry.
See [Authenticate end users](/docs/handoffs/zendesk/zendesk-messaging#authenticate-end-users) for the full matching rules.

A successful request returns `201` with the token:

```json
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "type": "identity",
  "expires_in": 900
}
```

| Field        | Type    | Description                                                          |
| ------------ | ------- | -------------------------------------------------------------------- |
| `token`      | string  | Single-use JWT that the Messaging SDK exchanges. Treat it as opaque. |
| `type`       | string  | Always `identity`.                                                   |
| `expires_in` | integer | Token lifetime in seconds. Always `900` (15 minutes).                |

### Errors

| Status | When it occurs                                                                                |
| ------ | --------------------------------------------------------------------------------------------- |
| `400`  | `end_user_id` is invalid, or `verified_email` or `name` fails validation. Ada stores nothing. |
| `401`  | The API token is missing or invalid.                                                          |
| `404`  | No end user matches the supplied `end_user_id`.                                               |
| `429`  | The request exceeded the rate limit. Back off and retry.                                      |
| `503`  | Token minting is not available for this AI Agent. Contact your Ada team.                      |

When your client is about to start or reset a chat session, mint a fresh token. Do not mint tokens in advance or cache them.

## Step 2: Pass the token to the Messaging SDK

Return only the `token` value to your client over HTTPS, then pass it to the SDK as `identityToken`:

```ts
import { loadAdaMessaging } from "@ada-cx/messaging-sdk";

const token = await fetchAdaIdentityToken(); // your backend call

const ada = await loadAdaMessaging({
  handle: "EXAMPLE",
  identityToken: token,
});
```

The SDK exchanges the token when the end user engages with the chat. The exchange consumes the token, so every session and every device needs a freshly minted token.

Follow the [identity tokens getting started guide](/messaging/identity/getting-started) for exchange failure handling, re-identification through `reset()`, and a two-device walkthrough.

Each platform documents its `identityToken` option:

* [Web SDK reference](/messaging/web/sdk-api-reference#identitytoken)
* [iOS SDK reference](/messaging/ios/sdk-api-reference#identitytoken)
* [Android SDK reference](/messaging/android/sdk-api-reference#identitytoken)
* [React Native SDK reference](/messaging/react-native/sdk-api-reference#identitytoken)