Skip to main content
This page is written for an agent that writes client code. Every fact here is also somewhere else on this site. Nothing here contradicts the OpenAPI document. When they disagree, the OpenAPI document wins.
Machine-readable spec: 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 /health is 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. Exactly one terminal event per stream. A model failure is an error event, with HTTP status 200. Do not map a failed turn to an HTTP status.

Mistakes to avoid

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.
The request body holds only message and an optional image. The server owns the history. Sending a message array is not supported and is silently dropped by schema validation.
The student message is persisted before the model runs. An automatic retry duplicates it. Retry only on an explicit student action.
Lala updates the profile itself during a conversation. Re-read GET /api/me instead of writing back a cached object.
PATCH /api/profile accepts communicationStyle, but no response returns it. It is stored with the conversation context, not the profile.
ChatMessage.id is optional and is not present on every message. Rebuild the list from the server response instead.
Route errors are {"error": string}. Schema validation errors are {"success": false, "data": ..., "error": [issues]}. Both use status 400 or 401.
There is no upload endpoint. The image goes inline as base64 in the chat body, with a mimeType.

Client checklist

1

Read the token from the Supabase session for each request

Do not cache the string. The library refreshes it.
2

Call GET /api/me after sign-in

It creates the student row and tells you whether onboarding is complete.
3

Set the OneSignal external_id to the same id

Without the alias, proactive messages never reach the device.
4

Set the chat request timeout to 90 seconds or more

The server aborts the model after 60 seconds, and a turn can run several tool steps.
5

Handle exactly one terminal SSE event, and a dropped socket

A dropped socket with no terminal event is a failed turn on the client. The server still finishes it.
6

Refetch history on foreground, after a push, and after an error

The history endpoint is the source of truth.

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.json or a generated client package. Run npm 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.