6.3 KiB
6.3 KiB
conol.ai Chat API Endpoints (2026-07-23)
Discovered from JS bundle analysis of /_next/static/immutable/chunks/ on conol.ai.
Architecture
- Frontend: Next.js SPA with Turbopack
- Auth:
better-auth(session token in__Secure-better-auth.session_tokencookie) - Chat: SSE (Server-Sent Events) via
EventSource - Subdomain:
agent.conol.aifor health checks only (/api/health→{"ok":true})
Authentication
The session token is stored in cookie __Secure-better-auth.session_token (URL-encoded value).
All API calls require this cookie. Bearer token in Authorization header returns Invalid API key.
Other cookies in the session:
__Secure-better-auth.better-auth-passkey— passkey authuser_session,__Host-user_session_same_site— GitHub sessionlogged_in,dotcom_user— GitHub login state
Chat Endpoints
Create Session
POST /api/sessions
Content-Type: application/json
Cookie: __Secure-better-auth.session_token=<token>
{
"source": "web",
"messages": [
{"type": "text", "content": "Hello"},
{"type": "image", "url": "https://..."} // optional
],
"timezone": "Europe/Moscow",
"agentServerId": "optional-server-id",
"agentName": "optional-agent-name",
"agentModel": "optional-model-id",
"modelPreset": "optional-preset",
"agentEffort": "optional-effort"
}
Response: {"sessionId": "..."}
Send Message to Existing Session
POST /api/sessions/{sessionId}/messages
Content-Type: application/json
Cookie: __Secure-better-auth.session_token=<token>
{
"messages": [{"type": "text", "content": "Hello"}],
"timezone": "Europe/Moscow"
}
Response: 200 OK
Stream Messages (SSE)
GET /api/sessions/{sessionId}/messages?logDeltas=1
Cookie: __Secure-better-auth.session_token=<token>
// SSE events:
event: history → {"messages": [...], "todoList": [...], "statusMessage": "...", "intention": "...", "title": "...", "sandboxAccess": [...], "sandboxStatus": "ready"}
event: history_delta → {"stages": [...], "windowReset": true/false, "from": N, "logFrom": N, "intention": "...", "agentSessionId": "...", "title": "...", "todoList": [...], "contextUsage": {...}, "pendingQuestionary": {...}, "sandboxAccess": [...]}
event: assistant → {"message": {"content": [...]}}
event: stream_event → {"delta": {"type": "text_delta", "text": "..."}}
event: thinking → {"message": {"content": "..."}}
event: tool_use → {"tool": "...", "brief": "..."}
event: plan → {"todoList": [...], "totalTodos": N, "doneTodos": N}
event: status → {"message": {"content": "..."}}
event: intention → {"message": {"content": "..."}}
event: questionary → {...}
event: sandbox_ready → {"sandboxAccess": [...]}
event: sandbox_paused → (no payload)
event: sandbox_resuming → (no payload)
event: done → (no payload)
event: error → {"message": {"content": "..."}}
event: result → {"message": {"subtype": "success|error", "content": "..."}}
event: insufficient_balance → (no payload)
Stop Generation
PUT /api/sessions/{sessionId}/stop
Cookie: __Secure-better-auth.session_token=<token>
Delete Session
DELETE /api/sessions/{sessionId}
Cookie: __Secure-better-auth.session_token=<token>
Change Model
POST /api/sessions/{sessionId}/model
Content-Type: application/json
Cookie: __Secure-better-auth.session_token=<token>
{
"agentModel": "model-id",
"modelPreset": "preset",
"agentEffort": "effort"
}
Load Older Messages
GET /api/sessions/{sessionId}/stages?beforeStage=N&beforeLog=N
Cookie: __Secure-better-auth.session_token=<token>
Response: {"older": [...], "newStageBase": N, "newLogBase": N, "hasOlder": true/false}
Management Endpoints
Active Sessions
GET /api/sessions/active
Cookie: __Secure-better-auth.session_token=<token>
Pinned Sessions
GET /api/sessions/pinned
Cookie: __Secure-better-auth.session_token=<token>
Session History
GET /api/sessions/history?limit=50 // first page
GET /api/sessions/history?limit=50&cursor=<encoded> // next page
Cookie: __Secure-better-auth.session_token=<token>
Other Endpoints
Agent Servers (Model List)
GET /api/agent-servers
// Returns 28+ models: claude-opus-4-8, gpt-5.6-sol, deepseek-v4-pro, grok-4.3, etc.
// No auth required for this endpoint
Billing
GET /api/billing/balance
GET /api/billing/subscription
GET /api/billing/catalog
Cookie: __Secure-better-auth.session_token=<token>
Auth
POST /api/auth/sign-in/email → CAPTCHA_MISSING (Cloudflare Turnstile)
POST /api/auth/sign-in/social → 429 rate limited
POST /api/auth/sign-up → 404
Secrets (API Keys)
GET /api/secrets
POST /api/secrets → {"name": "...", "domains": [...], "value": "sk-..."}
DELETE /api/secrets/{id}
Cookie: __Secure-better-auth.session_token=<token>
OmniRoute Provider Pattern
For building a proxy handler, follow the OmniRoute web-cookie provider pattern:
Registry Entry (in open-sse/config/providers/registry/conol-web/index.ts):
export const conol_webProvider: RegistryEntry = {
id: "conol-web",
alias: "cw",
format: "openai",
executor: "conol-web",
baseUrl: "https://conol.ai",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "gpt-5.6-sol", name: "GPT-5.6 Sol", toolCalling: true },
{ id: "claude-opus-4-8", name: "Claude Opus 4.8", toolCalling: true },
// ... all 28+ models from /api/agent-servers
],
};
Executor (in open-sse/executors/conol-web.ts):
- Accept cookie as
apiKey(the session token) - POST
/api/sessionsto create a chat session - Connect to SSE stream at
/api/sessions/{id}/messages?logDeltas=1 - Parse
stream_eventdeltas → OpenAI-compatible streaming chunks - Handle
doneevent → close stream - On error → translate to OpenAI error format
Blockers
- Rate limiting:
/api/auth/sign-in/socialreturns 429 after ~3 attempts - CAPTCHA:
/api/auth/sign-in/emailrequires Cloudflare Turnstile - Anti-bot: Browserbase headless browsers blocked on OAuth flow
- Session expiry: Session tokens from banned accounts return 401
- No public API: conol.ai has no OpenAI-compatible REST endpoint — only internal SSE API