Parse Response

The chat endpoint returns a Server-Sent Events (SSE) stream. Here's how to parse it.

Response Format

Each line starts with data: followed by JSON:

data: {"type":"text-delta","textDelta":"Hello"}
data: {"type":"text-delta","textDelta":"! How"}
data: {"type":"text-delta","textDelta":" can I help?"}
data: {"type":"finish","finishReason":"stop"}

Event Types

TypeDescription
text-deltaA chunk of the AI's response text
tool-callAI is calling a tool (web search, etc.)
tool-resultResult from a tool call
finishStream completed
errorSomething went wrong

JavaScript

chat.js
const BOX_URL = 'https://your-box.intelligencebox.it'; // Your server URL

async function chat(message, assistantId = null, vectorIds = null) {
  const body = {
    id: 'chat-' + Date.now(),
    messages: [{ role: 'user', content: message }],
    boxAddress: BOX_URL
  };

  if (assistantId) body.assistantId = assistantId;
  if (vectorIds) body.vector = vectorIds;

  const response = await fetch(`${BOX_URL}/api/ai/chat`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': 'YOUR_API_KEY'
    },
    body: JSON.stringify(body)
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let fullResponse = '';

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

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

    for (const line of lines) {
      if (line.startsWith('data: ')) {
        try {
          const data = JSON.parse(line.slice(6));

          if (data.type === 'text-delta') {
            fullResponse += data.textDelta;
            // Print in real-time
            process.stdout.write(data.textDelta);
          } else if (data.type === 'error') {
            console.error('Error:', data.error);
          } else if (data.type === 'finish') {
            console.log('\n[Done]');
          }
        } catch (e) {
          // Skip invalid JSON
        }
      }
    }
  }

  return fullResponse;
}

// Usage
const answer = await chat('What is AI?');
const answer2 = await chat('Summarize my docs', null, ['folder-id']);
const answer3 = await chat('Help me', 'assistant-id');

Python

chat.py
import requests
import json
import time

BOX_URL = 'https://your-box.intelligencebox.it'  # Your server URL

def chat(message, assistant_id=None, vector_ids=None):
    payload = {
        'id': f'chat-{int(time.time())}',
        'messages': [{'role': 'user', 'content': message}],
        'boxAddress': BOX_URL
    }

    if assistant_id:
        payload['assistantId'] = assistant_id
    if vector_ids:
        payload['vector'] = vector_ids

    response = requests.post(
        f'{BOX_URL}/api/ai/chat',
        headers={
            'Content-Type': 'application/json',
            'x-api-key': 'YOUR_API_KEY'
        },
        json=payload,
        stream=True
    )

    full_response = ''

    for line in response.iter_lines():
        if line:
            line = line.decode('utf-8')
            if line.startswith('data: '):
                try:
                    data = json.loads(line[6:])

                    if data.get('type') == 'text-delta':
                        chunk = data.get('textDelta', '')
                        full_response += chunk
                        print(chunk, end='', flush=True)
                    elif data.get('type') == 'error':
                        print(f"\nError: {data.get('error')}")
                    elif data.get('type') == 'finish':
                        print('\n[Done]')

                except json.JSONDecodeError:
                    pass

    return full_response

# Usage
answer = chat('What is AI?')
answer = chat('Summarize my docs', vector_ids=['folder-id'])
answer = chat('Help me', assistant_id='assistant-id')

cURL

For cURL, use -N flag to disable buffering:

curl -N -X POST BOX_URL/api/ai/chat \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"id":"chat-1","messages":[{"role":"user","content":"Hello"}],"boxAddress":"BOX_URL"}'

You'll see the stream in real-time:

data: {"type":"text-delta","textDelta":"Hello"}
data: {"type":"text-delta","textDelta":"! How"}
data: {"type":"text-delta","textDelta":" can I help you today?"}
data: {"type":"finish","finishReason":"stop"}

TypeScript Types

type SSEEvent =
  | { type: 'text-delta'; textDelta: string }
  | { type: 'tool-call'; name: string; args: Record<string, any> }
  | { type: 'tool-result'; name: string; result: any }
  | { type: 'finish'; finishReason: 'stop' | 'length' | 'error' }
  | { type: 'error'; error: string };