Brain Rot Hub · API Docs

Quick start

Tất cả endpoint dưới đây có thể "try it" trực tiếp. Paste HUB_API_KEY vào ô bên dưới (lưu localStorage), bấm "Try it" trên từng endpoint để gọi thật.

Base URL:

Endpoints

GET /health

Health check. Trả về {status, timestamp} nếu Worker đang chạy.

No auth required
Click "Try it" để gọi thử
Code examples
curl JavaScript Dart
curl HUB_URL/health
const res = await fetch(`${HUB_URL}/health`);
const data = await res.json();
// { status: "ok", timestamp: 1234567890 }
final res = await http.get(Uri.parse('$hubUrl/health'));
final data = jsonDecode(res.body);
// {'status': 'ok', 'timestamp': 1234567890}
POST /chat

Non-streaming chat. Gửi query, chờ full response, trả về JSON.

Authorization: Bearer <HUB_API_KEY>
Click "Try it" để gọi thử
Code examples
curl JavaScript Dart
curl -X POST HUB_URL/chat \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer HUB_API_KEY" \
  -d '{"projectId":"english-learning","userId":"demo_user","query":"Hello"}'
const res = await fetch(`${HUB_URL}/chat`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${HUB_API_KEY}`,
  },
  body: JSON.stringify({
    projectId: 'english-learning',
    userId: 'demo_user',
    query: 'Hello',
  }),
});
const { answer, latencyMs } = await res.json();
final res = await http.post(
  Uri.parse('$hubUrl/chat'),
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer $hubApiKey',
  },
  body: jsonEncode({
    'projectId': 'english-learning',
    'userId': 'demo_user',
    'query': 'Hello',
  }),
);
final data = jsonDecode(res.body);
final answer = data['answer'];
POST /chat/stream

Streaming chat. Trả response từng chunk qua Server-Sent Events. UX typing effect.

Authorization: Bearer <HUB_API_KEY>
Click "Try it" để gọi thử (sẽ thấy chunks xuất hiện dần)
SSE response format
data: {"delta": "Sure! "}

data: {"delta": "Here are "}

data: {"delta": "3 tips..."}

data: {"done": true, "latencyMs": 1850}
Code examples
curl JavaScript Dart
curl -N -X POST HUB_URL/chat/stream \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer HUB_API_KEY" \
  -d '{"projectId":"english-learning","userId":"demo_user","query":"Hello"}'
const res = await fetch(`${HUB_URL}/chat/stream`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${HUB_API_KEY}`,
  },
  body: JSON.stringify({ projectId, userId, query }),
});

const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = '';

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  const lines = buffer.split('\n');
  buffer = lines.pop() || '';
  for (const line of lines) {
    if (!line.startsWith('data: ')) continue;
    const data = JSON.parse(line.slice(6));
    if (data.delta) console.log(data.delta);
  }
}
// Flutter: dùng http.Request với send() để stream
final req = http.Request('POST', Uri.parse('$hubUrl/chat/stream'))
  ..headers['Content-Type'] = 'application/json'
  ..headers['Authorization'] = 'Bearer $hubApiKey'
  ..body = jsonEncode({'projectId': p, 'userId': u, 'query': q});

final streamed = await req.send();
await for (final chunk in streamed.stream.transform(utf8.decoder)) {
  for (final line in chunk.split('\n')) {
    if (line.startsWith('data: ')) {
      final data = jsonDecode(line.substring(6));
      if (data['delta'] != null) print(data['delta']);
    }
  }
}
POST /sessions/get

Load conversation history của (project, user) từ server. Dùng khi app khởi động để hiển thị chat cũ.

Authorization: Bearer <HUB_API_KEY>
Click "Try it" để gọi thử
Response shape
{
  "messages": [
    { "role": "user", "content": "...", "timestamp": 1234567890 },
    { "role": "assistant", "content": "...", "timestamp": 1234567891 }
  ]
}
POST /sessions/clear

Xóa conversation history của (project, user). Dùng cho nút "New chat" / "Reset" trong app.

Authorization: Bearer <HUB_API_KEY>
Click "Try it" để gọi thử