Chat

The Chat API processes messages through the LVNG engine. Two endpoints are available: a synchronous endpoint that returns a complete response, and a streaming endpoint that delivers incremental text and tool events via Server-Sent Events. Both take images and file attachments.

Send Message

Send a message and wait for the complete response. Rate limited to 100 requests per minute per IP, and 30 requests per minute per user. Supports JWT or API key authentication.

POST/api/v2/chatAuthenticated

Process a message through the LVNG engine and return a complete response. Takes file attachments, images, and a message type (chat, research, image, video).

Body Parameters

messagestringrequired

The user message to process.

platformstring
Default: "api"

Where the message comes from, for example api or web.

userIdstring

User ID for conversation context and per-user rate limiting.

channelIdstring (UUID)

Channel UUID for conversation scoping. Messages are stored and retrieved by channel.

contextobject

Additional context passed to the AI engine (tool results, metadata, prior state).

personalitystring
Default: "lvng"

The id of a twin in your workspace to answer as. Leave it out for LVNG's own answer. The expert twin catalogue is not available.

streamingboolean
Default: false

Reserved flag (use /api/v2/chat/stream for actual streaming).

modelstring

A Claude model id to use instead of the chat model (claude-sonnet-5-5). Leave it out to use the chat model.

messageTypestring
Default: "chat"

Routing hint: chat, research, image, or video. Research mode enables web search/scraping.

useFirecrawlboolean
Default: false

Enable web search and scraping for this request.

attachmentsarray

File attachments as [{ id, name, type, size, url }]. Content is extracted and injected into the message context.

imagesarray

Base64-encoded images for Claude vision: [{ filename, mediaType, base64 }].

debugboolean
Default: false

Enable debug mode to include tool call traces in the response.

Request

cURL
curl -X POST https://api.lvng.ai/api/v2/chat \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Summarize the latest sales report",
    "channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "platform": "api"
  }'

Response 200

{
  "messageId": "7e6d5c4b-3a29-1098-7654-321fedcba098",
  "reply": "Based on the latest sales report, Q1 revenue increased 23% year-over-year to $4.2M. Key highlights:\n\n- Enterprise segment grew 31% driven by 12 new accounts\n- Average deal size increased from $48K to $62K\n- Sales cycle shortened by 8 days on average",
  "personality": "lvng",
  "sessionId": "b8c9d0e1-f2a3-4b5c-6d7e-8f9012345678",
  "timestamp": "2026-03-19T14:32:18.000Z",
  "responseTime": 2340,
  "attachments": [],
  "confidence": null,
  "metadata": {
    "toolsUsed": [{ "name": "search_knowledge", "status": "success" }]
  }
}

Stream Response

Stream an AI response in real-time using Server-Sent Events. The connection stays open while the AI generates text and executes tools, then closes after the final done event. A keepalive comment is sent every 15 seconds to prevent proxy timeouts.

POST/api/v2/chat/streamAuthenticated

Stream an AI response via Server-Sent Events. Returns Content-Type: text/event-stream.

Body Parameters

messagestringrequired

The user message to process.

platformstring
Default: "api"

Source platform identifier.

userIdstring

User ID for conversation context.

channelIdstring (UUID)

Channel UUID. Conversation history is loaded from this channel (last 10 messages).

workspaceIdstring (UUID)

Workspace context for the conversation.

threadIdstring

Thread ID for threaded conversations.

personalitystring

The id of a twin in your workspace to answer as. Leave it out for LVNG's own answer.

modelstring

A Claude model id to use instead of the chat model (claude-sonnet-5-5).

contextobject

Additional context passed to the AI engine.

imagesarray

Base64-encoded images for multi-modal input.

Request

cURL
curl -N -X POST https://api.lvng.ai/api/v2/chat/stream \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "message": "Walk me through how OODA loops work in LVNG",
    "channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }'

Response 200

event: connected
data: {"streamId":"c4b3a291-0987-4543-81fe-dcba09876543","timestamp":"2026-10-13T14:35:00.000Z"}

event: tool_start
data: {"tool":"search_knowledge","toolId":"toolu_01A2b3C4","timestamp":"2026-10-13T14:35:01.000Z"}

event: tool_call
data: {"tool":"search_knowledge","input":{"query":"remote work policy core hours"}}

event: tool_result
data: {"tool":"search_knowledge","duration":420,"resultPreview":"remote-work-policy.pdf: Core hours are 10am-3pm..."}

event: tool_complete
data: {"tool":"search_knowledge","toolId":"toolu_01A2b3C4","success":true,"duration":420}

event: text_delta
data: {"content":"The policy sets core hours","accumulated_length":26}

event: text_delta
data: {"content":" from 10am to 3pm.","accumulated_length":44}

event: done
data: {"streamId":"c4b3a291-0987-4543-81fe-dcba09876543","reply":"The policy sets core hours from 10am to 3pm.","personality":"lvng","responseTime":3200,"toolsUsed":["search_knowledge"],"confidence":null,"metadata":{"toolsUsed":["search_knowledge"],"knowledgeGraphQueried":false}}

SSE Event Types

The streaming endpoint emits the following event types. Your client should handle each type to provide a responsive user experience.

EventDescriptionData Fields
connectedInitial heartbeat confirming the stream is open.streamId, timestamp
text_deltaIncremental text content. Append to your buffer.content, accumulated_length
tool_startA tool invocation has begun.tool, toolId, timestamp
tool_callTool input parameters (sent after tool_start).tool, input
tool_resultTool output preview (truncated to 200 chars).tool, duration, resultPreview
tool_completeTool execution finished with success/failure status.tool, toolId, success, duration
doneStream complete. Contains the full reply and metadata.streamId, reply, personality, responseTime, toolsUsed, confidence, metadata
errorAn error occurred during processing.message, streamId

Client Example

A minimal TypeScript example that consumes the SSE stream, appends text deltas, and handles tool and completion events.

stream-client.ts
const response = await fetch('https://api.lvng.ai/api/v2/chat/stream', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_JWT_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    message: 'Summarize this week in the #general channel',
    userId: 'f6a7b8c9-0d1e-2f3a-4b5c-6d7e8f901234',
    channelId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
  }),
})

const reader = response.body!.getReader()
const decoder = new TextDecoder()
let buffer = ''
let fullText = ''

while (true) {
  const { done, value } = await reader.read()
  if (done) break

  buffer += decoder.decode(value, { stream: true })
  const lines = buffer.split('\n')
  buffer = lines.pop() || ''

  let currentEvent = ''
  for (const line of lines) {
    if (line.startsWith('event: ')) {
      currentEvent = line.slice(7)
    } else if (line.startsWith('data: ')) {
      const data = JSON.parse(line.slice(6))

      switch (currentEvent) {
        case 'connected':
          console.log('Stream started:', data.streamId)
          break
        case 'text_delta':
          fullText += data.content
          process.stdout.write(data.content)
          break
        case 'tool_start':
          console.log('\nTool started:', data.tool)
          break
        case 'tool_complete':
          console.log('Tool done:', data.tool, data.duration + 'ms')
          break
        case 'done':
          console.log('\n---')
          console.log('Response time:', data.responseTime + 'ms')
          console.log('Tools used:', data.toolsUsed)
          break
        case 'error':
          console.error('Stream error:', data.message)
          break
      }
    }
  }
}