API: Chat
Base URL: /projects/{projectId}/chat
The chat API provides AI-assisted co-design coaching with streaming support and form trigger generation.
Endpoints
Create Thread
POST /projects/{projectId}/chat
Request Body:
{
"project_context": {
"projectId": "uuid",
"projectName": "Climate Resilience Service"
},
"phase": 1
}
Response (201):
{
"thread_id": "uuid",
"projectId": "project-uuid",
"phase": 1,
"intro_message": "Welcome to Phase 1! Let's start by identifying...",
"createdAt": "2026-01-15T10:30:00Z"
}
List Threads
GET /projects/{projectId}/chat
Returns all threads for the authenticated user in this project.
Response (200):
[
{
"thread_id": "uuid",
"phase": 1,
"lastMessage": "Help me identify stakeholders",
"messageCount": 12,
"createdAt": "2026-01-15T10:30:00Z"
}
]
Get Thread
GET /projects/{projectId}/chat/{thread_id}
Send Message
POST /projects/{projectId}/chat/{thread_id}/messages
Request Body:
{
"content": "Help me create a stakeholder card for the local municipality",
"stream": false
}
Response (200) — Non-streaming:
{
"message_id": "uuid",
"role": "assistant",
"content": "I'll help you create a stakeholder card for the local municipality...",
"status": "completed",
"follow_up_options": [
"Add assessment scores",
"Create another stakeholder",
"Generate ecosystem matrix"
],
"form_trigger": {
"templateCode": "1.0.1",
"action": "create",
"fields": {
"formalInfo_name": "Local Municipality",
"formalInfo_type": "Public administration",
"formalInfo_location": "City, Country"
}
},
"token_usage": {
"prompt_tokens": 1200,
"completion_tokens": 350
}
}
Streaming Response:
When stream=true, the response uses Server-Sent Events (SSE):
data: {"type": "token", "content": "I'll"}
data: {"type": "token", "content": " help"}
data: {"type": "token", "content": " you"}
...
data: {"type": "follow_up", "options": ["Add assessment", "Create another"]}
data: {"type": "form_trigger", "data": {...}}
data: {"type": "done"}
Get Thread Messages
GET /projects/{projectId}/chat/{thread_id}/messages
Response (200):
[
{
"message_id": "uuid",
"role": "user",
"content": "Help me identify stakeholders",
"timestamp": "2026-01-15T10:30:00Z"
},
{
"message_id": "uuid",
"role": "assistant",
"content": "Based on your project...",
"follow_up_options": [...],
"timestamp": "2026-01-15T10:30:05Z"
}
]
Delete Thread
DELETE /projects/{projectId}/chat/{thread_id}
Response (204): No content.
Frontend Integration
Streaming example (JavaScript):
async function sendMessage(projectId, threadId, content) {
const response = await fetch(
`/projects/${projectId}/chat/${threadId}/messages`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({ content, stream: 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').filter(l => l.startsWith('data: '));
for (const line of lines) {
const data = JSON.parse(line.slice(6));
switch (data.type) {
case 'token':
appendToMessage(data.content);
break;
case 'follow_up':
showFollowUpButtons(data.options);
break;
case 'form_trigger':
openTemplateForm(data.data);
break;
}
}
}
}