Skip to content

Brain API v1

Every request carries Authorization. The API key is the authoritative team identity, so clients do not need to configure or send a separate team identifier:

Authorization: Bearer aios_<key_id>_<secret>
X-AIOS-Team: <team-uuid-or-slug> # optional, for older clients

API keys are aios_<key_id>_<secret> format, issued per member and shown once at creation; the brain stores only sha256(secret). X-AIOS-Team is an optional compatibility header — when supplied it must match the key’s team UUID or slug, and clients must omit it rather than send an empty value. Authentication failures return 401 and are audit-logged.


Upsert one or more content items from a workspace push.

Request body:

{
"items": [
{
"row_key": "2-work/sprint-1-retro.md",
"content": "# Sprint 1 Retro\n...",
"frontmatter": {
"title": "Sprint 1 retrospective",
"audience": "team",
"date": "2025-06-01"
},
"tier": "team",
"checksum": "sha256:abc123..."
}
]
}

Response:

{ "accepted": 3, "rejected": 0, "errors": [] }

Errors:

  • 422 — Item has admin tier. Admin content is never accepted. Fix the audience frontmatter.
  • 401 — Invalid or missing API key.
  • 403 — Team not found or key not authorized for this team.

Pull team-tier content since a given timestamp (for aios pull).

Query parameters:

ParamTypeDescription
sinceISO 8601Return items updated after this time
cursorstringKeyset pagination cursor from previous response
limitintPage size (default 50, max 200)

Response:

{
"items": [...],
"next_cursor": "eyJpZCI6MTIzfQ==",
"has_more": true
}

Pull task rows materialized from decision/task logs since a given timestamp. Used by aios pull to write back task updates.

Same pagination parameters as /api/v1/items.

?mode=sync-origin&project=<slug> (v1.13) returns status and assignee changes for the rows this workspace pushed. Before it existed the writeback feed was dashboard-origin only, so the brain→Linear projection was one-way and 3-log/tasks-team.md decayed silently. The mode selector is additive and defaults to the pre-1.13 behaviour, so an old client’s requests and responses are byte-identical; a new client feature-detects by checking the echoed mode (a pre-1.13 brain ignores the parameter and answers mode: "writeback") and tolerates 400/404. Sync-origin rows also carry raw_status, and the mode is paged via next_cursor.


GET /api/v1/tasks?mode=table&keys=<k1,k2,…>

Section titled “GET /api/v1/tasks?mode=table&keys=<k1,k2,…>”

Check whether up to 200 specific task keys are visible to the caller without confusing absence from a capped full-table page with non-existence. The response uses the ordinary table feed and adds unknown_keys for requested keys that matched nothing the caller may see.

Clients must confirm both mode === "table" and an unknown_keys array before treating the answer as authoritative. A pre-v1.14 brain can ignore keys and return a different feed. If the read could have truncated, unknown_keys is null, meaning “could not determine.” Tier filtering is intentional: a key the caller cannot see is indistinguishable from one that does not exist.


Pull decision rows created or edited in the dashboard since a given ?since= timestamp. Used by aios pull to write dashboard decisions back into 3-log/decision-log.md. Tier-scoped — an external-tier key receives only audience: "external" rows. (Additive in v1; clients tolerate a 404 from an older brain.)


List the team’s projects (team-tier keys only) so aios pull can register brain-created projects (created in the dashboard, never pushed) as local marker files. Returns { "projects": [{ "slug", "name", "brain_only" }] }. (Additive in v1; clients tolerate a 404.)


Natural-language query over the team’s shared memory. Returns a server-sent event (SSE) stream.

Request body:

{ "q": "what decisions were made about auth in sprint 1?" }

SSE event types:

EventPayload
delta{ "text": "..." } — incremental LLM output
sources[{ "row_key": "...", "title": "...", "tier": "team" }] — cited items
done{} — stream complete

Ingest a codebase scan (raw metrics + an optional AM agent-readiness score). The canonical pusher is the ingestion sidecar (aios-ingest scan) — the workspace’s aios assess-codebase is offline and read-only, its sparse --push having been removed in the 2026-06-19 revision. Team-tier only — an external-tier key is rejected. (Additive in v1; clients tolerate a 404 from an older brain.)

The full raw-metrics block is required. A sparse push is rejected 422, because the metrics upsert replaces the row on (codebase_id, head_sha) and a partial write would zero existing analytics. The readiness_* fields stay optional.

Request body:

{
"codebase": { "slug": "my-repo", "full_name": "org/my-repo", "provider": "github" },
"metrics": {
"head_sha": "abc123…",
"has_claude_md": true,
"has_agents_md": false,
"skills_count": 7,
"commands_count": 3,
"readiness_level": "L3",
"readiness_pct": 67.0,
"readiness_pillars": { "testing": { "passed": 2, "total": 2 } },
"readiness_rubric_version": "1.0.0"
}
}

The readiness_* fields are scored scanner-side and persisted as-is; the brain computes a separate heuristic agentic_score at ingest.

codebase_health (revision 1.15, optional) — a scalar-only snapshot of the repository’s workspace-governance health check, scored scanner-side, carried under metrics. Fields (all required when the object is present): schema_version, rubric_version, head_sha, score_pct (0100), status ("pass" | "warn" | "fail"), dimensions (short dimension id → { "passed": int, "total": int }), failed_invariant_ids (short rubric ids), and measured_at (ISO-8601 UTC). Three normative rules:

  • Additive — a payload without codebase_health remains valid exactly as before 1.15; an older brain ignores the unknown key.
  • Never sparse — a sender including codebase_health must still send the full raw-metrics block in the same push. A health-only payload is a sparse push and is rejected 422, because the metrics upsert replaces the row on (codebase_id, head_sha).
  • Provenance-only — the brain persists it verbatim and never recomputes it. Scalars only: no file paths, no source text, no contributor identity cross the boundary (failed_invariant_ids are short rubric ids, not paths or findings text).

The machine-readable contract is contract/codebase-payload-1.15.schema.json in the workspace repo, with canonical parity fixtures alongside it. Revision 1.15 is doc + schema only — it enables no new push lane; the canonical pusher remains the ingestion sidecar.

Response:

{ "status": "ok", "codebase_id": "uuid", "metrics_id": "uuid", "contributions": 0, "issues": 0 }

Idempotent: the codebase is keyed by (team, slug) and each scan point by (codebase, head_sha) — re-pushing the same commit updates in place.

Errors:

  • 403 (forbidden_tier) — codebase metrics are team-tier only.
  • 429 — rate limit, 60 scans/min per key.

Ingest one day’s Agentic Maturity (AM) individual snapshot from aios analyze --push. Team-tier only — an external-tier key is rejected. Only ratios and counts cross the boundary; raw session content never leaves the machine. (Additive in v1; clients tolerate a 404.)

Request body:

{
"member": "alex",
"metric": "aem-individual",
"date": "2026-06-19",
"window_days": 1,
"signals": {
"delegation_ratio": 0.18, "correction_loop_avg": 1.4, "error_rate": 0.05,
"cost_per_task": 0.42, "tokens_per_task": 31000, "cache_hit_rate": 0.71,
"tool_diversity": 9.0, "verify_tool_rate": 0.22, "subagent_usage": 0.06
},
"provisional": {
"spine": "L3",
"axes": { "verification": 3.1, "context_hygiene": 3.8, "autonomy": 2.4, "learning": 3.0, "cost_governance": 3.6 }
},
"ce_band": 3,
"sessions": 41,
"tasks": 137
}

provisional is the client’s local placement (provenance only); the brain recomputes the canonical axes/Spine from signals so team rollups have a single authority. member is optional and defaults to the key’s member.

v1.3 (additive): optional ce_band — integer 04 or omitted/null. A coarse cognitive-ergonomics shadow band scored client-side relative to the operator’s own baseline (higher = more protected attention). Provenance-only: the brain persists it verbatim and never recomputes it. Older CLIs omit it; an older brain ignores it. Together with signals and provisional, this scalar is the entire privacy surface — the four raw attention signals (focus_block_avg_min, context_switch_rate, interrupts_per_hour, concurrent_sessions_peak) never cross the boundary.

Response:

{ "status": "ok", "snapshot_id": "uuid", "member_id": "uuid", "canonical": { "spine": "L3", "axes": { "verification": 3 } } }

Idempotent per (team, member, date, metric) — re-pushing the same day updates in place.

Errors:

  • 403 (forbidden_tier) — agentic-maturity metrics are team-tier only.
  • 422 — supplied member is not on the caller’s team.
  • 429 — rate limit, 60 snapshots/min per key.

row_key is the relative path from the workspace root (e.g. 2-work/sprint-1-retro.md). It is the stable identifier used for diff-sync — a push with the same row_key and a new checksum updates the existing record; same checksum is a no-op.


Rate limits are enforced per-member and per-team in the query_log table. Defaults:

ScopeLimit
Per-member daily query costConfigurable via DAILY_MEMBER_CAP_USD
Per-team daily query costConfigurable via DAILY_TEAM_CAP_USD
Sync writes per minute60 items/min per key

Friendly nameCanonical (wire format)Accepted by brain?
private, personaladminNo — 422
teamteamYes
client, companyexternalYes