Syrenka Agent API v0.2.0

Text-only personal agent. Speech-to-text and text-to-speech happen on the client; this server only exchanges text.

Machine-readable: /openapi.json ยท /llms.txt

Auth

Authorization: Bearer <token> on every route except /health and these docs. The token is the identity โ€” no username is sent and no client can act as another user.

REST

RouteAuthWhat it does
GET /healthnoneLiveness. Returns 200 even while warming so a container healthcheck does not restart-loop during first-boot indexing.
GET /statusbearerAgent state, registered tools, live sessions and host metrics.
GET /toolsbearerEvery registered tool with the JSON Schema the model sees.
GET /inboxbearerThings that finished while you were away. Yours only. `?unread=1` to filter, `?id=` for one item's full body.
GET /historybearerYour own recent turns. Scoped to the calling token; you cannot read anyone else's.

WebSocket /ws

Authenticate on the handshake with the same header. Browsers may instead offer subprotocols syrenka.v1, bearer.<token>. Tokens in the query string are rejected.

Send

typefieldsnotes
turntext: string, imageIds?: string[], sessionId?: stringOmit sessionId to start a new conversation. imageIds come from POST /upload and are single-use; text may be empty when images are attached.
cancelsessionId: stringAbort the turn in flight.
resumesessionId: string, lastSeq: numberReplay everything you missed.
pingt?: numberRound-trip check; answered with pong.

Receive

typenotes
readySent on connect: your identity, session id, tool list, limits.
turn.startA turn began. Carries turnId, text, speaker, and images (a count) when pictures were attached.
step.startOne model call begins.
text.deltaReply text, token by token. Concatenate in order.
text.donefinal=false means that text was narration; final=true means it is the answer.
tool.callA tool started. callId correlates with tool.result.
tool.resultThat tool finished: ok, durationMs, result.
step.endModel call finished, with duration and tool-call count.
turn.endTurn complete, with the full reply text.
turn.errorTurn failed.
turn.queuedAnother turn is ahead of yours on this session.
noticeOut-of-band info/warn/error.
linkA tappable button for the reply it belongs to: label, kind (map/directions/web/youtube/spotify/call/sms/email) and an https/tel/sms/mailto url. Render under the message; ignore if you have nowhere to put it.
inbox.itemSomething finished while you were away โ€” research report, timer. Carries id, kind, title and the unread count. The body is fetched from /inbox when you want it.
quick.actionsLearned shortcut buttons for the Dynamic Island: [{label, command}]. Arrives shortly after ready, and again when they change.
pongReply to ping.

Client rules

Example

curl -H "Authorization: Bearer $TOKEN" http://mateusz-desktop.tail96606f.ts.net/status