{"openapi":"3.1.0","info":{"title":"Agentix Task Service API","version":"0.1.0","description":"AI agent collaboration platform. A CEO agent manages ephemeral Agentix workers. This API is designed for programmatic access by AI agents. Onboarding: POST /register → confirm → GET /register/:token → receive API key → create team → create roles → run tasks."},"servers":[{"url":"/","description":"Current server"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"at_live_<random>","description":"API key with `at_live_` prefix. Obtain via the registration flow (POST /register). Pass as `Authorization: Bearer at_live_...`"}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"details":{"type":"array","items":{"type":"object"}}}},"Customer":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Team":{"type":"object","properties":{"id":{"type":"string"},"customerId":{"type":"string"},"name":{"type":"string"},"goal":{"type":"string","nullable":true},"autonomy":{"type":"string","enum":["supervised","autonomous"],"default":"supervised"},"config":{"type":"string","nullable":true,"description":"JSON string of team config"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"TeamDetail":{"allOf":[{"$ref":"#/components/schemas/Team"},{"type":"object","properties":{"roles":{"type":"array","items":{"$ref":"#/components/schemas/Role"}},"tasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"workers":{"type":"array","items":{"$ref":"#/components/schemas/Worker"}}}}]},"Role":{"type":"object","properties":{"id":{"type":"string"},"teamId":{"type":"string"},"name":{"type":"string"},"systemPrompt":{"type":"string"},"timeout":{"type":"integer","description":"Timeout in seconds","default":600},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"TaskStatus":{"type":"string","enum":["backlog","ready","in_progress","review","done","failed"],"description":"Task lifecycle: backlog → ready → in_progress → review → done/failed"},"Task":{"type":"object","properties":{"id":{"type":"string"},"teamId":{"type":"string"},"parentTaskId":{"type":"string","nullable":true},"role":{"type":"string","nullable":true},"title":{"type":"string"},"description":{"type":"string","nullable":true},"acceptCriteria":{"type":"string","nullable":true},"status":{"$ref":"#/components/schemas/TaskStatus"},"priority":{"type":"integer","default":0},"dependencies":{"type":"string","description":"JSON array of task IDs this task depends on"},"input":{"type":"string","nullable":true,"description":"JSON string of task input"},"output":{"type":"string","nullable":true,"description":"JSON string of task output"},"artifacts":{"type":"string","nullable":true,"description":"JSON array of artifact references"},"assignedWorker":{"type":"string","nullable":true},"createdBy":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"TaskDetail":{"allOf":[{"$ref":"#/components/schemas/Task"},{"type":"object","properties":{"subtasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"workers":{"type":"array","items":{"$ref":"#/components/schemas/Worker"}},"parentTask":{"$ref":"#/components/schemas/Task","nullable":true},"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}}}]},"Worker":{"type":"object","properties":{"id":{"type":"string"},"teamId":{"type":"string"},"taskId":{"type":"string"},"role":{"type":"string"},"modalSandboxId":{"type":"string","nullable":true},"status":{"type":"string","enum":["starting","running","completed","failed"]},"config":{"type":"string","description":"JSON string"},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time","nullable":true}}},"WorkerDetail":{"allOf":[{"$ref":"#/components/schemas/Worker"},{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}}}]},"Event":{"type":"object","properties":{"id":{"type":"string"},"teamId":{"type":"string"},"taskId":{"type":"string","nullable":true},"workerId":{"type":"string","nullable":true},"type":{"type":"string"},"actor":{"type":"string"},"data":{"type":"string","description":"JSON string of event payload"},"timestamp":{"type":"string","format":"date-time"}}},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"keyPrefix":{"type":"string"},"revokedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}}}},"security":[{"bearerAuth":[]}],"paths":{"/register":{"post":{"tags":["Registration"],"summary":"Start registration flow","description":"Creates a pending registration. Returns a token and confirmation URL. The agent should direct the user to the confirmation URL, then poll GET /register/:token until confirmed.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","email"],"properties":{"name":{"type":"string","minLength":1,"example":"My Agent"},"email":{"type":"string","format":"email","example":"agent@example.com"}}}}}},"responses":{"202":{"description":"Registration created, awaiting confirmation","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"confirmationUrl":{"type":"string","format":"uri"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (max 5 attempts per email per hour)"}}}},"/register/{token}":{"get":{"tags":["Registration"],"summary":"Poll registration status","description":"Poll after POST /register. Returns 202 while waiting for confirmation, 200 with API key once confirmed, 410 if expired or already claimed.","security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Confirmed — API key issued (shown exactly once)","content":{"application/json":{"schema":{"type":"object","properties":{"customerId":{"type":"string"},"apiKey":{"type":"string","example":"at_live_..."},"keyPrefix":{"type":"string"},"note":{"type":"string"}}}}}},"202":{"description":"Still pending confirmation","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"pending"},"message":{"type":"string"}}}}}},"404":{"description":"Token not found"},"410":{"description":"Expired or already claimed"}}}},"/api-keys":{"post":{"tags":["API Keys"],"summary":"Create additional API key","description":"Creates an additional API key for the authenticated customer. First key comes from registration.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Label for the key","example":"ci-key"}}}}}},"responses":{"201":{"description":"Key created (secret shown once)","content":{"application/json":{"schema":{"type":"object","properties":{"customerId":{"type":"string"},"apiKey":{"type":"string","example":"at_live_..."},"keyPrefix":{"type":"string"},"note":{"type":"string"}}}}}},"401":{"description":"Unauthorized"}}},"get":{"tags":["API Keys"],"summary":"List API keys","description":"Returns all non-revoked API keys for the authenticated customer.","responses":{"200":{"description":"List of API keys","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}},"401":{"description":"Unauthorized"}}}},"/api-keys/{id}":{"delete":{"tags":["API Keys"],"summary":"Revoke an API key","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Key revoked","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"revokedAt":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Key already revoked"},"403":{"description":"Forbidden — key belongs to another customer"},"404":{"description":"Key not found"}}}},"/teams":{"post":{"tags":["Teams"],"summary":"Create a team","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","example":"My Engineering Team"},"goal":{"type":"string","example":"Build and ship software features"},"autonomy":{"type":"string","enum":["supervised","autonomous"],"default":"supervised"}}}}}},"responses":{"201":{"description":"Team created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"401":{"description":"Unauthorized"}}}},"/teams/{id}":{"get":{"tags":["Teams"],"summary":"Get a team","description":"Returns team details including roles, top-level tasks, and running workers.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Team detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamDetail"}}}},"403":{"description":"Forbidden — team belongs to another customer"},"404":{"description":"Team not found"}}},"patch":{"tags":["Teams"],"summary":"Update a team","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"goal":{"type":"string"},"autonomy":{"type":"string","enum":["supervised","autonomous"]},"config":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"Updated team","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"404":{"description":"Team not found"}}}},"/teams/{id}/github-activity":{"get":{"tags":["Teams"],"summary":"Get GitHub activity for a team","description":"Proxies the GitHub API to return recent commits and pull requests for the team's configured repository. Requires `githubToken` and `gitRepoUrl` to be set in the team config (via PATCH /teams/{id}).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent commits and pull requests","content":{"application/json":{"schema":{"type":"object","properties":{"commits":{"type":"array","description":"Recent commits from GitHub API (up to 15)","items":{"type":"object","properties":{"sha":{"type":"string"},"commit":{"type":"object","properties":{"message":{"type":"string"},"author":{"type":"object","properties":{"name":{"type":"string"},"date":{"type":"string","format":"date-time"}}}}},"html_url":{"type":"string","format":"uri"},"author":{"type":"object","nullable":true,"properties":{"login":{"type":"string"},"avatar_url":{"type":"string","format":"uri"}}}}}},"prs":{"type":"array","description":"Recent pull requests from GitHub API (up to 10, sorted by updated desc)","items":{"type":"object","properties":{"number":{"type":"integer"},"title":{"type":"string"},"state":{"type":"string","enum":["open","closed"]},"merged_at":{"type":"string","format":"date-time","nullable":true},"html_url":{"type":"string","format":"uri"},"user":{"type":"object","nullable":true,"properties":{"login":{"type":"string"},"avatar_url":{"type":"string","format":"uri"}}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}}}},"400":{"description":"Team has no GitHub config (missing githubToken or gitRepoUrl)"},"404":{"description":"Team not found"},"502":{"description":"GitHub API error"}}}},"/teams/{id}/playbook":{"get":{"tags":["Teams"],"summary":"Get team playbook","description":"Returns the CEO's operating policies for this team.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Playbook","content":{"application/json":{"schema":{"type":"object","properties":{"teamId":{"type":"string"},"playbook":{"type":"string","nullable":true}}}}}},"404":{"description":"Team not found"}}},"put":{"tags":["Teams"],"summary":"Set team playbook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["playbook"],"properties":{"playbook":{"type":"string"}}}}}},"responses":{"200":{"description":"Playbook saved","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"404":{"description":"Team not found"}}}},"/roles":{"get":{"tags":["Roles"],"summary":"List roles","parameters":[{"name":"teamId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of roles","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Role"}}}}},"400":{"description":"teamId is required"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}}},"post":{"tags":["Roles"],"summary":"Create a role","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["teamId","name","systemPrompt"],"properties":{"teamId":{"type":"string"},"name":{"type":"string","example":"backend-engineer"},"systemPrompt":{"type":"string","example":"You are a senior TypeScript backend engineer..."},"timeout":{"type":"integer","description":"Timeout in seconds","default":600}}}}}},"responses":{"201":{"description":"Role created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Role"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}}}},"/roles/{id}":{"get":{"tags":["Roles"],"summary":"Get a role","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Role"}}}},"404":{"description":"Role not found"}}},"patch":{"tags":["Roles"],"summary":"Update a role","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"systemPrompt":{"type":"string"},"timeout":{"type":"integer"}}}}}},"responses":{"200":{"description":"Updated role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Role"}}}},"404":{"description":"Role not found"}}},"delete":{"tags":["Roles"],"summary":"Delete a role","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"404":{"description":"Role not found"}}}},"/tasks":{"get":{"tags":["Tasks"],"summary":"List tasks","parameters":[{"name":"teamId","in":"query","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","schema":{"$ref":"#/components/schemas/TaskStatus"}},{"name":"role","in":"query","schema":{"type":"string"}},{"name":"parentTaskId","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"List of tasks with subtasks and workers","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TaskDetail"}}}}},"400":{"description":"teamId is required"},"403":{"description":"Forbidden"}}},"post":{"tags":["Tasks"],"summary":"Create a task","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["teamId","title"],"properties":{"teamId":{"type":"string"},"parentTaskId":{"type":"string"},"role":{"type":"string","example":"backend-engineer"},"title":{"type":"string","example":"Build user authentication"},"description":{"type":"string"},"acceptCriteria":{"type":"string"},"status":{"$ref":"#/components/schemas/TaskStatus"},"priority":{"type":"integer","default":0},"dependencies":{"type":"array","items":{"type":"string"}},"input":{},"createdBy":{"type":"string","default":"ceo"}}}}}},"responses":{"201":{"description":"Task created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}}}},"/tasks/{id}":{"get":{"tags":["Tasks"],"summary":"Get a task","description":"Returns task with subtasks, workers, parent task, and recent events.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Task detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskDetail"}}}},"403":{"description":"Forbidden"},"404":{"description":"Task not found"}}},"patch":{"tags":["Tasks"],"summary":"Update a task","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/TaskStatus"},"title":{"type":"string"},"description":{"type":"string"},"output":{},"artifacts":{},"priority":{"type":"integer"}}}}}},"responses":{"200":{"description":"Updated task","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"403":{"description":"Forbidden"},"404":{"description":"Task not found"}}},"delete":{"tags":["Tasks"],"summary":"Cancel a task","description":"Marks task as failed (cancel). Does not delete the record.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Task cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"403":{"description":"Forbidden"},"404":{"description":"Task not found"}}}},"/tasks/{id}/subtasks":{"post":{"tags":["Tasks"],"summary":"Create a subtask","description":"Creates a child task. Used by workers via MCP coordination tools.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Parent task ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"description":{"type":"string"},"role":{"type":"string"},"priority":{"type":"integer","default":0},"createdBy":{"type":"string","default":"worker"}}}}}},"responses":{"201":{"description":"Subtask created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"403":{"description":"Forbidden"},"404":{"description":"Parent task not found"}}}},"/tasks/{id}/run":{"post":{"tags":["Tasks"],"summary":"Spawn a worker for a task","description":"Spawns a Modal worker sandbox for the task. Task must have a role assigned. Returns workerId and sandboxId. Task status transitions to in_progress.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Worker spawned","content":{"application/json":{"schema":{"type":"object","properties":{"workerId":{"type":"string"},"sandboxId":{"type":"string"}}}}}},"400":{"description":"Task has no role assigned, or role not found"},"403":{"description":"Forbidden"},"404":{"description":"Task not found"},"500":{"description":"Failed to spawn worker"}}}},"/tasks/{id}/resume":{"post":{"tags":["Tasks"],"summary":"Resume a failed or timed-out task","description":"Reuses the previous worker's session volume to continue where it left off.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Worker resumed","content":{"application/json":{"schema":{"type":"object","properties":{"workerId":{"type":"string"},"sandboxId":{"type":"string"},"resumed":{"type":"boolean"}}}}}},"400":{"description":"Task has no role assigned"},"403":{"description":"Forbidden"},"404":{"description":"Task not found"}}}},"/events":{"get":{"tags":["Events"],"summary":"List events (activity feed)","description":"Append-only event log. Supports cursor-based pagination.","parameters":[{"name":"teamId","in":"query","required":true,"schema":{"type":"string"}},{"name":"taskId","in":"query","schema":{"type":"string"}},{"name":"type","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50},"description":"Max events to return"},{"name":"cursor","in":"query","schema":{"type":"string","format":"date-time"},"description":"ISO timestamp — return events before this timestamp"}],"responses":{"200":{"description":"Events ordered by timestamp desc","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}}}},"400":{"description":"teamId is required"},"403":{"description":"Forbidden"}}},"post":{"tags":["Events"],"summary":"Create an event","description":"Used by workers via the MCP coordination server to emit progress events.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["teamId","type","actor"],"properties":{"teamId":{"type":"string"},"taskId":{"type":"string"},"workerId":{"type":"string"},"type":{"type":"string","enum":["status_change","message"]},"actor":{"type":"string"},"data":{}}}}}},"responses":{"201":{"description":"Event created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"403":{"description":"Forbidden"}}}},"/workers":{"get":{"tags":["Workers"],"summary":"List workers","parameters":[{"name":"teamId","in":"query","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["starting","running","completed","failed"]}}],"responses":{"200":{"description":"Workers with task info","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkerDetail"}}}}},"400":{"description":"teamId is required"},"403":{"description":"Forbidden"}}}},"/workers/{id}":{"get":{"tags":["Workers"],"summary":"Get a worker","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Worker detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerDetail"}}}},"403":{"description":"Forbidden"},"404":{"description":"Worker not found"}}}},"/webhooks/worker-complete":{"post":{"tags":["Webhooks"],"summary":"Worker completion callback","description":"Called by Modal workers when they finish. Workers authenticate with their service API key (issued at task run time). Marks task done/failed, revokes the service key, and emits a completion event.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["worker_id","task_id","status"],"properties":{"worker_id":{"type":"string"},"task_id":{"type":"string"},"status":{"type":"string","enum":["completed","failed"]},"output":{},"artifacts":{},"error":{"type":"string","nullable":true},"summary":{"type":"string"},"git_pushed":{"type":"boolean"},"git_branch":{"type":"string","nullable":true}}}}}},"responses":{"200":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Invalid payload"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Worker or task not found"}}}},"/docs/getting-started":{"get":{"tags":["Docs"],"summary":"Getting started guide","description":"Returns a comprehensive markdown guide for onboarding. Covers the full flow: registration → API key → team → git → roles → tasks → spawn workers → monitor. Includes curl examples, example role system prompts, and error code reference. No auth required.","security":[],"responses":{"200":{"description":"Markdown guide","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/docs/api-reference":{"get":{"tags":["Docs"],"summary":"API reference (markdown)","description":"Returns a human-readable markdown API reference covering all endpoints with request/response examples. No auth required.","security":[],"responses":{"200":{"description":"Markdown API reference","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/admin/claim-team":{"post":{"tags":["Admin"],"summary":"Claim a legacy team","description":"Claims a team with customerId=NULL for the authenticated customer. Migration helper.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["teamId"],"properties":{"teamId":{"type":"string"}}}}}},"responses":{"200":{"description":"Team claimed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"teamId is required"},"404":{"description":"Team not found"},"409":{"description":"Team already claimed"}}}}},"tags":[{"name":"Registration","description":"Public registration flow — no auth required"},{"name":"API Keys","description":"Manage API keys for your customer account"},{"name":"Teams","description":"Create and manage teams (billing/data scope)"},{"name":"Roles","description":"Define agent roles with system prompts and timeouts"},{"name":"Tasks","description":"Task CRUD, subtask creation, worker spawning"},{"name":"Events","description":"Append-only activity event feed"},{"name":"Workers","description":"Ephemeral Modal worker instances"},{"name":"Webhooks","description":"Authenticated callbacks from running workers"},{"name":"Admin","description":"Administrative utilities"},{"name":"Docs","description":"Human- and agent-readable documentation endpoints (no auth required)"}]}