Ingest a session event
Accept one coding-session event (a single Claude Code or Codex transcript line) and return immediately; a background worker embeds and stores it.
deduped instead of storing it twice, which is why this route takes no Idempotency-Key. Use POST /v1/ingest/session-batch for anything larger than a live tail.
Authorization
This route requires thewrite scope.
A missing or invalid credential returns 401 authentication_error. A valid credential without the scope returns 403 permission_denied, and the problem body names the exact scope required.
Headers
These are request conventions the contract does not declare as parameters, so they do not appear in the schema tables below.Success responses
Errors
application/problem+json body carrying a stable code, a requestId, and a suggestedAction where Exo has one. See Errors.
Notes
- Use the batch route for anything larger than a live tail. This one is for a daemon following an active transcript.
- The credential decides the organization and the user. Identity fields in the body are provenance only.
Authorizations
An Exo API key (exo_...) sent as the X-Exo-API-Key header.
Body
POST /v1/ingest/session-event: single event from Stop/SubagentStop hooks.
A single Claude Code session-log line.
Maps to one parsed line from a .jsonl session transcript (~/.claude/projects//.jsonl) or a sub-agent transcript (...//subagents/agent-*.jsonl).
Sub-agent events have parent_session_id + agent_id populated. Dedup key on the server side: (user_id, line_uuid).
Wire contract uses clean user_id / org_id field names
(camelCase aliases on the wire). DB column mapping is handled at the
SQL boundary in the ingest worker, not here.