https://client-api.lala.ist/openapi.json. Fetch it before you generate
code.Hard facts
- Base URL, production:
https://client-api.lala.ist - Base URL, local:
http://localhost:3000 - Auth:
Authorization: Bearer <supabase_access_token>. No API key exists. - Only
GET /healthis unauthenticated. - Content type for requests with a body:
application/json. - Timestamps are UTC, ISO 8601. Lala’s own day runs on
Europe/Istanbul. - All student-visible text is Turkish. All identifiers and error strings are English.
- There is no rate limit today. There is no pagination anywhere.
Endpoint table
The SSE contract
POST /api/chat/send responds 200 with text/event-stream.
error event, with HTTP status
200. Do not map a failed turn to an HTTP status.
Mistakes to avoid
Using EventSource for the stream
Using EventSource for the stream
EventSource sends GET and cannot set the Authorization header. Use fetch, or an HTTP
client that exposes the response body as a byte stream, and parse the SSE lines yourself.Sending the conversation history in the request
Sending the conversation history in the request
message and an optional image. The server owns the history.
Sending a message array is not supported and is silently dropped by schema validation.Retrying POST /api/chat/send automatically
Retrying POST /api/chat/send automatically
Treating the profile as client-owned state
Treating the profile as client-owned state
GET /api/me instead of
writing back a cached object.Expecting communicationStyle in a response
Expecting communicationStyle in a response
PATCH /api/profile accepts communicationStyle, but no response returns it. It is stored
with the conversation context, not the profile.Keying the UI on a message id
Keying the UI on a message id
ChatMessage.id is optional and is not present on every message. Rebuild the list from the
server response instead.Assuming one error shape
Assuming one error shape
{"error": string}. Schema validation errors are
{"success": false, "data": ..., "error": [issues]}. Both use status 400 or 401.Uploading an image as multipart
Uploading an image as multipart
mimeType.Client checklist
Read the token from the Supabase session for each request
Call GET /api/me after sign-in
Set the OneSignal external_id to the same id
Set the chat request timeout to 90 seconds or more
Handle exactly one terminal SSE event, and a dropped socket
Refetch history on foreground, after a push, and after an error
Do not generate
- Do not generate a stream reader from the OpenAPI document. The SSE framing is not in it.
- Do not hand-edit
openapi.jsonor a generated client package. Runnpm run openapi:emit. - Do not invent endpoints. Version 1 has the five routes in the table above, and nothing else.
- Do not translate or rewrite Turkish text from the API. Render it as it arrives.