AI Chat API

AI-powered support chat with streaming responses, grounded in your knowledge base.

Send Message

POST/api/support/{appSlug}/chatJWT Required

Send a message to the AI support assistant.

Request Body

messagestringrequiredUser message
sessionIdstringChat session ID for context
streambooleanEnable streaming response (default: false)

Response

200AI response with sources
{
  "sessionId": "uuid",
  "message": {
    "role": "assistant",
    "content": "To export your data, navigate to Settings > Export...",
  },
  "sources": [
    {
      "title": "How to Export Data",
      "slug": "how-to-export-data"
    }
  ]
}
Example Requestbash
curl -X POST "https://support.example.com/api/support/myapp/chat" \
  -H "Authorization: Bearer <jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "How do I export my data?",
    "sessionId": "optional-session-id"
  }'

Streaming Responses

Enable streaming to receive the response in real-time using Server-Sent Events (SSE).

Streaming Exampletypescript
const response = await fetch('/api/support/myapp/chat', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <jwt-token>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    message: 'How do I export my data?',
    stream: true
  })
})

const reader = response.body.getReader()
const decoder = new TextDecoder()

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

  const chunk = decoder.decode(value)
  const lines = chunk.split('\n')

  for (const line of lines) {
    if (line.startsWith('data: ')) {
      const data = JSON.parse(line.slice(6))
      if (data.type === 'content') {
        // Append content to UI
        console.log(data.content)
      } else if (data.type === 'done') {
        // Response complete
        console.log('Sources:', data.sources)
      }
    }
  }
}

Session Management

Use session IDs to maintain conversation context across messages.

Session Contexttypescript
// First message - no session ID
const res1 = await fetch('/api/support/myapp/chat', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer <token>' },
  body: JSON.stringify({ message: 'How do I export data?' })
})
const { sessionId } = await res1.json()

// Follow-up message - include session ID
const res2 = await fetch('/api/support/myapp/chat', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer <token>' },
  body: JSON.stringify({
    message: 'Can I export to CSV?',
    sessionId // Maintains context from previous message
  })
})

Handoff to Human Support

The AI can suggest creating a support issue when it cannot answer a question.

Handoff Responsejson
{
  "sessionId": "uuid",
  "message": {
    "role": "assistant",
    "content": "I'm not sure about that. Would you like to create a support ticket?",
  },
  "suggestHandoff": true,
  "handoffReason": "Complex billing question requiring human review"
}

When suggestHandoff is true, your UI should offer the option to create a support issue.