Skip to main content

API Endpoints

Canvases

List Canvases

GET /api/v1/canvases

Response (2xx)

{
"success": true,
"data": {
"canvases": [
{
"id": "...",
"name": "Energy Audit",
"displayOrder": 0,
"isDefault": true,
"widgetCount": 5,
"widgetLimit": 10
}
]
}
}

Create Canvas

POST /api/v1/canvases

Body

{
"name": "My Analysis"
}

Rename Canvas

PATCH /api/v1/canvases/:canvasId

Body

{
"name": "New Name"
}

Delete Canvas

DELETE /api/v1/canvases/:canvasId
  • Cannot delete the default Energy Audit canvas
  • Deletes all widgets and conversations under this canvas

Widgets

List Widgets in Canvas

GET /api/v1/canvases/:canvasId/widgets

Response (2xx)

{
"success": true,
"data": {
"widgets": [
{
"id": "...",
"title": "TC Trends — Line Chart",
"type": "chart",
"chartType": "line",
"position": 0,
"conversationId": "..."
}
]
}
}

Get Widget Data (Execute SQL)

GET /api/v1/widgets/:widgetId/data

Query

?limit=50&offset=0  (for tables only)

Response (2xx)

{
"success": true,
"data": {
"rows": [...],
"totalCount": 264
}
}

Update Widget Name

PATCH /api/v1/widgets/:widgetId

Body

{
"title": "Updated Widget Name"
}

Delete Widget

DELETE /api/v1/widgets/:widgetId
  • Repositions remaining widgets in the canvas
  • Deletes associated conversation

Conversations / Chat

Start New Conversation

POST /api/v1/conversations

Body

{
"canvasId": "...",
"message": "Show me TC trends over time"
}
  • Fails if user already has an active conversation
  • Fails if canvas not found or not owned by user
  • Fails if canvas has reached widget limit

Send Message (Continue Conversation)

POST /api/v1/conversations/:conversationId/messages

Body

{
"message": "Last 3 months"
}

Response — Clarification

{
"success": true,
"data": {
"type": "clarification",
"message": "What month range should this cover?",
"message": "What month range should this cover?"
}
}

Response — Widget Generated

{
"success": true,
"data": {
"type": "chart",
"widget": {
"id": "...",
"title": "TC Trends — Line Chart",
"type": "chart",
"chartType": "line",
"sql": "SELECT ...",
"chartConfig": { ... },
"position": 3
},
"rows": [...],
"conversationName": "TC trends over time"
}
}

Get Conversation (for widget editing)

GET /api/v1/conversations/:conversationId

Response (2xx)

{
"success": true,
"data": {
"conversation": {
"id": "...",
"name": "TC trends over time",
"status": "completed",
"widgetId": "...",
"messages": [
{ "role": "user", "content": "Show me TC trends", "timestamp": "..." },
{ "role": "assistant", "content": "What month range?", "timestamp": "..." },
{ "role": "user", "content": "Last 3 months", "timestamp": "..." },
{ "role": "assistant", "content": "Widget generated", "sql": "...", "chartConfig": { ... }, "timestamp": "..." }
]
}
}
}

Reopen Conversation (Edit Widget)

POST /api/v1/conversations/:conversationId/messages
  • Same endpoint as "Send Message"
  • If conversation is completed, it gets reopened to "active" status
  • User sends edit instruction → AI modifies SQL → widget updates

Health / Info

Inherited from slim-bp-v2 boilerplate:

GET /api/v1/general/info
GET /api/v1/general/health/service
GET /api/v1/general/health/mongo