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:
GET
/health
Health check. Trả về {status, timestamp} nếu Worker đang chạy.
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>Request body
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>Request body
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>Request body
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>Request body
Click "Try it" để gọi thử