Documentation
Ask API

Ask API

The Ask API allows you to send questions to your chatbot and receive streaming responses. This endpoint supports real-time interaction with your database through natural language queries.

Endpoint

POST /api/ask

Authentication

Requires API Key authentication. See API Authentication for details.

Request Format

Headers

Content-Type: application/json
Authorization: Bearer YOUR_API_KEY

Request Body

ParameterTypeRequiredDescription
questionstringThe natural language question to ask
botidstringYour chatbot ID
chatidstringThe chat session ID
debugbooleanEnable debug mode (default: false)
propertiesobjectCustom properties for the chat session
configobjectConfiguration overrides
databaseConfigobjectDynamic database configuration
fileUrlsstring[]URLs of files to analyze

Example Request

curl -X POST https://your-domain.com/api/ask \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_api_key_here" \
  -d '{
    "question": "Show me total sales by month for the last year",
    "botid": "bot_123456",
    "chatid": "chat_789012",
    "debug": true,
    "properties": {
      "user_id": "user_123",
      "department": "sales"
    }
  }'

Response Format

The API returns a Server-Sent Events (SSE) stream with Content-Type: text/event-stream. Each event is formatted as:

data: {"event_type": "value", ...additional_fields}

Event Types

1. Text Content Events

Event Type: isText: true

Streams the AI's text response in real-time.

{
  "isText": true,
  "content": "Based on your sales data, here are the monthly totals..."
}

2. SQL Execution Events

Event Type: isSQL: true

Shows the generated SQL query and its results (when debug mode is enabled).

{
  "id": "executeSQL_1234567890",
  "isSQL": true,
  "sql": "SELECT DATE_TRUNC('month', order_date) as month, SUM(total_amount) as total_sales FROM orders WHERE order_date >= CURRENT_DATE - INTERVAL '1 year' GROUP BY month ORDER BY month",
  "result": {
    "result": [
      {"month": "2024-01-01", "total_sales": 125000},
      {"month": "2024-02-01", "total_sales": 138000}
    ],
    "viewLink": "https://your-domain.com/api/data-response?hashid=abc123"
  }
}

3. Function Execution Status Events

Event Type: isExecutionStatus: true

Indicates when functions (SQL execution, Python code, etc.) start and complete.

Function Started

{
  "isExecutionStatus": true,
  "status": "started",
  "functionName": "executeSQL",
  "id": "executeSQL_1234567890"
}

Function Completed

{
  "isExecutionStatus": true,
  "status": "completed", 
  "functionName": "executeSQL",
  "id": "executeSQL_1234567890"
}

4. Image Generation Events

Event Type: isImage: true

When Python code generates charts or visualizations.

{
  "isImage": true,
  "url": "https://your-domain.com/api/generated-image/chart_abc123.png"
}

5. Thinking Events (Claude Models)

Event Type: isThinking: true

Shows the AI's reasoning process (when thinking mode is enabled).

{
  "isThinking": true,
  "content": "I need to analyze the sales data by grouping it by month..."
}

6. Reasoning Events (DeepSeek-R1)

Event Type: Function execution with functionName: "Reasoning"

Shows the model's internal reasoning process.

{
  "isExecutionStatus": true,
  "status": "started",
  "functionName": "Reasoning"
}

Error Handling

Authentication Errors

HTTP/1.1 401 Unauthorized
Content-Type: application/json
 
{
  "error": "Authentication failed"
}

Validation Errors

HTTP/1.1 400 Bad Request
Content-Type: application/json
 
{
  "error": "chatid is required in API mode"
}

Stream Errors

Error messages are sent as text events within the stream:

{
  "isText": true,
  "content": "An error occurred: Database connection failed. Please try again later."
}

JavaScript Example

const response = await fetch('/api/ask', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_api_key_here'
  },
  body: JSON.stringify({
    question: 'Show me top 10 customers by revenue',
    botid: 'bot_123456',
    chatid: 'chat_789012',
    debug: 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: ')) {
      try {
        const data = JSON.parse(line.slice(6));
        
        if (data.isText) {
          console.log('AI Response:', data.content);
        } else if (data.isSQL) {
          console.log('SQL Query:', data.sql);
          console.log('Results:', data.result);
        } else if (data.isExecutionStatus) {
          console.log(`Function ${data.functionName} ${data.status}`);
        }
      } catch (e) {
        console.error('Failed to parse SSE data:', e);
      }
    }
  }
}

Python Example

import requests
import json
 
url = "https://your-domain.com/api/ask"
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer your_api_key_here"
}
data = {
    "question": "What are our top selling products?",
    "botid": "bot_123456", 
    "chatid": "chat_789012",
    "debug": True
}
 
response = requests.post(url, headers=headers, json=data, stream=True)
 
for line in response.iter_lines():
    if line:
        line = line.decode('utf-8')
        if line.startswith('data: '):
            try:
                event_data = json.loads(line[6:])
                
                if event_data.get('isText'):
                    print(f"AI: {event_data['content']}")
                elif event_data.get('isSQL'):
                    print(f"SQL: {event_data['sql']}")
                    print(f"Results: {event_data['result']}")
                elif event_data.get('isExecutionStatus'):
                    status = event_data['status']
                    func_name = event_data['functionName']
                    print(f"Function {func_name} {status}")
                    
            except json.JSONDecodeError:
                print(f"Failed to parse: {line}")

Rate Limits

  • API requests are subject to your subscription plan's quotas
  • Streaming responses may take 30-300 seconds depending on query complexity
  • Maximum concurrent streams: 5 per API key

Best Practices

  1. Handle Stream Interruption: Always implement proper error handling for stream disconnections
  2. Parse Events Incrementally: Don't wait for the entire stream to complete before processing events
  3. Store Chat IDs: Reuse chat IDs to maintain conversation context
  4. Monitor Function Status: Use execution status events to show loading states in your UI
  5. Handle Large Results: Use the viewLink for large dataset results instead of processing them directly