Skip to main content

Endpoint

POST /api/debate
Starts a new AI-powered debate session. The endpoint returns a Server-Sent Events (SSE) stream that delivers debate messages in real-time as they’re generated.

Authentication

Requires valid NextAuth session. Returns 401 Unauthorized if not authenticated.

Rate Limiting

Limited to 8 requests per minute per user per IP address.

Request Body

topic
string
required
The debate topic or question. The system will use this to select an appropriate opponent and guide the debate.Example: “Is artificial intelligence beneficial or harmful to society?”
userProfile
object
required
User profile information for the AI agent. The agent will adopt these characteristics during the debate.

Example Request

{
  "topic": "远程工作是否应该成为主流?",
  "userProfile": {
    "name": "张三",
    "avatar": "https://example.com/avatar.jpg",
    "bio": "科技从业者,关注未来工作方式",
    "softMemory": {
      "traits": ["理性", "开放", "注重效率"],
      "interests": ["远程协作", "工作文化", "生产力"]
    }
  }
}

Response Format

Returns a text/event-stream response with Server-Sent Events. Each event has a type and associated data.

Response Headers

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

SSE Event Types

All events follow the format: event: <type>\ndata: <json>\n\n

init

Sent first to initialize the debate session.
id
string
Unique debate ID (format: debate_<timestamp>_<random>)
topic
string
The debate topic
userProfile
object
User’s profile information
opponentProfile
object
Selected opponent’s profile with personality and stance information
Example:
event: init
data: {"id":"debate_1234567890_abc","topic":"远程工作是否应该成为主流?","userProfile":{...},"opponentProfile":{"name":"李明","title":"传统管理专家",...}}

start

Indicates that a participant is about to speak.
role
string
Either "user" (user’s agent) or "opponent"
name
string
Name of the speaker
Example:
event: start
data: {"role":"user","name":"张三"}

chunk

Streaming content chunks as the AI generates responses.
role
string
Either "user" or "opponent"
content
string
Partial text content (append to previous chunks)
Example:
event: chunk
data: {"role":"user","content":"我认为"}

event: chunk
data: {"role":"user","content":"远程工作"}

event: chunk
data: {"role":"user","content":"能够提高效率"}

message

Complete message after all chunks are received.
role
string
Either "user" or "opponent"
name
string
Speaker’s name
content
string
Full message content
timestamp
number
Unix timestamp in milliseconds
Example:
event: message
data: {"role":"user","name":"张三","content":"我认为远程工作能够提高效率,减少通勤时间,让员工有更好的工作生活平衡。","timestamp":1709510400000}

synthesizing

Indicates that the debate has concluded and synthesis is being generated. Example:
event: synthesizing
data: {}

synthesis

AI-generated debate analysis and evaluation.
consensus
string[]
Points where both parties agreed
disagreements
string[]
Core points of disagreement
winner
string
Debate winner: "user", "opponent", or "tie"
winnerReason
string
Explanation for the winner determination
conclusion
string
Overall conclusion about the debate topic (max 100 characters)
recommendations
string[]
Recommendations for readers based on the debate
Example:
event: synthesis
data: {
  "consensus": ["远程工作确实存在沟通挑战", "不同行业适用性不同"],
  "disagreements": ["效率提升是否显著", "团队文化能否维持"],
  "winner": "user",
  "winnerReason": "提供了更多数据支持和实际案例,论证更充分",
  "conclusion": "远程工作的成功取决于组织文化、工具支持和管理方式的配合",
  "recommendations": ["建议企业采用混合办公模式", "重视远程协作工具的投资"]
}

done

Final event indicating debate completion. Contains full debate data.
id
string
Debate ID
topic
string
Debate topic
messages
array
Array of all debate messages (see message event structure)
synthesis
object
Complete synthesis object (see synthesis event structure)
Example:
event: done
data: {"id":"debate_1234567890_abc","topic":"...","messages":[...],"synthesis":{...}}

error

Sent if an error occurs during the debate.
message
string
Error description
Example:
event: error
data: {"message":"Debate generation failed"}

Debate Configuration

Debate Rounds: 5 rounds (configurable in source code:365)AI Model: Configured via OPENAI_MODEL environment variable (default: gpt-4o-mini)Message Length: Each participant’s response is controlled to 100-200 charactersTemperature: 0.8 for debate responses, 0.3 for synthesis

Error Responses

error
string
Error message

400 Bad Request

{
  "error": "Missing topic or userProfile"
}

401 Unauthorized

{
  "error": "Unauthorized"
}

429 Too Many Requests

{
  "error": "Rate limit exceeded",
  "retryAfter": 45
}

500 Internal Server Error

{
  "error": "Failed to start debate"
}

Implementation Notes

Request Size Limit: 24KB maximum for request body
Database Storage: All debates are automatically saved to MongoDB with status progression:
  • in_progress: During debate
  • completed: After synthesis generation

Client Implementation Example

const eventSource = new EventSource('/api/debate', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    topic: '远程工作是否应该成为主流?',
    userProfile: { name: '张三', bio: '科技从业者' }
  })
});

eventSource.addEventListener('init', (e) => {
  const data = JSON.parse(e.data);
  console.log('Debate started:', data.id);
});

eventSource.addEventListener('chunk', (e) => {
  const data = JSON.parse(e.data);
  appendToUI(data.role, data.content);
});

eventSource.addEventListener('synthesis', (e) => {
  const data = JSON.parse(e.data);
  console.log('Winner:', data.winner, data.winnerReason);
});

eventSource.addEventListener('done', (e) => {
  console.log('Debate complete');
  eventSource.close();
});

eventSource.addEventListener('error', (e) => {
  console.error('Stream error:', e);
  eventSource.close();
});

Build docs developers (and LLMs) love