stream/interactive_ask

Create or continue an interactive-mode conversation thread and stream responses via Server-Sent Events (SSE).
This endpoint provides a RESTful API for interactive mode conversations, allowing clients to send questions
and receive streaming responses in real-time. Supports both initial questions (creates new thread) and
follow-up questions (uses existing thread).

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

Streams interactive mode conversations with real-time AI responses and conversation management

This endpoint enables natural, conversational interactions with your data. Unlike the standard /stream/ask endpoint which focuses on SQL generation and execution, interactive mode allows the AI to engage in a more flexible conversation flow — it may ask clarifying questions, provide explanations, generate insights, or create visualizations based on the context.

This endpoint combines conversation creation and streaming into a single POST request, making it ideal for building conversational interfaces, chatbots, or interactive data exploration tools.

What It Does

The endpoint returns a Server-Sent Events (SSE) stream that includes:

  1. Conversation events — Real-time AI responses, explanations, and content blocks as they are generated.
  2. Conversation history management — Automatic thread management for multi-turn conversations.
  3. Content blocks — Various types of content including text explanations, SQL queries, charts, and recommended actions.

Basic Usage

Initial Question

Request

{
  "projectId": 123,
  "question": "What are the top 5 states with the most customers?"
}

Response

The stream begins immediately after validation and authentication. Events are forwarded directly from the AI Service:

// Stream begins - events forwarded from AI Service
event: message_start
data: {"type":"message_start","message":{"query_id":"6771808b-790a-48f3-b60c-5c7e62a694f4","trace_id":"a87102f7-6e27-4aed-a32d-52b444ceadac"}}

event: content_block_start
data: {"type":"content_block_start","index":0,"message":{"type":"text","content_block_label":"GREETINGS","trace_id":"a87102f7-6e27-4aed-a32d-52b444ceadac","metadata":{"visible_in_ui":true,"ui_components":["MARKDOWN","ASSISTANT"],"show_elapsed_time":false,"elapsed_time":0.0}}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"message":{"type":"text_delta","content_block_label":"GREETINGS","content":"You're all set. Let me process that for you.","trace_id":"a87102f7-6e27-4aed-a32d-52b444ceadac","metadata":{"visible_in_ui":true,"ui_components":["MARKDOWN","ASSISTANT"],"show_elapsed_time":false,"elapsed_time":0.01}}}

event: content_block_stop
data: {"type":"content_block_stop","index":0,"message":{"type":"text","trace_id":"a87102f7-6e27-4aed-a32d-52b444ceadac","content_block_label":"GREETINGS","metadata":{"show_elapsed_time":false,"elapsed_time":0.01}}}


...

// Stream ends
data: {"done": true}

Follow-up Question

Request

{
  "projectId": 123,
  "threadId": "0625991d-1bba-407d-8ad4-dd0210172484",
  "question": "What about last month?"
}

When threadId is provided, the API automatically retrieves conversation history and includes it in the request to the AI Service, enabling context-aware responses.

Response

Same SSE stream format as initial question, with AI responses considering previous conversation context.

Request Parameters

ParameterTypeRequiredDescription
projectIdnumberYesThe ID of the project to query
questionstringYesThe user's question or message
threadIdstringNoThread ID for follow-up questions. If not provided, a new thread is created automatically
languagestringNoLanguage code for responses (e.g., "en", "zh"). Defaults to project language
allowUserGuidebooleanNoSet false to stop answering product questions from the built-in user guide.
userGuidePromptstringNoReplace the built-in user guide with your own. Ignored when allowUserGuide is false.

Response Format

The endpoint returns a Server-Sent Events (SSE) stream with Content-Type: text/event-stream.

Stream Events

Events are forwarded directly from the AI Service's conversation API. The following event types are supported:

  • message_start — Indicates the start of a new conversation response
  • content_block_start — Beginning of a content block
  • content_block_delta — Streaming content updates (text or JSON deltas)
  • content_block_stop — End of a content block
  • content_block_failed — Indicates a content block failed to generate
  • message_stop — End of the entire message stream
  • error — Error events

Completion Event

When the stream completes successfully, the API sends a final event:

{
  "done": true
}

This event is sent by the API wrapper, not the AI Service, to indicate that streaming has finished.

Event Types

message_start

Indicates the start of a new conversation response.

Example

{
  "type": "message_start",
  "message": {
    "query_id": "6771808b-790a-48f3-b60c-5c7e62a694f4",
    "trace_id": "a87102f7-6e27-4aed-a32d-52b444ceadac"
  }
}

Fields

FieldTypeDescription
query_idstringUnique identifier for this conversation query
trace_idstringTrace ID for backend debugging

content_block_start

Signals the beginning of a content block.

Example

{
  "type": "content_block_start",
  "index": 0,
  "message": {
    "type": "text",
    "content_block_label": "GREETINGS",
    "trace_id": "a87102f7-6e27-4aed-a32d-52b444ceadac",
    "metadata": {
      "visible_in_ui": true,
      "ui_components": ["MARKDOWN", "ASSISTANT"],
      "show_elapsed_time": false,
      "elapsed_time": 0.0
    }
  }
}

Fields

FieldTypeDescription
indexnumberIndex of the content block in the message
message.typestringContent type: "text", "tool_use", or "think"
message.content_block_labelstringLabel identifying the content block type (see Content Block Labels below)
message.trace_idstringTrace ID for debugging
message.metadataobjectMetadata including UI components, visibility, and timing

content_block_delta

Streams incremental content updates from the AI. Can contain either text deltas or JSON deltas.

Example (Text Delta)

{
  "type": "content_block_delta",
  "index": 0,
  "message": {
    "type": "text_delta",
    "content_block_label": "GREETINGS",
    "content": "You're all set. Let me process that for you.",
    "trace_id": "a87102f7-6e27-4aed-a32d-52b444ceadac",
    "metadata": {
      "visible_in_ui": true,
      "ui_components": ["MARKDOWN", "ASSISTANT"],
      "show_elapsed_time": false,
      "elapsed_time": 0.01
    }
  }
}

Example (JSON Delta)

{
  "type": "content_block_delta",
  "index": 1,
  "message": {
    "type": "json_delta",
    "content_block_label": "SQL_GENERATION",
    "content": {
      "success":true,
      "sql":"SELECT ..."
		},
    "trace_id": "a87102f7-6e27-4aed-a32d-52b444ceadac",
    "metadata": {
      "visible_in_ui": true,
      "ui_components": ["PREPARATION"],
      "show_elapsed_time": true,
      "elapsed_time": 2.5
    }
  }
}

content_block_stop

Indicates the end of a content block.

Example

{
  "type": "content_block_stop",
  "index": 0,
  "message": {
    "type": "text",
    "trace_id": "a87102f7-6e27-4aed-a32d-52b444ceadac",
    "content_block_label": "GREETINGS",
    "metadata": {
      "show_elapsed_time": false,
      "elapsed_time": 0.01
    }
  }
}

content_block_failed

Indicates that a content block failed to generate.

Example

{
  "type": "content_block_failed",
  "index": 1,
  "message": {
    "type": "json_failed",
    "content_block_label": "SQL_GENERATION",
    "content": "Error message",
    "trace_id": "a87102f7-6e27-4aed-a32d-52b444ceadac",
    "metadata": {
      "visible_in_ui": true,
      "ui_components": ["PREPARATION"],
      "show_elapsed_time": true,
      "elapsed_time": 5.0
    }
  }
}

message_stop

Marks the end of the entire message stream.

Example

{
  "type": "message_stop",
  "message": {
    "query_id": "6771808b-790a-48f3-b60c-5c7e62a694f4",
    "trace_id": "a87102f7-6e27-4aed-a32d-52b444ceadac"
  }
}

error

Error events indicate failures during processing.

Example

{
  "type": "error",
  "message": {
    "query_id": "6771808b-790a-48f3-b60c-5c7e62a694f4",
    "trace_id": "a87102f7-6e27-4aed-a32d-52b444ceadac",
    "code": "SQL_GENERATION_FAILED",
    "message": "Failed to generate SQL",
    "invalid_sql": "SELECT * FROM invalid_table",
    "metadata": {
      "ui_components": ["ERROR"],
      "visible_in_ui": true
    }
  }
}

User Guide Controls

Before answering, Wren classifies what a question is asking for. Most questions are about the data and become SQL. Some are not: "Do I need to know SQL?", "How do I get started?" Wren recognises those as product help and answers them from a built-in user guide describing Wren itself.

If you have embedded Wren in your own product that is usually the wrong answer — your users have never heard of Wren, and the guide describes our product rather than yours. Two per-request fields change it:

  • allowUserGuide (boolean, default true) — set false and product help is removed from classification altogether. The question is classified as something else and the built-in guide is never consulted.
  • userGuidePrompt (string) — supply your own guide and Wren uses it in place of ours, both when classifying the question and when answering it. Ignored when allowUserGuide is false.

Both default to today's behavior, so omitting them leaves the request unchanged. Both are per-request: re-send them on every turn of a thread. See User Guide Controls for the shared behaviour, including what happens to a question your guide does not cover.

Switch the built-in guide off:

{
  "projectId": 1,
  "question": "How do I get started?",
  "allowUserGuide": false
}

Or answer from your own guide instead — same question, your content:

{
  "projectId": 1,
  "question": "How do I get started?",
  "userGuidePrompt": "# Northwind Insights - Help\n\n## Getting started\nOpen **Explore** in the left sidebar and pick a dataset. Type your question in\nthe box at the top; results appear as a table you can switch to a chart.\n\n## Saving a report\nClick **Save** in the top-right of any answer to add it to *My Reports*.\nSaved reports refresh every morning at 06:00 UTC.\n\n## Sharing a report\nOpen a saved report and choose **Share > Copy link**. Links work only for\nteammates in your workspace; external sharing must be enabled by an admin."
}

The content_block_label names the pipeline that ran, so allowUserGuide: false is visible without reading the answer.

Frames below are real but abridged — the stream opens with message_start and content blocks 0-4 (GREETINGS plus the retrieval and intent-classification tool blocks), which is why the block shown is "index": 5. trace_id and metadata are dropped, and the token-by-token text_delta frames are collapsed. The complete streamed text follows each block.

data: {"type":"content_block_start","index":5,"message":{"type":"text","content_block_label":"MISLEADING_QUERY_ASSISTANCE"}}

data: {"type":"content_block_delta","index":5,"message":{"type":"text_delta","content_block_label":"MISLEADING_QUERY_ASSISTANCE","content":"To"}}

data: {"type":"content_block_delta","index":5,"message":{"type":"text_delta","content_block_label":"MISLEADING_QUERY_ASSISTANCE","content":" get"}}

// ... 126 more text_delta frames ...

data: {"type":"content_block_stop","index":5,"message":{"type":"text","content_block_label":"MISLEADING_QUERY_ASSISTANCE"}}

data: {"type":"message_stop","message":{"query_id":"bfee2baf-aaa2-4e85-b6d4-c0a6bfc3b175"}}

To get started with your data analysis, follow these steps:

  1. Understand your data schema: Review tables like orders, customers, products, and reviews.
  2. Define your goal: What insights do you want? (e.g., customer satisfaction, sales trends)
  3. Explore key tables: For example, check order details, payment methods, and product categories.
  4. Formulate clear questions: Instead of "How do I get started?", try:
    • What are the top-selling product categories?
    • How does customer satisfaction vary by region?
    • Which payment methods are most popular?

This approach helps you analyze data effectively.

data: {"type":"content_block_start","index":5,"message":{"type":"text","content_block_label":"USER_GUIDE_ASSISTANCE"}}

data: {"type":"content_block_delta","index":5,"message":{"type":"text_delta","content_block_label":"USER_GUIDE_ASSISTANCE","content":"To"}}

data: {"type":"content_block_delta","index":5,"message":{"type":"text_delta","content_block_label":"USER_GUIDE_ASSISTANCE","content":" get"}}

// ... 90 more text_delta frames ...

data: {"type":"content_block_stop","index":5,"message":{"type":"text","content_block_label":"USER_GUIDE_ASSISTANCE"}}

data: {"type":"message_stop","message":{"query_id":"17367470-a008-4f49-a042-8df2c6ebe76b"}}

To get started with Northwind Insights, follow these steps:

  1. Open Explore in the left sidebar.
  2. Pick a dataset that you want to analyze.
  3. Type your question in the box at the top.
  4. View the results, which will appear as a table by default.
  5. You can switch the table view to a chart if you prefer a visual representation.

This will help you begin exploring your data and getting insights quickly.

The label separates allowUserGuide: false from everything else; it does not distinguish a supplied userGuidePrompt from the built-in guide, since both run the user-guide pipeline and both are labelled USER_GUIDE_ASSISTANCE. It also tells you which pipeline ran, not whether an answer was found — a question your guide does not cover is still labelled USER_GUIDE_ASSISTANCE.

Content Block Labels

The content_block_label field identifies the type of content being streamed. The following labels are supported:

Text-Based Content Blocks

These blocks stream text content incrementally:

  • GREETINGS — Initial greeting messages
  • MISLEADING_QUERY_ASSISTANCE — Assistance for misleading queries
  • GENERAL_ASSISTANCE — General help and guidance
  • USER_GUIDE_ASSISTANCE — User guide and documentation assistance
  • DATA_EXPLORATION_ASSISTANCE — Data exploration guidance
  • USER_CLARIFICATION_ASSISTANCE — Requests for user clarification
  • SQL_GENERATION_REASONING — Reasoning behind SQL generation
  • SQL_ANSWER — Final answer with SQL results
  • CHART_SUMMARY — Summary of chart generation
  • FAILED_CONTENT_BLOCK_RENDERING — Error messages when content blocks fail

USER_GUIDE_ASSISTANCE and MISLEADING_QUERY_ASSISTANCE are also how you verify the allowUserGuide / userGuidePrompt request fields took effect — see User Guide Controls.

Structured Content Blocks

These blocks contain structured JSON data:

HISTORICAL_QUESTION_RETRIEVAL

Contains SQL from historical questions.

{
  "sql": "SELECT ...",
  "type": "view",
  "viewId": "optional-view-id"
}

SQL_PAIRS_RETRIEVAL

Contains retrieved SQL pairs from knowledge base.

{
  "sql_pairs": [
    {
      "question": "What are the top products?",
      "sql": "SELECT ..."
    }
  ]
}

INSTRUCTIONS_RETRIEVAL

Contains retrieved instructions from knowledge base.

{
  "instructions": [
    {
      "instruction": "Always use UTC timezone",
      "question": "What time is it?",
      "instruction_id": "inst-123"
    }
  ]
}

INTENT_CLASSIFICATION

Classifies user intent and provides reasoning.

{
  "intent": "TEXT_TO_SQL",
  "rephrased_question": "Show me sales data",
  "reasoning": "User wants to query sales data using SQL"
}

Intent Types:

  • MISLEADING_QUERY
  • TEXT_TO_SQL
  • GENERAL
  • USER_GUIDE
  • DATA_EXPLORATION
  • CHART
  • USER_CLARIFICATION

DB_SCHEMA_RETRIEVAL

Contains retrieved database schema information.

Success:

{
  "success": true,
  "retrieved_tables": ["customers", "orders", "products"]
}

Failure:

{
  "success": false,
  "error": {
    "code": "NO_RELEVANT_DATA",
    "message": "No relevant tables found"
  }
}

SQL_GENERATION

Contains generated SQL query.

Success:

{
  "success": true,
  "sql": "SELECT customer_id, SUM(amount) FROM orders GROUP BY customer_id"
}

Failure:

{
  "success": false,
  "error": {
    "code": "GENERATION_FAILED",
    "message": "Unable to generate SQL"
  }
}

SQL_DIAGNOSIS

Contains diagnosis reasoning for SQL issues.

{
  "reasoning": "The SQL query failed because table 'invalid_table' does not exist"
}

SQL_CORRECTION

Contains corrected SQL after diagnosis.

Success:

{
  "success": true,
  "sql": "SELECT * FROM valid_table"
}

Failure:

{
  "success": false,
  "error": {
    "code": "CORRECTION_FAILED",
    "message": "Unable to correct SQL"
  }
}

SQL_EXECUTOR

Indicates SQL execution status.

Success:

{
  "success": true
}

Failure:

{
  "success": false,
  "error": {
    "code": "QUERY_FAILED",
    "message": "SQL execution failed"
  }
}

FIX_SQL

Contains SQL fix information.

{
  "data": {
    "code": "NO_RELEVANT_SQL",
    "message": "No relevant SQL found",
    "invalid_sql": "SELECT * FROM invalid_table"
  }
}

CHART_INTENT_CLASSIFICATION

Classifies chart intent.

Success:

{
  "success": true,
  "reasoning": ""
}

Failure:

{
  "success": false,
  "reasoning": "Unable to determine chart intent"
}

CHART_TYPE_RECOMMENDATION

Recommends chart type.

Success:

{
  "success": true,
  "reasoning": ""
}

Failure:

{
  "success": false,
  "reasoning": "Unable to recommend chart type"
}

CHART_VALIDATION

Validates chart generation.

Success:

{
  "success": true,
  "reasoning": ""
}

Failure:

{
  "success": false,
  "reasoning": "Chart validation failed"
}

CHART_GENERATION

Contains generated chart schema.

{
  "chart_schema": {
    "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
    "data": {...},
    "mark": "bar",
    "encoding": {...}
  }
}

CHART_ADJUSTMENT

Contains adjusted chart schema.

{
  "chart_schema": {
    "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
    "data": {...},
    "mark": "line",
    "encoding": {...}
  }
}

DATA_PREVIEW

Contains data preview information.

Chart Preview:

{
  "type": "CHART",
  "payload": {
    "title": "Sales Chart",
    "sql": "SELECT ...",
    "chart_schema": {...}
  }
}

Table Preview:

{
  "type": "TABLE",
  "payload": {
    "title": "Sales Data",
    "sql": "SELECT ..."
  }
}

SQL Preview:

{
  "type": "SQL",
  "payload": {
    "title": "Generated SQL",
    "sql": "SELECT ..."
  }
}

INSTRUCTION_RECOMMENDATION

Contains recommended instructions.

{
  "instruction_recommendation_info": [
    {
      "uuid": "rec-123",
      "instruction_type": "SQL_PAIR",
      "instruction": "Use customer_id for joins",
      "human_readable_explanation": "This will improve query performance"
    }
  ]
}

RECOMMENDED_ACTIONS

Contains recommended follow-up actions.

{
  "actions": [
    {
      "label": "Show me last month",
      "template": "What about last month?"
    }
  ]
}

AI_EVENT_COST

⚠️ Note: This event is for internal usage within the WrenAI system only and is used for monitoring and analysis purposes. It does not directly correspond to the actual usage or charges billed to you, and should not be treated as a representation of your final cost.

Non-Chargeable Events

The following events do not result in credit charges:

  • NO_DB_SCHEMAS
  • SQL_TIMEOUT
  • SQL_PERMISSION_DENIED
  • SQL_CORRCTION_FAILED
  • SQL_QUERY_ALL_FAILED
  • CHART_INTENT_FAILED
  • CHART_TYPE_FAILED
  • CHART_FAILED
  • OTHERS

CONVERSATION_HISTORY_PAYLOAD

Contains the conversation history payload for persistence. This is used internally to maintain conversation context and is included in API history.

Structure

The structure varies depending on the conversation type and content generated. The request object always contains the user's query, while response contains different fields based on what was generated.

Example 1: SQL Query Response

{
  "type": "content_block_delta",
  "message": {
    "type": "json_delta",
    "content_block_label": "CONVERSATION_HISTORY_PAYLOAD",
    "content": {
      "request": {
        "query": "What are the top 5 products?"
      },
      "response": {
        "sql": "SELECT product_id, SUM(quantity) FROM orders GROUP BY product_id LIMIT 5",
        "sql_reasoning": "Aggregating order quantities by product",
        "text": "Here are the top 5 products by quantity sold..."
      }
    }
  }
}

Example 2: Chart Response

{
  "type": "content_block_delta",
  "message": {
    "type": "json_delta",
    "content_block_label": "CONVERSATION_HISTORY_PAYLOAD",
    "content": {
      "request": {
        "query": "how many data do i have in events, please draw me a chart"
      },
      "response": {
        "intent": "CHART",
        "sql": "SELECT COUNT(*) AS \"row_count\" FROM \"events\"",
        "sql_reasoning": null,
        "text": null,
        "chart_schema": {
          "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
          "title": "Row count in events table",
          "mark": {"type": "text", "tooltip": true},
          "encoding": {...},
          "data": {"values": []},
          "width": 320,
          "height": 320
        },
        "metadata": {
          "failed_sql": null
        }
      }
    }
  }
}

Fields

FieldTypeDescription
request.querystringThe user's question
response.intentstring (optional)Intent classification (e.g., "CHART", "TEXT_TO_SQL")
response.sqlstring (optional)Generated SQL query, if applicable
response.sql_reasoningstring (optional)Reasoning behind SQL generation
response.textstring (optional)Text explanation or answer
response.chart_schemaobject (optional)Chart schema (Vega-Lite specification) if a chart was generated
response.metadataobject (optional)Additional metadata (e.g., failed_sql)

Note: All fields in response are optional. The structure varies based on the conversation type and what content was generated. Only relevant fields are included.

Body Params
integer
required
string
required
string

Provide to continue a conversation / follow up.

string
boolean
Defaults to true

Set false to stop answering product questions from the user guide.

string

Replaces the built-in user guide. Ignored when allowUserGuide is false.

Headers
string

Comma-separated key=value pairs applied as row/column-level security session properties (e.g. region=US,tier=pro). Unknown keys are echoed back in the invalidSessionProperties response field.

string
enum
Defaults to application/json

Generated from available response content types

Allowed:
Responses

Language
Credentials
Bearer
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
text/event-stream
application/json