Brain API v1
Authentication
Section titled “Authentication”All requests require a Bearer token (the per-member API key) and a team identifier header:
Authorization: Bearer aios_<key_id>_<secret>X-AIOS-Team: <team-slug>API keys are aios_<key_id>_<secret> format, SHA-256 hashed at rest. Keys are shown once at creation.
Endpoints
Section titled “Endpoints”POST /api/v1/items
Section titled “POST /api/v1/items”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 hasadmintier. Admin content is never accepted. Fix theaudiencefrontmatter.401— Invalid or missing API key.403— Team not found or key not authorized for this team.
GET /api/v1/items
Section titled “GET /api/v1/items”Pull team-tier content since a given timestamp (for aios pull).
Query parameters:
| Param | Type | Description |
|---|---|---|
since | ISO 8601 | Return items updated after this time |
cursor | string | Keyset pagination cursor from previous response |
limit | int | Page size (default 50, max 200) |
Response:
{ "items": [...], "next_cursor": "eyJpZCI6MTIzfQ==", "has_more": true}GET /api/v1/tasks
Section titled “GET /api/v1/tasks”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.
GET /api/v1/decisions
Section titled “GET /api/v1/decisions”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.)
GET /api/v1/projects
Section titled “GET /api/v1/projects”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.)
POST /api/v1/query
Section titled “POST /api/v1/query”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:
| Event | Payload |
|---|---|
delta | { "text": "..." } — incremental LLM output |
sources | [{ "row_key": "...", "title": "...", "tier": "team" }] — cited items |
done | {} — stream complete |
POST /api/v1/codebases
Section titled “POST /api/v1/codebases”Ingest a codebase scan (raw metrics + an optional AEM agent-readiness score) from aios assess-codebase --push. Team-tier only — an external-tier key is rejected. (Additive in v1; clients tolerate a 404 from an older brain.)
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.
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.
POST /api/v1/metrics
Section titled “POST /api/v1/metrics”Ingest one day’s Agentic Engineering Maturity (AEM) 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 } }, "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.
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— suppliedmemberis not on the caller’s team.429— rate limit, 60 snapshots/min per key.
Row keys
Section titled “Row keys”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
Section titled “Rate limits”Rate limits are enforced per-member and per-team in the query_log table. Defaults:
| Scope | Limit |
|---|---|
| Per-member daily query cost | Configurable via DAILY_MEMBER_CAP_USD |
| Per-team daily query cost | Configurable via DAILY_TEAM_CAP_USD |
| Sync writes per minute | 60 items/min per key |
Tier vocabulary
Section titled “Tier vocabulary”| Friendly name | Canonical (wire format) | Accepted by brain? |
|---|---|---|
private, personal | admin | No — 422 |
team | team | Yes |
client, company | external | Yes |