Skip to main content
POST
/
v1
/
lexi
/
chat
/
stream
Stream Chat with Lexi
curl --request POST \
  --url https://api.example.com/v1/lexi/chat/stream \
  --header 'Content-Type: application/json' \
  --data '
{
  "message": "<string>",
  "conversation_id": "<string>",
  "context": {},
  "allow_tools": true
}
'
This endpoint consumes AI credits (typically 1 - 5 credits per request depending on tool usage). If the workspace balance is insufficient, the API returns 402 insufficient_credits immediately, before any events are streamed.

Request

This is the streaming counterpart to POST /v1/lexi/chat. The response is a text/event-stream that emits incremental events as Lexi reasons through the prompt and uses tools. Because the request is a POST, you must use a fetch-based SSE client - the browser’s EventSource only supports GET.

Headers

Authorization: Bearer wbk_your_api_key_here
Content-Type: application/json
Accept: text/event-stream
Idempotency-Key
string
Optional UUID to deduplicate retries within 24 hours. Credits are charged only on the first successful stream.

Body Parameters

message
string
required
User message to send to Lexi. Maximum 12,000 characters.
conversation_id
string
Optional conversation UUID. When omitted, a new conversation is created and its ID is emitted in the first text event’s conversation_id metadata.
context
object
Optional page / entity context: contact_id, deal_id, matter_id, company_id, page.
allow_tools
boolean
default:"true"
When false, Lexi will not invoke any CRM tools and will respond purely from the conversation context.

Event Types

EventPurpose
thinkingIntermediate reasoning step. Payload: data: {"text": "..."}. Safe to ignore if not rendering a progress UI.
tool_stepLexi is about to invoke or has completed a CRM tool. Payload: data: {"tool": "...", "status": "started" or "completed", "summary": "..."}.
textIncremental assistant text. Payload: data: {"delta": "...", "conversation_id": "..."}. Concatenate delta values to build the final response.
doneFinal event with usage metadata. Payload: data: {"credits_remaining": 4840, "message_id": "msg_01HY1"}.
The stream terminates with the literal line data: [DONE] followed by a newline, consistent with the OpenAI SSE convention.

Response Format

event: thinking
data: {"text": "Looking up the contact in your pipeline..."}

event: tool_step
data: {"tool": "contacts.get", "status": "started"}

event: tool_step
data: {"tool": "contacts.get", "status": "completed", "summary": "Found 1 contact"}

event: text
data: {"delta": "Jane Doe is currently", "conversation_id": "conv_01HY1"}

event: text
data: {"delta": " in the Proposal stage...", "conversation_id": "conv_01HY1"}

event: done
data: {"credits_remaining": 4840, "message_id": "msg_01HY1"}

data: [DONE]
Responses include X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, and X-Request-ID headers on the initial HTTP response.
curl -N -X POST \
  https://data.leadlex.com/functions/v1/api-gateway/v1/lexi/chat/stream \
  -H "Authorization: Bearer wbk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "message": "Summarize my pipeline",
    "conversation_id": null
  }'

Errors

StatusCodeDescription
400validation_errorMissing message, or prompt exceeds size limit
401invalid_keyInvalid or expired API key
402insufficient_creditsWorkspace credit balance is exhausted
403insufficient_permissionsMissing write:ai permission
404conversation_not_foundSupplied conversation_id does not exist
429rate_limitedRate limit exceeded
Errors surface as a single event: error in the SSE stream when they occur after the HTTP headers have been sent, with the same code / message payload as JSON responses. Clients should therefore handle both HTTP-level and in-stream error events.