Skip to main content

Visit Later

N/a

Related

  • Chart & Table Response Spec — comprehensive guide for frontend rendering (chartConfig shapes per chart type, rows format, detection logic)

General Notes

  • Used for two scenarios: continuing an active conversation (clarification follow-up) or reopening a completed conversation (widget editing)
  • If conversation status is "completed", it gets reopened to "active" status
  • AI may respond with another clarification or generate/update the widget
  • On widget update (edit flow), the existing widget document is updated with new SQL/config
  • When the first AI call on a new conversation produces SQL that returns 0 rows, the handler transparently retries the AI once with adaptive thinking enabled, prompting it to re-examine filters/joins. Skipped on edits (where an empty result may be intentional filter tightening). The retry is flagged via aiMetadata.emptyResultRetry on the persisted assistant message.
  • Each retry-path AI call (SQL error, empty result, chart row-limit, missing stackField, missing yAxisLabel) uses per-model retry params from modelCapabilities.js — adaptive thinking + xhigh effort on Opus 4.7, scaled down on other models. First-turn calls run without thinking for minimum latency.
  • The system prompt is sent with cache_control: ephemeral so the ~27K-token prefix is served from cache on retries, edits, and multi-turn conversations (cache read/write tokens accumulated on conversation.totalCacheReadInputTokens / totalCacheCreationInputTokens).

Flow

Mermaid editor

Test cases

Method & URL

POST v1/conversations/:conversationId/messages

Request

Headers

authorization
- Required
- Type : <string>
- Bearer session token

Query


Body

message
- Required
- Type : <string>
- The user's follow-up message or edit instruction

Path parameter

conversationId
- Required
- Type : <string>
- The ID of the conversation

Response

2xx

success
- Type : true (boolean)
- This indicates that request was executed successfully

message
- Type : <string> | null
- Generic message

data
- Type : <object>

data.type
- Type : "clarification" | "chart" | "table" (string)

data.conversationId
- Type : <string>
- ID of the conversation

data.message
- Type : <string> | null
- Present when data.type is "clarification"
- The AI's clarification question

data.widget
- Type : <object> | null
- Present when data.type is "chart" or "table"
- The created or updated widget document

data.widget.id
- Type : <string>

data.widget.title
- Type : <string>

data.widget.type
- Type : <string>
- Enum : chart | table

data.widget.chartType
- Type : <string> | null
- Enum : line | bar | pie | donut | stackedBar | scatterPlot
- null when type is "table"
- scatterPlot supports up to 50 data points (all other chart types are limited to 10)

data.widget.chartConfig
- Type : <object> | null
- Frontend rendering config (axes, colors, etc.)
- null when type is "table"
- stackedBar requires a stackField property in chartConfig (the field used to split bar segments)

data.widget.columns
- Type : <object>[] | null
- Array of column definitions for table rendering
- Populated when type is "table", null when type is "chart"

data.widget.columns[].field
- Type : <string>
- Key used to read the value from each row object — must exactly match the SQL column alias

data.widget.columns[].label
- Type : <string>
- String displayed as the column header in the UI

data.widget.position
- Type : <number>

data.widget.latestExplanation
- Type : <string> | null
- Plain-language explanation of the chart, up to 5000 chars
- Populated for type "chart" only, always null for type "table"

data.widget.latestExplanationGeneratedAt
- Type : <string (ISO timestamp)> | null
- When the explanation was generated
- Populated for type "chart" only, always null for type "table"

data.rows
- Type : <object>[] | null
- Present when data.type is "chart" or "table"
- Query result rows

data.totalCount
- Type : <number> | null
- Present when data.type is "table"
- Total matching rows (for pagination)

404

success
- Type : false (boolean)

message
- Type : <string>
- Conversation not found