Customer Chat API
The Customer Chat API lets your backend create conversations and exchange messages with the support agent on behalf of your users.
Authentication
All requests require a customer API key (lxc_ prefix) in the Authorization header:
Authorization: Bearer lxc_...
Base URL
https://lexey.ai/api/v1/customer
Quick start
1. Create a conversation:
| 1 | curl -X POST https://lexey.ai/api/v1/customer/conversations \ |
| 2 | -H "Authorization: Bearer $LEXEY_CUSTOMER_KEY" \ |
| 3 | -H "Content-Type: application/json" |
Response (201): { "conversationId": "550e8400-...", "mode": "live" }
2. Send a message (streamed response):
| 1 | curl -N -X POST https://lexey.ai/api/v1/customer/conversations/CONVERSATION_ID/messages \ |
| 2 | -H "Authorization: Bearer $LEXEY_CUSTOMER_KEY" \ |
| 3 | -H "Content-Type: application/json" \ |
| 4 | -d '{"message": "What are your business hours?"}' |
3. Retrieve message history:
| 1 | curl https://lexey.ai/api/v1/customer/conversations/CONVERSATION_ID/messages \ |
| 2 | -H "Authorization: Bearer $LEXEY_CUSTOMER_KEY" |
Response: { "messages": [{ "role": "user" | "assistant", "content": "...", "createdAt": "..." }] }
Shadow mode
To try Lexey on real customer messages without it acting on them, create the conversation in shadow mode:
| 1 | curl -X POST https://lexey.ai/api/v1/customer/conversations \ |
| 2 | -H "Authorization: Bearer $LEXEY_CUSTOMER_KEY" \ |
| 3 | -H "Content-Type: application/json" \ |
| 4 | -d '{"mode": "shadow"}' |
The agent answers as usual, but escalation emails and webhooks are only recorded, never sent. Your API connector still makes its read-only calls. Shadow conversations appear in Conversations marked Shadow. Use it to run Lexey alongside your current support and compare its answers before you go live. A body other than {"mode": "live"} or {"mode": "shadow"} is rejected with 400; an empty body is live.
Check a key
GET /api/v1/customer/identity returns the key's organization without starting a conversation or using credits: { "tenantId": "...", "type": "customer", "environment": "production", "expiresAt": null }.
SSE stream format
The send message endpoint returns text/event-stream. Each event includes a monotonically incrementing id: field and a data: line:
id: 1\ndata: {"type":"delta","text":"chunk"}— incremental text, append to the responseid: N\ndata: {"type":"response_options","options":[...],"displayMode":"buttons"}— choices the agent offers, after the text (only when the Interactive response options skill is on)id: N\ndata: {"type":"error","message":"..."}— an error after streaming beganid: N\ndata: [DONE]— stream complete
For code examples in TypeScript, Python, Go, Ruby, and C#, see the Streaming guide.
Error codes
| Status | Meaning |
|---|---|
| 400 | Invalid request (e.g. a message over 3,000 characters, or an unknown mode) |
| 401 | Missing or invalid API key |
| 402 | No active subscription or credits exhausted |
| 403 | Wrong key type (use lxc_ key) |
| 404 | Conversation not found |
| 429 | The conversation reached 100 messages (code: "CONVERSATION_LIMIT_REACHED"), or too many requests |
| 500 | Internal server error |