> 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.

# Mint an identity token

POST https://example.ada.support/api/v2/auth/tokens/
Content-Type: application/json

Mints a short-lived, single-use identity token for an existing end user.
The token contains Ada identity references.
When the request includes `verified_email` or `name`, the token also carries those values encrypted.
Treat the token as opaque.
The Messaging SDK exchanges it for messaging session auth.


Reference: https://docs.ada.cx/reference/auth-tokens/create-identity-token

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Request

### Body (application/json)

This endpoint expects an IdentityTokenRequest.

- `end_user_id` (string, required) — The Ada end user ID to identify the messaging session as
- `verified_email` (string, optional) — An optional email address whose ownership your server has verified. Ada links only when the mint request includes this field. 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](https://docs.ada.cx/docs/handoffs/zendesk/zendesk-messaging#authenticate-end-users). Send it only from your server when you mint the identity token. Ada removes surrounding whitespace and accepts valid addresses of at most 254 characters after trimming. Ada carries the linking values encrypted in the identity 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. A new exchange replaces the previous linking values. Sunshine initialization errors keep the value available for a retry. When the request includes this field, exchange updates the display copy jwt_email. A missing or empty value clears its previous display copy only if that copy still matches the value Ada wrote. Claim clearing also clears this display copy only if it still matches the value Ada wrote. Ada never writes META email or reads the display copy for identity. Tokens contain no plaintext name or email. Ada omits the linking values from API responses, end-user resources, and webhooks. Ada sends display copies to the end user's browser and shows them in the dashboard.
- `name` (string, optional) — The end user's optional name, supplied only by your server when you mint the identity token. Ada stores and displays this name only when the mint request includes it. Ada links to or creates a Zendesk user only when the request also includes verified_email. Ada removes surrounding whitespace and accepts at most 255 characters after trimming. Ada carries the linking values encrypted in the identity 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. A new exchange replaces the previous linking values. Sunshine initialization errors keep the value available for a retry. If verified_email is present and this name is empty or absent, handoffs use the profile first_name and last_name. When the request includes this field, exchange updates the display copy jwt_name. A missing or empty value clears its previous display copy only if that copy still matches the value Ada wrote. Exchange updates META name only when empty or equal to the previous token-derived name. Claim clearing also clears jwt_name and META name only if they still match the values Ada wrote. Ada never reads display copies for identity. Tokens contain no plaintext name or email. Ada omits the linking values from API responses, end-user resources, and webhooks. Ada sends display copies to the end user's browser and shows them in the dashboard.

## Response

### 201

Identity token minted

- `token` (string, required) — Short-lived, single-use JWT exchanged by the Messaging SDK
- `type` (enum, required) — Token type
  - Allowed values: `identity`
- `expires_in` (enum, required) — Fixed identity token lifetime in seconds
  - Allowed values: `900`

## Errors

### 400 Bad Request Error

Bad Request

- `errors` (list of ErrorsErrorsItems, required) — A list of errors

### 401 Unauthorized Error

Unauthorized

- `errors` (list of ErrorsErrorsItems, required) — A list of errors

### 404 Not Found Error

Not Found

- `errors` (list of ErrorsErrorsItems, required) — A list of errors

### 429 Too Many Requests Error

Too Many Requests

- `errors` (list of ErrorsErrorsItems, required) — A list of errors

### 500 Internal Server Error

Internal Server Error

- `errors` (list of ErrorsErrorsItems, required) — A list of errors

### 503 Service Unavailable Error

Service Unavailable

- `errors` (list of ErrorsErrorsItems, required) — A list of errors

## Types

### ErrorsErrorsItems

- `type` (string, required) — The error type
- `message` (string, required) — The error message
- `details` (string, optional, nullable) — Extra information about the error

## Examples

**Request**

```json
{
  "end_user_id": "6657912fd012e36f8bdde124"
}
```

**Response**

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

**SDK Code**

```python
import requests

url = "https://example.ada.support/api/v2/auth/tokens/"

payload = { "end_user_id": "6657912fd012e36f8bdde124" }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://example.ada.support/api/v2/auth/tokens/';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"end_user_id":"6657912fd012e36f8bdde124"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://example.ada.support/api/v2/auth/tokens/"

	payload := strings.NewReader("{\n  \"end_user_id\": \"6657912fd012e36f8bdde124\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://example.ada.support/api/v2/auth/tokens/")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"end_user_id\": \"6657912fd012e36f8bdde124\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://example.ada.support/api/v2/auth/tokens/")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"end_user_id\": \"6657912fd012e36f8bdde124\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://example.ada.support/api/v2/auth/tokens/', [
  'body' => '{
  "end_user_id": "6657912fd012e36f8bdde124"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://example.ada.support/api/v2/auth/tokens/");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"end_user_id\": \"6657912fd012e36f8bdde124\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["end_user_id": "6657912fd012e36f8bdde124"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://example.ada.support/api/v2/auth/tokens/")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```