Endpoints
Grouped by area; paths relative to the Mother AI origin.Jobs
Workflows & prompts
Projects, capabilities, work
Approvals
Models & catalog
Slack, knowledge, misc
The SSE stream
GET /v1/jobs/:id/stream replays the durable backlog (the job’s event list in Redis) before joining the live pub/sub channel, and stays open until the job finishes or errors. The invariant: a reconnecting client never misses an event — replay first, then live, with monotonic sequence numbers to detect gaps.
The AgentEvent envelope
Every event is JSON with a discriminatedkind:
worker/worker/runtime/agent_messages.py (Python) mirrored by apps/frontend/lib/types/agent-event.ts (TypeScript).
Kind catalog
Payload contracts worth knowing
routing_decision— emitted per level during scenario runs (level_id,provider,model,tier,model_candidates).modelis the intended model and may be""(nothing pinned). The legacy job-level variant from the pre-scenario orchestrator carries nolevel_id; consumers must not attribute it to a level.level_finished—ok,attempt,duration_ms,cost_usd,output_preview, optionalverdict. Its optionalprovider/modelname the model that actually answered, and are present only for levels that made an LLM call. Absence is the contract: gates, verifiers, and aggregators omit both, which is what lets the canvas keep a role glyph instead of painting a brand mark on a level that never talked to a provider. Do not default the field. Apromptlevel that was composed in code setsdeterministic: true— a third state, distinct from both “model present” and a gate’s silent absence.model_fallback— dispatch walked the band and a later candidate answered (from_model,to_model,to_provider,reason). It corrects the intended model arouting_decisionalready reported for the same level, live, instead of waiting forlevel_finished.provider_fallback— the coarser, older signal: a level rerouted from paid to free transport entirely.ask_uservsapproval_requested—ask_userdrives the inline question panel on the live stream and pauses the graph on an interrupt (resumable viaPOST /v1/jobs/:id/resume).approval_requestedmeans a durableapprovalsrow exists, so the decision can also land from Slack or the approvals page; both are addressable bycall_id/approval_id.scenario_chained— ScenarioOrchestrator re-dispatched the same job to a follow-up scenario (e.g. intent classification → QA); the nextscenario_startedarrives right after.final— terminal, withagent_message,summary, and cumulativecreated_files;erroris the other terminal kind and carriesretryable.