Skip to main content

Overview

This guide walks through a complete integration flow where your backend system creates an agent conversation in response to an event, then delivers that conversation to your end user via the embedded SDK widget. What you’ll build: A backend function that detects an event, starts an agent conversation about it, and directs the user to pick it up — with the agent’s response already waiting. Time to complete: 20–30 minutes Prerequisites:
  • A Mindset AI app with a configured agent (agentVersion 3)
  • An API key from the Developer section of AMS
  • Your API host URL — of the form {subdomain}.api.mindset.ai, shown as {api-host} in this guide. Available in the Developer section of AMS.
  • Your SDK script URL — shown as {MINDSET_SDK_LOCATION} in this guide. Also available in the Developer section of AMS.
  • The Mindset AI SDK v3 script loaded on the page where the agent will be embedded

How the Flow Works

Your backend makes two API calls before notifying the user, then one more when the user arrives.
Customer Backend                                    Mindset Platform
───────────────                                     ────────────────

1. Event occurs for user


2. POST /agentsessions ──────────────────────────►  Create agent session
   (externalUserId, agentUid)                       Returns: uid, agentSessionUid


3. POST /threads ─────────────────────────────────► Create thread, invoke agent
   (agentSessionUid, externalUserId, message)       Agent processes message
                                                    Returns: threadUid, humanUid


4. Store threadUid + agentSessionUid


5. Notify user (email, push, in-app)
         .
         .
         .
User arrives


6. POST /sdkusers/auth ──────────────────────────►  Authenticate user
   (externalId, name)                               Returns: authToken


7. Render page with embedded SDK
   <mindset-agent
     agent-uid="{agentSessionUid}"
     thread-uid="{threadUid}">


8. User sees the agent's response to the
   original event-specific message

Step-by-Step

1

Event Occurs

Your system detects an event that warrants a proactive agent conversation. You know which user it relates to and what information the agent needs.For this example, an order has shipped and you want an agent to proactively brief the user on their delivery details.
2

Create an Agent Session

Create an agent session that links the agent to the specific user. This session scopes the conversation and can optionally attach specific contexts or MCP servers.
POST https://{api-host}/api/v1/appuid/{appUid}/agentsessions
x-api-key: {apiKey}
Content-Type: application/json

{
  "agentUid": "your-agent-uid",
  "externalUserId": "user-12345",
  "mcpserverUids": ["order-tracking-tools", "customer-tools"],
  "contextUids": ["product-training"]
}
Response (201):
{
  "uid": "a1b2c3d4e5",
  "agentSessionUid": "your-agent-uid::a1b2c3d4e5",
  "humanUid": "firebase-uid-xyz",
  "agentUid": "your-agent-uid",
  "externalUserId": "user-12345",
  "contextUids": ["product-training"],
  "mcpserverUids": ["order-tracking-tools", "customer-tools"],
  "createdAt": "2026-02-27T10:30:00.000Z"
}
Store the agentSessionUid value — you’ll need it in steps 3 and 7.Optional fields:
FieldPurpose
tagsLabel the session (e.g., ["order-shipped", "priority"])
3

Create a Thread via the Threads API

Use the Threads API to start a new conversation thread. The agent processes your message and generates its first response.
POST https://{api-host}/api/v1/appuid/{appUid}/threads
x-api-key: {apiKey}
Content-Type: application/json

{
  "agentUid": "your-agent-uid::a1b2c3d4e5",
  "externalUserId": "user-12345",
  "messageType": "system",
  "message": "Order ORD-98765 for customer user-12345 has shipped via FedEx, tracking number 1Z999AA10123456784, estimated delivery March 2nd. Please brief the user on their delivery status and offer to help with any questions about their order."
}
Pass the full agentSessionUid (the composite agentUid::sessionUid string) as the agentUid field. This links the thread to the session you created in step 2.
Use the same user identifier type (externalUserId in this example) that you used when creating the agent session.
Response (201):
{
  "threadUid": "t9x8y7z6w5",
  "humanUid": "firebase-uid-xyz",
  "agentUid": "your-agent-uid"
}
Store the threadUid — this is the conversation the user will be directed to.The API waits for the agent to process your message before responding. The agent’s first response is now stored in the thread and ready for the user to see.

Message Types

By default, your message appears in the conversation as a visible user message. To have the agent act on context without the user seeing your original prompt, use messageType: "system":
{
  "agentUid": "your-agent-uid::a1b2c3d4e5",
  "externalUserId": "user-12345",
  "message": "The user's name is Jane. Order ORD-98765 has shipped. Tracking: 1Z999AA10123456784. Delivery: March 2nd. Brief the user naturally about their delivery.",
  "messageType": "system"
}
With "system", the user only sees the agent’s response — not your original message. Because your backend knows who the user is and what triggered the event, you can include personal details (name, order number, account status) in the system message. The agent can then greet the user by name and reference specifics naturally, without needing agent memory or prior conversation history.
4

Store the Identifiers

Your system now has everything it needs to deliver this conversation to the user later.
ValueFromUsed In
agentSessionUidStep 2 responseEmbedding the SDK (step 7)
threadUidStep 3 responseEmbedding the SDK (step 7)
externalUserIdYour systemAuthenticating the user (step 6)
Store these against the user and event in your system.
5

Notify the User

Notify the user through whatever channel suits your application — email, push notification, in-app alert, SMS. Include a link that takes them to the page where the agent is embedded.This step is entirely within your system. Mindset doesn’t send the notification.See Building Deep Links below for how to construct the link.
6

Authenticate the User

When the user arrives, authenticate them with Mindset to get a Firebase auth token. Use the same identifier you used in steps 2 and 3.
POST https://{api-host}/api/v1/appuid/{appUid}/sdkusers/auth
x-api-key: {apiKey}
Content-Type: application/json

{
  "externalId": "user-12345"
}
The sdkusers/auth endpoint uses externalId (not externalUserId). This refers to the same user — the field name just differs between APIs.
Response (201):
{
  "authToken": "eyJhbGciOiJSUzI1NiIs..."
}
7

Embed the SDK with the Thread

Render the page with the Mindset AI SDK, passing the agentSessionUid and threadUid so the widget loads the existing conversation rather than starting a new one.
<script src="https://{{MINDSET_SDK_LOCATION}}/mindset-sdk3.umd.js"></script>

<mindset-agent
  agent-uid="{agentSessionUid}"
  thread-uid="{threadUid}">
</mindset-agent>

<script>
  window.MindsetAgent.initialize({
    appUid: '{appUid}',
    fetchAuthentication: async () => {
      // Return the authToken obtained in step 6
      return '{authToken}';
    }
  });
</script>
Replace the placeholders:
  • {appUid} — your Mindset app UID
  • {agentSessionUid} — the composite string from step 2 (e.g., your-agent-uid::a1b2c3d4e5)
  • {threadUid} — the thread UID from step 3
  • {authToken} — the token from step 6
8

User Sees the Conversation

The SDK loads the existing thread and displays the agent’s response to the event-specific message you sent in step 3. The user can continue the conversation naturally from there.
  • If messageType was "user" (the default), the user sees both their message and the agent’s reply.
  • If messageType was "system", the user sees only the agent’s reply — the conversation appears to have been initiated by the agent.

User Identifier Consistency

You must use the same user identifier type across all three API calls. The identifier resolves to the same internal user, so mixing types creates separate users.
API CallField NameExample Value
Agent Sessions (step 2)externalUserIduser-12345
Threads (step 3)externalUserIduser-12345
SDK Users Auth (step 6)externalIduser-12345
The sdkusers/auth endpoint uses externalId rather than externalUserId. Despite the different field name, these refer to the same identifier.

Using Email-Based Identifiers

If your users are identified by email rather than an external ID:
API CallField NameExample Value
Agent Sessions (step 2)sdkUserEmailjane@example.com
Threads (step 3)sdkUserEmailjane@example.com
SDK Users Auth (step 6)sdkUserEmailjane@example.com

Error Handling

Thread Creation Errors

StatusMeaningAction
404Agent not found or not version 3Check agent UID and that the agent is active
422User identifier invalid or agent denied accessCheck identifier format; review agent access rules
502Agent processing failedRetry; if persistent, check agent configuration
503Agent service unavailableRetry after a short delay
504Agent timed out (120s)The message may be too complex — simplify or retry

SDK Thread Loading

If the threadUid is invalid or the thread can’t be loaded, the SDK displays an error message and offers the user a “Start New Thread” option to begin a fresh conversation.

Complete Backend Example (Node.js)

const API_HOST = 'https://{api-host}';
const APP_UID = 'your-app-uid';
const API_KEY = 'your-base64-api-key';
const AGENT_UID = 'your-agent-uid';

async function createProactiveThread(externalUserId, eventMessage) {
  // Step 2: Create agent session
  const sessionRes = await fetch(
    `${API_HOST}/api/v1/appuid/${APP_UID}/agentsessions`,
    {
      method: 'POST',
      headers: {
        'x-api-key': API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        agentUid: AGENT_UID,
        externalUserId,
        mcpserverUids: ['order-tracking-tools', 'customer-tools'],
        contextUids: ['product-training'],
      }),
    }
  );
  const session = await sessionRes.json();

  // Step 3: Create thread
  const threadRes = await fetch(
    `${API_HOST}/api/v1/appuid/${APP_UID}/threads`,
    {
      method: 'POST',
      headers: {
        'x-api-key': API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        agentUid: session.agentSessionUid,
        externalUserId,
        message: eventMessage,
        messageType: 'system',
      }),
    }
  );
  const thread = await threadRes.json();

  return {
    agentSessionUid: session.agentSessionUid,
    threadUid: thread.threadUid,
  };
}

async function getAuthToken(externalUserId) {
  // Step 6: Authenticate user
  const authRes = await fetch(
    `${API_HOST}/api/v1/appuid/${APP_UID}/sdkusers/auth`,
    {
      method: 'POST',
      headers: {
        'x-api-key': API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        externalId: externalUserId,
      }),
    }
  );
  const auth = await authRes.json();

  return auth.authToken;
}
The flow above creates several identifiers that together point to a specific conversation for a specific user. To notify the user in step 5, you need to build a link that routes them to the right place in your application. In the embedded SDK model, the Mindset agent lives inside your application. You control how users log in, what pages exist, and how the <mindset-agent> element is rendered. Mindset can’t generate a working deep link for you because we don’t know your application’s URL structure or routing. What we provide is the set of identifiers your application needs to render the right conversation — you build the link. At minimum, your link needs to carry enough information for your application to:
  1. Identify the user (so your app can authenticate them and call /sdkusers/auth)
  2. Retrieve the stored agentSessionUid and threadUid (so your app can render <mindset-agent> with the correct attributes)
How you encode this is up to you. Three common approaches: Option A: Encode the Mindset identifiers directly in the URL
https://app.example.com/agent?sid=your-agent-uid::a1b2c3d4e5&tid=t9x8y7z6w5
Your page reads sid and tid from the query string and passes them to the SDK element. Authentication is handled by your existing user session. Option B: Use your own event or notification ID
https://app.example.com/notifications/evt-77890
Your application looks up event evt-77890 in your database, retrieves the associated agentSessionUid and threadUid stored in step 4, authenticates the user, and renders the agent. Option C: Route within an existing page
https://app.example.com/dashboard#agent/t9x8y7z6w5
Your SPA catches the hash route and opens the agent panel with the correct thread.
Subject: Update on your order ORD-98765

Hi Jane,

Your order has shipped! Our AI assistant has prepared a delivery
briefing for you.

[View delivery details]
→ https://app.example.com/agent?sid=your-agent-uid::a1b2c3d4e5&tid=t9x8y7z6w5
When Jane clicks the link, your application:
  1. Recognises Jane from her existing session (or prompts login)
  2. Reads sid and tid from the query string
  3. Calls /sdkusers/auth with Jane’s externalId to get an auth token
  4. Renders <mindset-agent agent-uid="{sid}" thread-uid="{tid}"> with the token

Universal Client: A Simpler Path

When Mindset provides the entire end-user application — as with Universal Client — the deep linking story is simpler:
  • User identifier: realEmailAddress — users log into the UC app directly with their real email, so there’s no need for /sdkusers/auth or external ID mapping
  • Agent session: Not required — the Threads API can be called with a plain agentUid rather than a composite agentSessionUid, because the UC app manages agent access directly
  • Deep link: A URL pointing to the specific app, agent, and thread within the UC app
In this model, the only API call your external system needs to make is the Threads API itself.
Deep link URL patterns for Universal Client are under active development and will be documented separately.