> 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

For [Messaging identity tokens](/messaging/identity/getting-started), your backend creates an end user or looks one up by `external_id`. Pass the resulting identity token to the SDK; the conversation creation flow below remains specific to custom channels.

The End Users API lets you create and work with end-user data in Ada and respond to changes as users interact across channels. This page highlights common integration patterns to help you get started quickly.

The guides below show how to:

* [Create an end user with context before a conversation starts](#create-an-end-user-with-context-before-a-conversation) (custom channels only)
* [Pass sensitive metadata securely](#pass-sensitive-metadata-securely)
* Use end-user attributes to influence conversations in real time, such as [changing the conversation language](#change-conversation-language-based-on-end-users-selection-on-any-channel) based on a user's selection.
* [Receive webhook notifications when an end user is created or updated](#get-notified-at-your-webhook-when-an-ada-end-user-is-created-or-updated), so your systems stay in sync with Ada.

For end-to-end examples and advanced patterns, see the [developer guide](/reference/end-users/developer-guide). For a complete overview of end-user concepts and available endpoints, see the [End Users API Overview](/reference/end-users/overview).

## Create an end user with context before a conversation

> **Info**
>
> This flow is for **custom channel (Conversations API) integrations only**. For legacy Chat, use the Chat SDK [`setMetaFields()`](/chat/web/sdk-api-reference#setmetafields) instead.

Use `POST /v2/end-users/` to create an end user with profile data (language, metadata) before starting a conversation. This ensures the AI Agent has full context from the greeting onward.

### Before you begin

* An [API token](/reference/introduction/authentication)
* A [custom channel](/reference/conversations/create-channel) configured in the Ada dashboard

### Steps

1. Create the end user with language and metadata:
   ```bash
   curl -X POST https://EXAMPLE.ada.support/api/v2/end-users/ \
     -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
       "profile": {
         "language": "pt-BR",
         "metadata": {
           "region": "latam",
           "plan_type": "enterprise"
         }
       }
     }'
   ```
2. Copy the `end_user_id` from the response.
3. Start a conversation using the `end_user_id`:
   ```bash
   curl -X POST https://EXAMPLE.ada.support/api/v2/conversations/ \
     -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
       "channel_id": "YOUR_CHANNEL_ID",
       "end_user_id": "END_USER_ID_FROM_STEP_1"
     }'
   ```
4. The greeting fires in the correct language (`pt-BR`), with metadata values available as metavariables for Playbooks, Actions, and article rules.

## Pass sensitive metadata securely

Use the `sensitive_metadata` field to pass auth tokens, session IDs, or personally identifiable information through a secure, write-only pathway. Values are encrypted at rest, redacted from the dashboard, excluded from LLM context, and automatically deleted after 24 hours.

`sensitive_metadata` is available on both `POST /v2/end-users/` and `PATCH /v2/end-users/:id`. The conversation creation examples use custom channels.

### Set sensitive metadata at user creation time

```bash
curl -X POST https://EXAMPLE.ada.support/api/v2/end-users/ \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "profile": {
      "language": "en-US",
      "sensitive_metadata": {
        "fields": {
          "auth_token": "eyJhbGciOiJIUzI1NiIs...",
          "session_id": "sess_abc123"
        }
      }
    }
  }'
```

The `sensitive_metadata` values do not appear in the response. The AI Agent can use them to execute authenticated Actions. MCP tools that act as the end user can use a value too, when it is a token the MCP server accepts and the server connection [names the field](/docs/automation/tools/mcp-tools/authentication-and-channels).

### Update sensitive metadata mid-conversation

```bash
curl -X PATCH https://EXAMPLE.ada.support/api/v2/end-users/END_USER_ID \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "profile": {
      "sensitive_metadata": {
        "fields": {
          "auth_token": "eyJhbGciOiJSUzI1NiIs..."
        }
      }
    }
  }'
```

### Remove a sensitive metavariable

Set the key to `null`:

```bash
curl -X PATCH https://EXAMPLE.ada.support/api/v2/end-users/END_USER_ID \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "profile": {
      "sensitive_metadata": {
        "fields": {
          "auth_token": null
        }
      }
    }
  }'
```

## Reuse end users across conversations with external\_id

Use the optional `external_id` field to reference end users by a stable identifier from your own system — for example a CRM contact ID or a phone number. The same value can be used to look up, create, or update end users across conversations without storing Ada's `end_user_id`.

> **Info**
>
> The conversation creation example below applies to custom channels. For Messaging, use the end-user lookup with [identity tokens](/messaging/identity/getting-started) and start the session through the SDK.

### Before you begin

* An [API token](/reference/introduction/authentication)
* A [custom channel](/reference/conversations/create-channel) configured in the Ada dashboard
* A stable identifier from your system for the end user (maximum 36 characters, must not contain `<` or `>`)

### Steps

1. Look up the end user by external ID:

   ```bash
   curl -X GET "https://EXAMPLE.ada.support/api/v2/end-users/?external_id=user-12345" \
     -H "Authorization: Bearer YOUR_API_TOKEN"
   ```

   A `200` response returns the existing end user. A `404` response means no end user is mapped to that `external_id` yet. A `400` response indicates the value failed validation — for example, an empty value, a value longer than 36 characters, or a value containing `<` or `>`.

2. If the lookup returned `404`, create the end user with the `external_id`:

   ```bash
   curl -X POST https://EXAMPLE.ada.support/api/v2/end-users/ \
     -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
       "external_id": "user-12345",
       "profile": {
         "language": "en-US",
         "metadata": {
           "plan_type": "enterprise"
         }
       }
     }'
   ```

   `POST /v2/end-users/` is idempotent when `external_id` is supplied. If a user with that `external_id` already exists, the response is `200` with the existing record. A new user returns `201`.

3. Start a conversation with the returned `end_user_id`:
   ```bash
   curl -X POST https://EXAMPLE.ada.support/api/v2/conversations/ \
     -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
       "channel_id": "YOUR_CHANNEL_ID",
       "end_user_id": "END_USER_ID_FROM_PREVIOUS_STEP"
     }'
   ```

4. To clear an `external_id` later (for example to reassign it), send a `PATCH` with `external_id` set to `null`. `profile` is required on `PATCH` requests, so pass an empty `profile` object when you only need to clear `external_id`:
   ```bash
   curl -X PATCH https://EXAMPLE.ada.support/api/v2/end-users/END_USER_ID \
     -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
       "profile": {},
       "external_id": null
     }'
   ```

## Change conversation language based on end user's selection on any channel

### Before you begin

Before you start, make sure you have everything you need:

* An [API token](/reference/introduction/authentication) stored securely in Ada's [Token Vault](/docs/automation/tools/api-tools/token-configuration)

### Configure languages in your AI Agent

1. In your AI Agent's language settings, configure the following:
   * Ensure [multilingual and auto-translation](/docs/setup/languages/about-multilingual-support) are enabled in your AI Agent.
   * [Enable language support](/docs/setup/languages/about-multilingual-support) in your dashboard for one or two additional languages. We'll use French and Portuguese in this example.
2. In your AI Agent's greeting, use a List Option block to present the language options you selected to your user.
3. Use a Request block to set the end user's language to their list selection.

   ![](/_fern-img/e3d86327ea4b2fb4dda57494e02886040f6f11a4c617adde9d0bcdba7bbaac54.webp)
   > **Info**
   >
   > Language codes must be in BCP 47 4-digit format, per the [End Users API schema](https://example.ada.support/api/end-users/v1/docs#/End-Users/updateEndUserById).
4. Save your greeting.
5. Test the greeting in your Test Bot, embed, or any other channel. The conversation language should change immediately based on the end user's selection, and the AI Agent should immediately respond using the appropriate translation.

## Get notified at your webhook when an Ada end user is created or updated

### Before you begin

Before you set up your webhook, make sure you have everything you need:

* An Ada dashboard with the [Test Bot](/docs/optimization/testing/interactive-testing) enabled (or any other supported channel where your bot is active)
* An [API token](/reference/introduction/authentication)

### Set up your webhook

1. Set up a test webhook, or bring your own, with Ada's webhooks manager.
   1. On the Ada dashboard, find your webhook settings.
      * If you're using a **generative AI Agent**, go to **Platform** > **Webhooks**.
      * If you're using a **scripted bot**, go to **Settings** > **Integrations** > **Webhooks**.
   2. Click **Add Endpoint** to get started. If you don't have your own endpoint, [configure a test endpoint using Svix Play](https://docs.svix.com/receiving/using-app-portal/adding-endpoints).
   3. In the Message Filtering section, subscribe to both `v1.end_user.updated` and `v1.end_user.created` events.
   4. Click **Create** to save your endpoint.
2. Open your Test Bot in a new tab or window and start a conversation.
3. In a separate tab, open the Webhooks Logs to monitor new events. You'll see the conversation with your Test Bot has created an end user! There will be a corresponding log entry called `v1.end_user.created`.
4. Click on the log to see the webhook event payload and copy the `end_user_id` value.
5. Make a [PATCH request](/reference/end-user/patch-end-user-by-id) with the following payload:

   **`JSON`**

   ```json JSON
   {
      "profile": {
         "first_name": "Ada",
         "last_name": "Lovelace",
         "display_name": "Ada Lovelace",
         "avatar": "https://example.com/avatars/ada.png",
         "email": "ada.lovelace@ada.cx",
         "language": "en-US",
         "metadata": {
            "end_user_api_test": true
         }
      }
   }
   ```
6. Check the Webhooks Logs tab. A successful PATCH request will generate a `v1.end_user.updated` log.
7. You can continue to chat with Test Bot while making these changes to the end user. The End Users API can update records at any point whether a conversation is active or not. Go ahead and send a few messages to your AI Agent!
8. Finally, go the Conversations View and find your conversation. You'll see that the metavariables are updated from the PATCH request.

That's it! You have the building blocks to create an integration between your customer data platform and Ada's End Users API. Your integration can ingest webhook events and use the PATCH endpoint to send user details to Ada so that features such as [Article Rules](https://docs.ada.cx/docs/generative/set-up-your-ai-agent-s-knowledge-and-behavior/manage-your-knowledge-content#article-rules) can be applied automatically for your end users.