Authenticated with the tenant admin JWT (different from the SDK’s X-API-KEY). Hosted on https://{tenantCode}.aika.life (beta) / https://{tenantCode}.ones1ght.com (production).Backoffice (admin.aika.life) calls /api/v1/admin/sdk-chat/... for unrestricted cross-tenant access (super admin role).
1. Real-time SSE stream
GET /api/v1/sdk-chat/events/stream
Content-Type: text/event-stream. Open one connection as a tenant admin and every SDK chat lifecycle event for that tenant is pushed live. 25 s ping heartbeat keeps the connection past ALB / nginx idle timeouts.
Events
| event | trigger | data payload |
|---|
ready | Once on connect | {} |
ping | Every 25 s | (empty string) |
chat_completed | First time poll status flips to "completed" | {profile_id, chat_id} |
backlist_triggered | iOS calls POST /v1/chat/{pid}/backlist-trigger | {profile_id, chat_id, notification_items} |
Browser example
const es = new EventSource("/api/v1/sdk-chat/events/stream", { withCredentials: true });
es.addEventListener("chat_completed", (e) => {
const { profile_id, chat_id } = JSON.parse(e.data);
// → re-fetch GET /api/v1/sdk-chat/{chat_id} for fresh detail
});
es.addEventListener("backlist_triggered", (e) => {
const { profile_id, chat_id, notification_items } = JSON.parse(e.data);
// → toast / map marker in the dashboard
});
Live-only — events fired while no one is subscribed are dropped (no buffering). Use the history endpoints below for backfill.
2. History list (paged)
GET /api/v1/sdk-chat?profile_id={uuid}&page=0&size=20
Paginates the tenant’s sdk_chat rows, newest first. profile_id filter optional. size capped at 100.
Response 200
{
"success": true,
"data": {
"items": [
{
"chat_id": "3736f10f-...",
"profile_id": "6b97957c-...",
"profile_summary": { "name": "Sato Hanako", "gender": "F", "age": 32, "locale": "ja" },
"prompt": "Dinner ideas?",
"status": "completed",
"last_error": null,
"created_at": "2026-04-23T05:28:08Z",
"updated_at": "2026-04-23T05:30:00Z",
"ended_at": "2026-04-23T05:31:00Z"
}
],
"total": 234,
"page": 0,
"size": 20
}
}
| Field | Description |
|---|
status | in_progress / completed / error / ended (same vocabulary as poll) |
profile_summary | {name, gender, age, locale} extracted from sdk_profile.data JSONB |
last_error | Set on error only |
ended_at | DELETE timestamp; null otherwise |
pipeline_result is intentionally omitted from the list to keep payloads small. Hit the detail endpoint for the full snapshot.
3. History detail
GET /api/v1/sdk-chat/{chat_id}
Mirrors the poll-completion shape — status / back_list_status / todos / recommended_items / notification_items are hoisted to the top level so the dashboard can replay the same render. Field reference: see Profile Chat — 4. Replay a past chat.
Adds profile_summary and profile_session_id on top of the poll shape.
4. Backoffice (super admin) endpoints
For admin.aika.life. Cross-tenant unrestricted view. Both tenant_id and profile_id are optional filters.
| Endpoint | Effect |
|---|
GET /api/v1/admin/sdk-chat?tenant_id=...&profile_id=...&page=...&size=... | List shape identical to tenant-admin variant; each row also carries tenant_id |
GET /api/v1/admin/sdk-chat/{chat_id} | Detail shape identical, no tenant constraint |
Auth: ROLE_ADMIN (Spring Security @PreAuthorize).
5. Permissions matrix
| Endpoint | Auth | Required role |
|---|
GET /api/v1/sdk-chat/events/stream | Tenant JWT | user.role == 'admin' |
GET /api/v1/sdk-chat | Tenant JWT | user.role == 'admin' |
GET /api/v1/sdk-chat/{chat_id} | Tenant JWT | user.role == 'admin' |
GET /api/v1/admin/sdk-chat | Backoffice JWT | ROLE_ADMIN |
GET /api/v1/admin/sdk-chat/{chat_id} | Backoffice JWT | ROLE_ADMIN |
Returns 401 / 403 on auth failure.
6. Recommended push + pull pattern
[page mount]
├─ GET /api/v1/sdk-chat?page=0 → initial list render
└─ EventSource(/events/stream) → live deltas afterwards
├─ chat_completed → re-fetch GET /{chat_id} for fresh detail
└─ backlist_triggered → toast / map marker immediately