# Conol.ai SSE Protocol (Agent Sessions) Conol.ai uses a custom SSE protocol over `/api/sessions`. This is NOT standard OpenAI SSE. ## Endpoints ### 1. Create Session ``` POST https://conol.ai/api/sessions Content-Type: application/json Cookies: __Secure-better-auth.session_token= __Secure-better-auth.better-auth-passkey= Body: { "source": {"type": "home"}, "messages": [{"type": "text", "content": "user prompt"}], "timezone": "Europe/Kyiv", "agentModel": "gpt-5.5", "agentEffort": "low" } Response: 201 Created { "sessionId": "dh2btg2juiqtjfuv5m02by2v" } ``` ### 2. Stream SSE Messages ``` GET https://conol.ai/api/sessions/{sessionId}/messages?logDeltas=1 ``` ## SSE Event Types ### `history_delta` — Main content event This is the PRIMARY event type. Content is nested: `stages[] → logs[] → content[] → {type: "text", text: "..."}` ```json { "type": "history_delta", "runtimeVersion": "orcai", "stages": [{ "id": "hjbl6q...", "logs": [{ "role": "assistant", "type": "thinking", "content": [{"type": "text", "text": "The user is asking..."}] }], "preview": [{ "role": "assistant", "type": "thinking", "content": [{"text": "..."}] }] }] } ``` ### `done` — End of stream ```json {"type": "done"} ``` ## Common Mistakes ### ❌ Looking for `text-delta` events Conol.ai does NOT emit `text-delta`. All content comes via `history_delta`. ### ❌ Direct `POST /api/chat` There is NO `/api/chat` endpoint. The only way to interact is through `/api/sessions`. ### ❌ Parsing only top-level content Content is always nested: `stages[].logs[].content[]`. Must iterate through all levels. ## Correct Parser (Python) ```python async with client.stream("GET", f"https://conol.ai/api/sessions/{sid}/messages?logDeltas=1") as stream: async for line in stream.aiter_lines(): if not line or not line.startswith("data:"): continue ev = json.loads(line[5:].strip()) if ev.get("type") == "done": break if ev.get("type") == "history_delta": for stage in ev.get("stages", []): for log in stage.get("logs", []): content = log.get("content", []) if isinstance(content, list): for part in content: if isinstance(part, dict) and part.get("type") == "text": full_text = part.get("text", full_text) ``` ## Cookies Conol.ai uses `better-auth` (not next-auth): - `__Secure-better-auth.session_token` — session token - `__Secure-better-auth.better-auth-passkey` — passkey Both are `Secure`, `HttpOnly`, `SameSite=Lax`, domain `.conol.ai`. Cookies expire and return HTTP 401 — re-login via Chrome CDP.