cortex conversations
The public Cortex API uses the canonical /api/cortex/conversations route family. The older /api/chat/* routes remain compatibility aliases, but new clients should not depend on them.
scopes
Use chat=<siteId>:read to list conversations and chat=<siteId>:write to create, rename, soft-delete, or send a message.
API-key callers are intentionally capped to read-only Cortex tools during streamed replies. A chat key can ask Cortex to inspect state, but it cannot inherit the owning user's admin role to dispatch destructive machine, process, or deployment tools. Use the dashboard/session flow for operator-approved destructive tool execution until per-tool API-key scopes are introduced.
list
curl -fsS "$OWLETTE_API_URL/api/cortex/conversations?siteId=$SITE_ID&page_size=20" \
-H "Authorization: Bearer $OWLETTE_TOKEN"Response:
{
"ok": true,
"data": {
"conversations": [],
"next_page_token": "",
"nextPageToken": ""
}
}create
curl -fsS -X POST "$OWLETTE_API_URL/api/cortex/conversations" \
-H "Authorization: Bearer $OWLETTE_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d "{\"siteId\":\"$SITE_ID\",\"machineId\":\"$MACHINE_ID\",\"title\":\"diagnostics\"}"machineId is optional. Omit it for a site-wide conversation. initial_message, when supplied, must use role: "user".
send
curl -fsS -N -X POST "$OWLETTE_API_URL/api/cortex/conversations/$CONVERSATION_ID" \
-H "Authorization: Bearer $OWLETTE_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"role":"user","content":"summarize the current machine health"}'The response is text/plain; charset=utf-8 with X-Vercel-AI-Data-Stream: v1. Frames follow the AI SDK line-prefixed protocol:
0:"text": assistant text deltad:{...}: stream completion metadata3:"message": upstream Cortex error
Public send accepts only role and content. To change machines, create a new conversation pinned to the desired machine instead of overriding a conversation target mid-stream.
rename
curl -fsS -X PATCH "$OWLETTE_API_URL/api/cortex/conversations/$CONVERSATION_ID" \
-H "Authorization: Bearer $OWLETTE_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"title":"morning diagnostics"}'Only title is mutable.
delete
curl -fsS -X DELETE "$OWLETTE_API_URL/api/cortex/conversations/$CONVERSATION_ID" \
-H "Authorization: Bearer $OWLETTE_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"Delete is a soft delete. A repeated delete returns success with alreadyDeleted: true.
internal routes
/api/cortex/categorize, /api/cortex/provision-key, /api/cortex/autonomous, and /api/cortex/escalation are dashboard, agent, or scheduler internals. They are not public API surfaces.
roost versions
A version is an immutable JSON body that lists the files in a roost publish and the chunk hashes needed to reconstruct each file. The public routes use that body to publish history, resolve version refs, list files, compute diffs, roll back the current pointer, and trigger deployments.
Owlette API webhooks
webhooks are how roost tells your systems that something happened — a new version published, a deploy failed, a machine dropped offline, a quota alarm tripped. instead of polling the api on a timer, you subscribe a url once and roost posts a signed json event to it when a matching event is dispatched.