sel-chat-coach / docs /openapi.yaml
tblaisaacliao's picture
fix: Add branch metadata to list conversations endpoint
6e8be48
openapi: 3.1.0
info:
title: SEL Chat Coach API
description: |
Social-Emotional Learning Chat Coach API for teachers to practice conversations
with simulated ADHD student agents and consult coaching agents.
All endpoints require Basic Auth unless otherwise specified.
version: 1.0.0
contact:
name: API Support
servers:
- url: http://localhost:3000
description: Local development server
- url: https://sel-chat-coach.example.com
description: Production server (update with actual URL)
security:
- basicAuth: []
tags:
- name: Health
description: Service health check
- name: Auth
description: User authentication and registration
- name: Conversations
description: Conversation management
- name: Messages
description: Conversation messages
- name: System Messages
description: System-level contextual messages
- name: Coach
description: Coach interactions
- name: Stats
description: Statistics and analytics
paths:
/api/health:
get:
tags: [Health]
summary: Health check
description: Check if the API is running
security: []
responses:
'200':
description: Service is healthy
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: healthy
timestamp:
type: string
format: date-time
/api/auth/register:
post:
tags: [Auth]
summary: Register a new user
description: Create a new user account with username. Use BASIC_AUTH_PASSWORD to authenticate subsequent requests.
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [username, email, name]
properties:
username:
type: string
example: teacher_wang
email:
type: string
format: email
example: wang@example.com
name:
type: string
example: 王老師
responses:
'200':
description: User created successfully
content:
application/json:
schema:
type: object
properties:
user:
type: object
properties:
id:
type: string
format: uuid
username:
type: string
message:
type: string
example: "User registered successfully. Use password 'cz-2025' to login."
'400':
$ref: '#/components/responses/BadRequest'
/api/conversations:
get:
tags: [Conversations]
summary: List all conversations
description: Get all conversations for the authenticated user
responses:
'200':
description: List of conversations
content:
application/json:
schema:
type: object
properties:
conversations:
type: array
items:
$ref: '#/components/schemas/Conversation'
'401':
$ref: '#/components/responses/Unauthorized'
/api/conversations/create:
post:
tags: [Conversations]
summary: Create a new conversation
description: Create a new conversation with a student personality and coach pairing
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [studentPromptId, coachPromptId]
properties:
studentPromptId:
type: string
enum: [grade_1, grade_2, grade_3, grade_4, grade_5, grade_6, grade_7, grade_8, grade_9, coach_direct]
description: Student grade level or 'coach_direct' for direct coach chat
example: grade_3
coachPromptId:
type: string
enum: [empathetic, structured, balanced]
example: empathetic
title:
type: string
example: 數學課專注力問題
include3ConversationSummary:
type: boolean
description: Include summary of last 3 conversations with this student
responses:
'200':
description: Conversation created
content:
application/json:
schema:
type: object
properties:
conversation:
$ref: '#/components/schemas/Conversation'
message:
type: string
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/api/conversations/{conversationId}:
get:
tags: [Conversations]
summary: Get conversation details
parameters:
- $ref: '#/components/parameters/ConversationId'
responses:
'200':
description: Conversation details
content:
application/json:
schema:
$ref: '#/components/schemas/Conversation'
'404':
$ref: '#/components/responses/NotFound'
put:
tags: [Conversations]
summary: Update conversation
description: Update conversation title
parameters:
- $ref: '#/components/parameters/ConversationId'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
example: 更新的對話標題
responses:
'200':
description: Conversation updated
content:
application/json:
schema:
$ref: '#/components/schemas/Conversation'
'404':
$ref: '#/components/responses/NotFound'
delete:
tags: [Conversations]
summary: Delete conversation
parameters:
- $ref: '#/components/parameters/ConversationId'
responses:
'200':
description: Conversation deleted
content:
application/json:
schema:
type: object
properties:
message:
type: string
deletedCount:
type: number
'404':
$ref: '#/components/responses/NotFound'
/api/conversations/{conversationId}/messages:
get:
tags: [Messages]
summary: Get conversation messages
description: Retrieve all messages for a conversation
parameters:
- $ref: '#/components/parameters/ConversationId'
responses:
'200':
description: List of messages
content:
application/json:
schema:
type: object
properties:
messages:
type: array
items:
$ref: '#/components/schemas/Message'
total:
type: number
'404':
$ref: '#/components/responses/NotFound'
/api/conversations/{conversationId}/message:
post:
tags: [Messages]
summary: Send a message
description: |
Send a message in the conversation. Returns a streaming response.
Uses Vercel AI SDK message format.
parameters:
- $ref: '#/components/parameters/ConversationId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [messages]
properties:
messages:
type: array
description: Array of messages in AI SDK format
items:
type: object
properties:
id:
type: string
role:
type: string
enum: [user, assistant, system]
content:
type: string
parts:
type: array
items:
type: object
properties:
type:
type: string
example: text
text:
type: string
metadata:
type: object
properties:
speaker:
type: string
enum: [student, coach]
description: Who is being addressed (student) or who is responding (coach)
quotedText:
type: string
quotedMessageId:
type: string
example:
messages:
- id: msg-1
role: user
content: 你好,我有數學問題
parts:
- type: text
text: 你好,我有數學問題
metadata:
speaker: student
responses:
'200':
description: Streaming response with AI-generated message
content:
text/event-stream:
schema:
type: string
'404':
$ref: '#/components/responses/NotFound'
/api/conversations/{conversationId}/system-messages:
post:
tags: [System Messages]
summary: Create system message
description: |
Add a system message to the conversation for context.
Use cases: student background info, medication status, session notes, milestones.
parameters:
- $ref: '#/components/parameters/ConversationId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [content]
properties:
content:
type: string
example: 學生剛吃了ADHD藥物(30分鐘前)
responses:
'200':
description: System message created
content:
application/json:
schema:
type: object
properties:
message:
$ref: '#/components/schemas/Message'
success:
type: boolean
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/api/conversations/{conversationId}/system-messages/{messageId}:
put:
tags: [System Messages]
summary: Update system message
description: Update the content of an existing system message
parameters:
- $ref: '#/components/parameters/ConversationId'
- $ref: '#/components/parameters/MessageId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [content]
properties:
content:
type: string
example: 學生剛吃了ADHD藥物(1小時前)
responses:
'200':
description: System message updated
content:
application/json:
schema:
type: object
properties:
message:
$ref: '#/components/schemas/Message'
success:
type: boolean
'400':
description: Bad request (e.g., trying to update non-system message)
'404':
$ref: '#/components/responses/NotFound'
delete:
tags: [System Messages]
summary: Delete system message
parameters:
- $ref: '#/components/parameters/ConversationId'
- $ref: '#/components/parameters/MessageId'
responses:
'200':
description: System message deleted
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
message:
type: string
'400':
description: Bad request (e.g., trying to delete non-system message)
'404':
$ref: '#/components/responses/NotFound'
/api/coach/types:
get:
tags: [Coach]
summary: List available coaches
description: Get list of available coach personalities
responses:
'200':
description: List of coaches
content:
application/json:
schema:
type: object
properties:
coaches:
type: array
items:
type: object
properties:
id:
type: string
example: empathetic
name:
type: string
example: 王老師
description:
type: string
/api/stats:
get:
tags: [Stats]
summary: Get user statistics
description: Get conversation and message statistics for the authenticated user
responses:
'200':
description: User statistics
content:
application/json:
schema:
type: object
properties:
totalConversations:
type: number
totalMessages:
type: number
conversationsByStudent:
type: object
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
description: Use username and the password from BASIC_AUTH_PASSWORD env var (default 'cz-2025')
parameters:
ConversationId:
name: conversationId
in: path
required: true
schema:
type: string
format: uuid
description: Conversation ID
MessageId:
name: messageId
in: path
required: true
schema:
type: string
format: uuid
description: Message ID
schemas:
Conversation:
type: object
properties:
id:
type: string
format: uuid
userId:
type: string
format: uuid
studentPromptId:
type: string
example: grade_3
studentName:
type: string
example: 小三學生
description: "Derived from student prompt template (not stored in database). Generated from student-prompts.ts based on studentPromptId."
coachPromptId:
type: string
enum: [empathetic, structured, balanced]
coachName:
type: string
example: 王老師
description: "Derived from coach prompt template (not stored in database). Generated from coach-prompts.ts based on coachPromptId."
title:
type: string
titleSource:
type: string
enum: [auto, auto-locked, user]
summary:
type: string
systemPrompt:
type: string
sourceConversationId:
type: string
format: uuid
description: "ID of conversation this was branched from (null if not a branch)"
branchedFromMessageId:
type: string
format: uuid
description: "ID of message where this branch was created (null if not a branch)"
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
lastActiveAt:
type: string
format: date-time
Message:
type: object
properties:
id:
type: string
format: uuid
conversationId:
type: string
format: uuid
role:
type: string
enum: [user, assistant, system]
speaker:
type: string
enum: [student, coach]
description: Who is speaking in this message
content:
type: string
responseId:
type: string
description: OpenAI Responses API response ID
timestamp:
type: string
format: date-time
quotedText:
type: string
description: Selected text being replied to
quotedMessageId:
type: string
description: ID of message being replied to
responses:
BadRequest:
description: Bad request
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Invalid input
Unauthorized:
description: Unauthorized
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Unauthorized
NotFound:
description: Resource not found
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Conversation not found