Users & Auth
Identify end users with your own userId, mint short-lived chat session tokens from your backend, and keep dashboard credentials off every client device.
Server-only mint
Tokens are issued only with your dashboard Basic Auth. Clients never hold the master key.
Configurable TTL
300–86400 seconds per token. Short sessions for web; longer for trusted mobile apps.
Your user ids
Bring your own userId — no separate Sendexa login for end users.
Scoped claims
Tokens encode business + user identity and cannot create channels without membership.
3600s
1 hour
5m–24h
300–86400 seconds
128
characters
60/min
per API key (soft)
Authentication
Authorization: Basic <token>. Auth guide →Authenticate in your app first
userId in your own session or JWT middleware.Request Body
{"userId": "user_01HZX9K2M","displayName": "Ama Mensah","ttl": 3600}
| Field | Type | Required | Description |
|---|---|---|---|
| userId | string | required | Your application's unique user id. Immutable for a real person. Used in membership and message.userId. |
| displayName | string | optional | Shown in channel UIs and presence. Updated when you mint a new token with a new value. |
| ttl | number | optional | Seconds until expiry. Default 3600. Range 300–86400. |
Response
{"success": true,"code": "CHAT_USER_TOKEN_ISSUED","message": "User chat token minted.","requestId": "REQ-1782001100001","timestamp": "2026-07-12T10:00:00.000Z","data": {"userId": "user_01HZX9K2M","displayName": "Ama Mensah","token": "chat_usr_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJ1c2VyXzAxSFpYOUsyTSIsImV4cCI6MTc4Mzg1NDgwMH0.signature","expiresAt": "2026-07-12T11:00:00.000Z","ttl": 3600}}
Code Examples
curl -X POST 'https://api.sendexa.co/v1/chat-sdk/users/token' \-H 'Content-Type: application/json' \-H 'Authorization: Basic YOUR_DASHBOARD_BASE64_TOKEN' \-d '{"userId": "user_01HZX9K2M","displayName": "Ama Mensah","ttl": 3600}'
Token Lifecycle
POST /v1/chat-sdk/users/token and hand data.token to the client once.Re-mint with the same userId before expiresAt. On the client, apply the new token without dropping the session:
await chat.updateToken(newToken);
On logout, disconnect the client. Tokens expire automatically at expiresAt; keep TTL short so stolen tokens die quickly.
await chat.disconnect();
Using the Token in the Client
import { SendexaChat } from '@sendexa/chat-sdk';// token from YOUR backend onlyconst chat = SendexaChat.init({ token: userChatToken });chat.on('error', (err) => {if (err.code === 'TOKEN_EXPIRED' || err.code === 'UNAUTHORIZED') {// Fetch a fresh token from your API, then:// await chat.updateToken(freshToken);}});await chat.connect();// The WebSocket and REST history calls use the user token automatically.
| Rule | Guidance |
|---|---|
| Stable userId | Never recycle a userId for a different person; membership and history are keyed by it. |
| One person, one id | Map all devices for the same login to the same userId so presence and read state merge correctly. |
| Agents & bots | Give support agents and bots their own userIds (e.g. agent_*, bot_*). Mint tokens for them the same way. |
| displayName | Optional cosmetic field; do not use it for authorization decisions. |
| PII | Prefer opaque ids. If you must use phone/email-derived keys, hash them first. |
HTTP Status Codes
| Code | Status | Description |
|---|---|---|
| 200 | OK | Token minted successfully |
| 400 | Bad Request | Missing userId, invalid ttl, or validation failure |
| 401 | Unauthorized | Invalid or missing Basic Auth credentials |
| 403 | Forbidden | Chat SDK not enabled for this business |
| 429 | Too Many Requests | Token mint rate limit exceeded |
| Error code | Cause |
|---|---|
INVALID_USER_ID | userId missing, empty, or exceeds 128 characters |
INVALID_TTL | ttl outside 300–86400 or not an integer |
UNAUTHORIZED | Missing/invalid Authorization: Basic header |
CHAT_SDK_DISABLED | Product not enabled for the business |
RATE_LIMIT_EXCEEDED | Too many mint requests — back off and retry |
Best Practices
- Keep dashboard Basic tokens only in server environment variables (never NEXT_PUBLIC_ or mobile builds)
- Prefer
ttl: 3600for web and refresh via your session; longer TTLs only on secure device storage - Log
requestIdfrom mint responses when debugging auth failures - On multi-tab web apps, share one token per user session and call
updateTokenin all tabs when refreshing