Overview
Live Chat (`product_id: conversations_suite`) is the only Connect product with a generally available public REST API. Use a product-scoped API token so your server or agent can mint hosted chat sessions, read and write conversations, list visitors, and manage outbound webhooks—without embedding secrets in mobile or browser clients.
| Item | Value |
|---|---|
| product_id | conversations_suite |
| Suite token (in keys) | live |
| Status | Generally available |
| Base URL (production) | https://umneyconnect.com/api |
| Base URL (staging) | https://www.staging.umneyconnect.com/api |
| OpenAPI | /developers/openapi-live-chat.json |
| Markdown (AI) | /developers/live-chat.md |
Get started
- In Dashboard → Billing, enable Live Chat & Inbox (conversations_suite).
- In Dashboard → Developers, create an API token for product Live Chat. Environment: live (production traffic) or test. Scopes: at least chat:write to mint sessions; add chat:read, visitors:read, webhooks:manage as needed. Optional: expiry and IP allowlist.
- Copy the plaintext secret once. Store as UMNEY_CONNECT_API_KEY (or equivalent) on your server / Nest / agent runtime.
- Call https://umneyconnect.com/api/v1/chat/... with Authorization: Bearer <token> or X-API-Key: <token>.
- Return chatUrl (from POST /v1/chat/sessions) to end-user apps—never the API token.
Minimal session mint
curl -X POST "https://umneyconnect.com/api/v1/chat/sessions" \
-H "Authorization: Bearer $UMNEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"externalId": "TAXI:trip_123:user:usr_456",
"displayName": "Maya Chen",
"source": "umney-safety",
"attributes": { "scopeType": "TAXI", "scopeId": "trip_123" }
}'Authentication & key formats
Live Chat live keys use the legacy form umk_live_<8>_<secret>. Test keys use umk_test_live_<8>_<secret>. Send either header style below. Responses include X-Request-ID.
Authorization: Bearer umk_live_<prefix>_<secret>
# or
X-API-Key: umk_live_<prefix>_<secret>| Scope | Required for |
|---|---|
| chat:write | POST /v1/chat/sessions, create conversation, send message |
| chat:read | List conversations and messages |
| visitors:read | GET /v1/chat/visitors |
| webhooks:manage | CRUD /tenants/{tenantId}/webhooks |
Concepts
| Resource | Meaning |
|---|---|
| Visitor | End user. Prefer stable externalId (e.g. Nest user or trip:user key) so repeats reopen the same person. |
| Session | Server-minted hosted chat link: chatUrl + visitorToken + conversationId. |
| Conversation | Inbox channel (status: open | pending | resolved | closed). Source often api, widget, or channel name. |
| Message | Visitor or agent/API content inside a conversation. |
| Widget | Tenant siteKey (umw_…) used by /widget/chat. Auto-created on first session mint if missing. |
| Webhook subscription | HTTPS endpoint receiving signed chat events. |
Do not confuse Live Chat tables (chat_channels, chat_visitors, …) with Growth Suite “conversations” CRUD under /api/growth/conversations—they share billing product_id but are different APIs.
POST /v1/chat/sessions
Mint a hosted visitor chat URL for Nest Safety, CRM deep links, or any server integration. Requires chat:write. Upserts visitor by externalId, reuses an open/pending channel when present, otherwise opens a new conversation and may auto-assign an agent.
| Field | Required | Notes |
|---|---|---|
| externalId | yes | Stable id ≤200 chars |
| displayName | no | Shown to agents |
| no | Visitor email | |
| name | no | Conversation title; defaults from displayName/email/externalId |
| source | no | Defaults to api |
| attributes | no | JSON object merged into visitor attributes |
200 response shape
{
"conversationId": "8bb7f3b8-7e0f-4a86-bd84-b39d669f06c1",
"chatUrl": "https://umneyconnect.com/widget/chat?siteKey=umw_…&token=…",
"externalId": "TAXI:trip_123:user:usr_456",
"visitorToken": "…",
"expiresAt": "2026-09-14T21:00:00.000Z",
"siteKey": "umw_…"
}Conversations
List and create inbox conversations. List supports cursor pagination on last_message_at.
| Method | Path | Scope | Query / body |
|---|---|---|---|
| GET | /v1/chat/conversations | chat:read | limit (1–100, default 50), cursor, status, source |
| POST | /v1/chat/conversations | chat:write | name (required), priority, optional visitor{externalId,displayName,email,attributes} |
curl "https://umneyconnect.com/api/v1/chat/conversations?limit=50&status=open" \
-H "Authorization: Bearer $UMNEY_API_KEY"
curl -X POST "https://umneyconnect.com/api/v1/chat/conversations" \
-H "Authorization: Bearer $UMNEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Website visitor", "source": "api", "priority": "normal" }'List response: { data: Conversation[], meta: { limit, nextCursor } }. Conversation fields include id, name, source, status, priority, assignedUserId, visitorId, unreadCount, lastMessageAt, createdAt, updatedAt.
Messages
| Method | Path | Scope | Notes |
|---|---|---|---|
| GET | /v1/chat/conversations/{id}/messages | chat:read | limit, optional after cursor |
| POST | /v1/chat/conversations/{id}/messages | chat:write | body { content } — sent as API/integration message |
curl "https://umneyconnect.com/api/v1/chat/conversations/{id}/messages" \
-H "Authorization: Bearer $UMNEY_API_KEY"
curl -X POST "https://umneyconnect.com/api/v1/chat/conversations/{id}/messages" \
-H "Authorization: Bearer $UMNEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "Hello from Nest" }'Visitors
GET /v1/chat/visitors requires visitors:read. Pass limit (1–100) to list, or externalId for an exact lookup. Prefer minting sessions with a stable externalId so the same person is reused across trips.
curl "https://umneyconnect.com/api/v1/chat/visitors?limit=50" \
-H "Authorization: Bearer $UMNEY_API_KEY"
curl "https://umneyconnect.com/api/v1/chat/visitors?externalId=TAXI:trip_123:user:usr_456" \
-H "Authorization: Bearer $UMNEY_API_KEY"Response: { data: Visitor[] } (plus meta.limit when listing). Fields: id, display_name, email, phone, external_id, attributes, created_at, last_seen_at.
Outbound webhooks
Manage subscriptions from Dashboard → Developers or with scope webhooks:manage. Secret is returned once on create. Deliveries drain on cron and opportunistically after chat events.
| Method | Path | Auth |
|---|---|---|
| GET | /tenants/{tenantId}/webhooks | webhooks:manage or tenant admin JWT |
| POST | /tenants/{tenantId}/webhooks | webhooks:manage or tenant admin JWT |
| PATCH | /tenants/{tenantId}/webhooks/{id} | webhooks:manage or tenant admin JWT |
| DELETE | /tenants/{tenantId}/webhooks/{id} | webhooks:manage or tenant admin JWT |
| GET | /tenants/{tenantId}/webhooks/{id}/deliveries | webhooks:manage or tenant admin JWT |
| POST | /tenants/{tenantId}/webhooks/{id}/test | webhooks:manage or tenant admin JWT |
| Event | Emitted today? |
|---|---|
| message.created | Yes — widget, agent, omnichannel |
| conversation.created | Yes — widget, support, omnichannel |
| conversation.closed | Yes — support/close flows |
| conversation.assigned | Yes — assignment flows |
| csat.submitted | Yes — CSAT submit |
| visitor.created | Allowlisted only — not emitted yet |
Delivery JSON body: { event, eventId, payload, timestamp }. Signed with X-Umney-Signature (HMAC-SHA256 hex of `${unixTimestamp}.${rawBody}`) and X-Umney-Timestamp. Drain runs on prod every 15m / staging every 6h, plus opportunistic drain after emitWebhookEvent.
const crypto = require('node:crypto');
function verify(rawBody, signatureHeader, timestampHeader, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestampHeader}.${rawBody}`, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signatureHeader, 'utf8'),
Buffer.from(expected, 'utf8'),
);
}Errors and rate limits
Per-route IP limits apply, plus 600 requests/minute per API key on /api/v1/*. HTTP 429 includes Retry-After, X-Request-ID, and X-RateLimit-Limit / Remaining / Reset. Session mint may record chat_session_mint usage when billing_usage_events exists.
{
"statusCode": 403,
"error": "Forbidden",
"message": "API key lacks required scope: chat:write",
"requestId": "…"
}API tokens for agents (Cloudflare-style)
Same ease-of-use model as Cloudflare: create an API token so an agent (Nest Safety, Agent Lee–style automation, CI) can access only Live Chat resources—not the whole workspace. Enable the product, mint a least-privilege token, store it server-side, call /v1/chat/*, return chatUrl to humans.
ENABLE_UMNEY_CONNECT=Yes
ENABLE_UMNEY_CONNECT_LIVE_CHAT=Yes
UMNEY_CONNECT_API_BASE_URL=https://umneyconnect.com/api
UMNEY_CONNECT_API_KEY=umk_live_… # conversations_suite + chat:write
# Agent workflow
# 1. Read /llms.txt → open /developers/live-chat.md
# 2. Confirm entitlement + token scopes
# 3. POST /v1/chat/sessions with stable externalId
# 4. Return chatUrl only — never the API tokenDashboard APIs (JWT — not public tokens)
Richer inbox ops use tenant JWT (browser), not umk_* keys: /api/tenants/{tenantId}/chat/* and /api/public/chat/* for the widget. Prefer public /v1/chat/* for Nest and third parties.
- Agent UI: /dashboard/chat, /dashboard/chat/reports
- Keys & webhooks UI: /dashboard/developers
- Hosted visitor UI: /widget/chat
- Omnichannel (WhatsApp/Meta/Telegram) feeds the same inbox and can emit outbound webhook events
OpenAPI & AI index
- OpenAPI 3: /developers/openapi-live-chat.json
- Markdown for RAG/agents: /developers/live-chat.md
- Global index: /llms.txt · /developers/catalog.json
- Token guide: /developers/api-tokens