{"openapi":"3.1.0","info":{"title":"growthos API","version":"0.1.0","description":"Stub spec emitted by Phase 1 scaffold. Phase 2 replaces this with one generated from @hono/zod-openapi."},"paths":{"/health":{"get":{"summary":"Health check","responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","const":"ok"},"uptime_seconds":{"type":"number"},"commit":{"type":"string","nullable":true}},"required":["status","uptime_seconds"]}}}}}}},"/api/v1/agent/conversations":{"get":{"summary":"List agent conversations","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Tenant conversations"}}},"post":{"summary":"Create an agent conversation","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":160}},"additionalProperties":false}}}},"responses":{"201":{"description":"Conversation created"},"400":{"description":"Invalid conversation payload"}}}},"/api/v1/agent/conversations/{id}":{"get":{"summary":"Get an agent conversation","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Conversation"},"404":{"description":"Conversation not found"}}}},"/api/v1/agent/conversations/{id}/messages":{"post":{"summary":"Post a user turn and enqueue an agent run","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","minLength":1,"maxLength":10000},"model":{"type":"string","minLength":1},"toolNames":{"type":"array","items":{"type":"string"}}},"required":["content"],"additionalProperties":false}}}},"responses":{"201":{"description":"Turn accepted and job enqueued"},"400":{"description":"Invalid turn payload"},"404":{"description":"Conversation not found"},"409":{"description":"Conversation not active"}}}},"/api/v1/agent/conversations/{id}/feedback":{"get":{"summary":"List the current users feedback for one agent conversation","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Conversation message feedback","content":{"application/json":{"schema":{"type":"object","properties":{"feedback":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"conversationId":{"type":"string","format":"uuid"},"messageId":{"type":"string"},"jobId":{"type":"string","format":"uuid","nullable":true},"userId":{"type":"string","format":"uuid"},"verdict":{"type":"string","enum":["up","down"]},"correction":{"type":"string","nullable":true},"messageExcerpt":{"type":"string"},"metadata":{"type":"object","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","conversationId","messageId","jobId","userId","verdict","correction","messageExcerpt","metadata","createdAt","updatedAt"]}}},"required":["feedback"]}}}},"401":{"description":"Unauthenticated"},"404":{"description":"Conversation not found"}}},"post":{"summary":"Submit feedback for an assistant message","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"messageId":{"type":"string","minLength":1,"maxLength":200},"verdict":{"type":"string","enum":["up","down"]},"correction":{"type":"string","minLength":1,"maxLength":4000}},"required":["messageId","verdict"],"additionalProperties":false}}}},"responses":{"201":{"description":"Feedback stored","content":{"application/json":{"schema":{"type":"object","properties":{"feedback":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"conversationId":{"type":"string","format":"uuid"},"messageId":{"type":"string"},"jobId":{"type":"string","format":"uuid","nullable":true},"userId":{"type":"string","format":"uuid"},"verdict":{"type":"string","enum":["up","down"]},"correction":{"type":"string","nullable":true},"messageExcerpt":{"type":"string"},"metadata":{"type":"object","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","conversationId","messageId","jobId","userId","verdict","correction","messageExcerpt","metadata","createdAt","updatedAt"]}},"required":["feedback"]}}}},"400":{"description":"Invalid feedback payload or non-assistant message"},"401":{"description":"Unauthenticated"},"404":{"description":"Conversation or message not found"},"500":{"description":"Feedback insert failed"}}}},"/api/v1/agent/feedback":{"get":{"summary":"List tenant agent message feedback","security":[{"bearerAuth":[]}],"parameters":[{"name":"verdict","in":"query","required":false,"schema":{"type":"string","enum":["up","down"]}},{"name":"since","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"Tenant feedback rows","content":{"application/json":{"schema":{"type":"object","properties":{"feedback":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"conversationId":{"type":"string","format":"uuid"},"messageId":{"type":"string"},"jobId":{"type":"string","format":"uuid","nullable":true},"userId":{"type":"string","format":"uuid"},"verdict":{"type":"string","enum":["up","down"]},"correction":{"type":"string","nullable":true},"messageExcerpt":{"type":"string"},"metadata":{"type":"object","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","conversationId","messageId","jobId","userId","verdict","correction","messageExcerpt","metadata","createdAt","updatedAt"]}}},"required":["feedback"]}}}},"400":{"description":"Invalid feedback query"},"401":{"description":"Unauthenticated"}}}},"/api/v1/agent/jobs/{id}/trace":{"get":{"summary":"Get an agent job trace","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Trace spans for the job","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","additionalProperties":true},"spans":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["job","spans"]}}}},"401":{"description":"Unauthenticated"},"404":{"description":"Job not found"},"500":{"description":"Trace query failed"}}}},"/api/v1/agent/jobs/{id}":{"get":{"summary":"Get an agent job detail, including steps, approvals, and child jobs","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Agent job detail","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","additionalProperties":true},"steps":{"type":"array","items":{"type":"object","additionalProperties":true}},"approvals":{"type":"array","items":{"type":"object","additionalProperties":true}},"children":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["job","steps","approvals","children"]}}}},"401":{"description":"Unauthenticated"},"404":{"description":"Job not found"}}}},"/api/v1/agent/jobs/{id}/cancel":{"post":{"summary":"Cancel an agent job and any non-terminal children","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Cancellation accepted"},"401":{"description":"Unauthenticated"},"404":{"description":"Job not found"}}}},"/api/v1/agent/approvals":{"get":{"summary":"List agent approvals","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","approved","rejected"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Tenant approvals","content":{"application/json":{"schema":{"type":"object","properties":{"approvals":{"type":"array","items":{"type":"object","additionalProperties":true,"properties":{"job":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"goal":{"type":"string"}},"required":["id","goal"]},{"type":"null"}]}}}}},"required":["approvals"]}}}},"400":{"description":"Invalid approval list query"},"401":{"description":"Unauthenticated"}}}},"/api/v1/agent/usage":{"get":{"summary":"Get tenant agent usage and budget limits","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Agent usage summary","content":{"application/json":{"schema":{"type":"object","properties":{"limits":{"type":"object","properties":{"tokens_day":{"type":"integer"},"tokens_month":{"type":"integer"},"cost_usd_cents_month":{"type":"integer"},"tool_calls_hour":{"type":"integer"},"max_steps":{"type":"integer"}},"required":["tokens_day","tokens_month","cost_usd_cents_month","tool_calls_hour","max_steps"]},"usage":{"type":"object","properties":{"tokens_day":{"type":"integer"},"tokens_month":{"type":"integer"},"cost_usd_cents_month":{"type":"integer"}},"required":["tokens_day","tokens_month","cost_usd_cents_month"]},"remaining":{"type":"object","properties":{"tokens_day":{"type":"integer","nullable":true},"tokens_month":{"type":"integer","nullable":true},"cost_usd_cents_month":{"type":"integer","nullable":true}},"required":["tokens_day","tokens_month","cost_usd_cents_month"]},"tools_hour":{"type":"array","items":{"type":"object","properties":{"tool":{"type":"string"},"calls":{"type":"integer"},"limit":{"type":"integer"}},"required":["tool","calls","limit"]}},"cost_is_estimated":{"type":"boolean"}},"required":["limits","usage","remaining","tools_hour","cost_is_estimated"]}}}},"401":{"description":"Unauthenticated"}}}},"/api/v1/agent/analytics":{"get":{"summary":"Get tenant agent analytics","security":[{"bearerAuth":[]}],"parameters":[{"name":"window","in":"query","required":false,"schema":{"type":"string","enum":["7d","30d"],"default":"7d"}}],"responses":{"200":{"description":"Agent analytics summary","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"window":{"type":"string","enum":["7d","30d"]},"generated_at":{"type":"string","format":"date-time"},"tasks":{"type":"object","properties":{"completed":{"type":"integer"},"failed":{"type":"integer"},"cancelled":{"type":"integer"},"running":{"type":"integer"},"by_day":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"completed":{"type":"integer"},"failed":{"type":"integer"}},"required":["date","completed","failed"]}}},"required":["completed","failed","cancelled","running","by_day"]},"actions":{"type":"object","properties":{"total":{"type":"integer"},"by_tool":{"type":"array","items":{"type":"object","properties":{"tool":{"type":"string"},"module":{"type":"string"},"calls":{"type":"integer"}},"required":["tool","module","calls"]}},"by_module":{"type":"array","items":{"type":"object","properties":{"module":{"type":"string"},"calls":{"type":"integer"}},"required":["module","calls"]}}},"required":["total","by_tool","by_module"]},"cost":{"type":"object","properties":{"usd_cents":{"type":"integer"},"input_tokens":{"type":"integer"},"output_tokens":{"type":"integer"},"is_estimated":{"type":"boolean","const":true}},"required":["usd_cents","input_tokens","output_tokens","is_estimated"]},"approvals":{"type":"object","properties":{"pending":{"type":"integer"},"items":{"type":"array","maxItems":10,"items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"job_id":{"type":"string","format":"uuid"},"tool_name":{"type":"string"},"goal":{"type":"string"},"created_at":{"type":"string","format":"date-time"}},"required":["id","job_id","tool_name","goal","created_at"]}}},"required":["pending","items"]}},"required":["window","generated_at","tasks","actions","cost","approvals"]}}}},"400":{"description":"Invalid analytics window"},"401":{"description":"Unauthenticated"}}}},"/api/v1/agent/tasks":{"get":{"summary":"List structured agent tasks","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["queued","running","completed","failed","cancelled"]}}],"responses":{"200":{"description":"Tenant structured tasks"},"401":{"description":"Unauthenticated"}}},"post":{"summary":"Create and enqueue a structured agent task","security":[{"bearerAuth":[]}],"x-task-types":[{"type":"extract_action_items","description":"Extract concise action items from free text.","tier":"fast","maxAttempts":null},{"type":"classify_text","description":"Classify text into one of the caller-provided labels.","tier":"fast","maxAttempts":null}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"taskType":{"type":"string","minLength":1,"maxLength":80},"input":{"type":"object","additionalProperties":true},"tier":{"type":"string","enum":["fast","reasoning"]},"model":{"type":"string","minLength":1},"maxAttempts":{"type":"integer","minimum":1,"maximum":5}},"required":["taskType","input"],"additionalProperties":false}}}},"responses":{"201":{"description":"Structured task created and enqueued"},"400":{"description":"Invalid task payload"},"401":{"description":"Unauthenticated"},"500":{"description":"Task enqueue failed"}}}},"/api/v1/agent/tasks/{id}":{"get":{"summary":"Get structured agent task detail","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Structured task detail","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"object","additionalProperties":true}},"required":["task"]}}}},"401":{"description":"Unauthenticated"},"404":{"description":"Task not found"}}}},"/api/v1/agent/tasks/{id}/cancel":{"post":{"summary":"Cancel a queued structured agent task","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Cancellation accepted or task already terminal"},"401":{"description":"Unauthenticated"},"404":{"description":"Task not found"},"409":{"description":"Task is already running"}}}},"/api/v1/channels":{"get":{"summary":"List channel adapters and tenant connections","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Channel adapters and connections"},"401":{"description":"Unauthenticated"}}},"post":{"summary":"Create a channel connection","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"channel":{"type":"string","enum":["email","slack","whatsapp","sms","dev"]},"routingKey":{"type":"string"},"displayName":{"type":"string"},"senderPolicy":{"type":"string","enum":["members","anyone"]},"config":{"type":"object","additionalProperties":true},"credentials":{"type":"object","additionalProperties":true}},"required":["channel","routingKey"]}}}},"responses":{"201":{"description":"Channel connection created"},"400":{"description":"Invalid payload"},"401":{"description":"Unauthenticated"},"409":{"description":"Channel or routing key already connected"}}}},"/api/v1/channels/{id}":{"patch":{"summary":"Update a channel connection","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Channel connection updated"},"400":{"description":"Invalid payload"},"401":{"description":"Unauthenticated"},"404":{"description":"Channel connection not found"}}},"delete":{"summary":"Delete a channel connection","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Channel connection deleted"},"401":{"description":"Unauthenticated"},"404":{"description":"Channel connection not found"}}}},"/webhooks/channels/{channel}":{"post":{"summary":"Receive signed inbound channel webhooks","parameters":[{"name":"channel","in":"path","required":true,"schema":{"type":"string","enum":["email","slack","whatsapp","sms","dev"]}}],"responses":{"200":{"description":"Inbound message handled"},"401":{"description":"Invalid signature"},"404":{"description":"Unknown channel"},"503":{"description":"Channel adapter unconfigured"}}}},"/api/v1/agent/playbooks":{"get":{"summary":"List tenant agent playbooks","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","archived"]}}],"responses":{"200":{"description":"Tenant playbooks"},"401":{"description":"Unauthenticated"}}},"post":{"summary":"Create a playbook with version 1 active","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,63}$"},"name":{"type":"string","minLength":1,"maxLength":160},"description":{"type":"string","maxLength":500},"content":{"type":"string","minLength":1,"maxLength":20000},"pinned":{"type":"boolean"}},"required":["slug","name","content"],"additionalProperties":false}}}},"responses":{"201":{"description":"Playbook created"},"400":{"description":"Invalid playbook payload"},"409":{"description":"Slug already exists"}}}},"/api/v1/agent/playbooks/{id}":{"get":{"summary":"Get a playbook and all versions","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Playbook detail"},"404":{"description":"Playbook not found"}}},"patch":{"summary":"Update playbook metadata","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":160},"description":{"type":"string","maxLength":500},"pinned":{"type":"boolean"},"status":{"type":"string","enum":["active","archived"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"Playbook updated"},"400":{"description":"Invalid playbook payload"},"404":{"description":"Playbook not found"}}}},"/api/v1/agent/playbooks/{id}/versions":{"post":{"summary":"Create a draft playbook version","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","minLength":1,"maxLength":20000},"rationale":{"type":"string","maxLength":2000}},"required":["content"],"additionalProperties":false}}}},"responses":{"201":{"description":"Draft version created"},"400":{"description":"Invalid version payload"},"404":{"description":"Playbook not found"}}}},"/api/v1/agent/playbooks/{id}/versions/{versionId}/activate":{"post":{"summary":"Activate a draft or retired playbook version","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"versionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Version activated"},"400":{"description":"Version not activatable"},"404":{"description":"Playbook or version not found"}}}},"/api/v1/agent/playbooks/{id}/versions/{versionId}/reject":{"post":{"summary":"Reject a draft playbook version","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"versionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Version rejected"},"400":{"description":"Version not rejectable"},"404":{"description":"Playbook or version not found"}}}},"/api/v1/actions/{name}":{"post":{"summary":"Execute a registered capability","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"x-capabilities":[{"name":"get_current_time","description":"Returns the current date and time as an ISO-8601 UTC timestamp. Use when you need to know the current moment.","module":"agent","policy":{"tenancy":"system","mutating":false}},{"name":"fetch_url","description":"Fetches a URL and returns its HTTP status plus a short text preview. Hosts outside the built-in allow-list (example.com, example.org, httpbin.org) require human approval before the request is sent.","module":"agent","policy":{"tenancy":"tenant","mutating":false,"requiresApproval":false,"untrustedOutput":true}},{"name":"remember","description":"Persist a concise tenant/user preference or fact that should influence future agent runs.","module":"agent","policy":{"tenancy":"user","mutating":true,"requiresApproval":false}},{"name":"search_memories","description":"Search durable tenant/user memories for facts or preferences relevant to the current task.","module":"agent","policy":{"tenancy":"user","mutating":false,"requiresApproval":false}},{"name":"list_playbooks","description":"List tenant playbooks the agent can follow, including whether each has an active version.","module":"agent","policy":{"tenancy":"tenant","mutating":false,"requiresApproval":false}},{"name":"read_playbook","description":"Read the active content for a tenant playbook by slug.","module":"agent","policy":{"tenancy":"tenant","mutating":false,"requiresApproval":false}},{"name":"propose_playbook_update","description":"Create an inert draft playbook version for human review. Existing active playbooks are not changed until a human activates the draft.","module":"agent","policy":{"tenancy":"tenant","mutating":true,"requiresApproval":false}},{"name":"schedule_task","description":"Schedule a UTC follow-up for the agent. Use once for reminders or follow-ups, and cron for recurring digests. Convert user-local times to UTC before calling. Scheduled runs cannot create more schedules.","module":"agent","policy":{"tenancy":"user","mutating":true,"requiresApproval":false}},{"name":"list_scheduled_tasks","description":"List the tenant scheduled agent tasks, enabled tasks first by next run time.","module":"agent","policy":{"tenancy":"tenant","mutating":false}},{"name":"cancel_scheduled_task","description":"Cancel one scheduled agent task by id. This only affects the current tenant.","module":"agent","policy":{"tenancy":"user","mutating":true,"requiresApproval":false}},{"name":"create_webhook_rule","description":"Create a signed inbound webhook rule that runs the agent when an external system posts events. Return the endpoint path and one-time secret to the user so they can paste them into the external system.","module":"agent","policy":{"tenancy":"user","mutating":true,"requiresApproval":false}},{"name":"list_webhook_rules","description":"List masked inbound webhook rules for this tenant.","module":"agent","policy":{"tenancy":"tenant","mutating":false}},{"name":"delegate","description":"Delegate a self-contained sub-task to a sub-agent with a restricted tool list. Use for research, draft, or verify steps that need many tool calls. You pause until it finishes and receive its final answer as this tool result.","module":"agent","policy":{"tenancy":"user","mutating":true,"requiresApproval":false}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Capability executed successfully"},"400":{"description":"Invalid capability args"},"404":{"description":"Capability not found"},"409":{"description":"Capability requires approval"},"422":{"description":"Capability returned an error"}}}},"/api/v1/documents":{"get":{"summary":"List tenant documents","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Tenant documents"}}},"post":{"summary":"Create a tenant document and enqueue ingest","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"fileName":{"type":"string","minLength":1,"maxLength":240},"mimeType":{"type":"string","enum":["text/plain","text/markdown"]},"content":{"type":"string","minLength":1},"metadata":{"type":"object","additionalProperties":true}},"required":["fileName","content"],"additionalProperties":false}}}},"responses":{"201":{"description":"Document created"},"400":{"description":"Invalid document payload"},"409":{"description":"Duplicate or tenant document limit reached"},"500":{"description":"Document enqueue failed"}}}},"/api/v1/documents/{id}":{"get":{"summary":"Get a tenant document","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Document"},"404":{"description":"Document not found"}}},"delete":{"summary":"Delete a tenant document","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Document deleted"},"404":{"description":"Document not found"}}}},"/api/v1/documents/{id}/retry":{"post":{"summary":"Retry a failed document ingest","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Document ingest retry enqueued"},"404":{"description":"Document not found"},"409":{"description":"Document is not failed"}}}},"/api/v1/artifacts":{"get":{"summary":"List tenant artifacts","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Tenant artifacts","content":{"application/json":{"schema":{"type":"object","properties":{"artifacts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"jobId":{"type":"string","format":"uuid","nullable":true},"conversationId":{"type":"string","format":"uuid","nullable":true},"createdByUserId":{"type":"string","format":"uuid","nullable":true},"source":{"type":"string","enum":["capability","sandbox","browser"]},"kind":{"type":"string","enum":["report","data","chart","image","screenshot","other"]},"fileName":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"metadata":{"type":"object","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"deletedAt":{"type":"string","format":"date-time","nullable":true}},"required":["id","tenantId","jobId","conversationId","createdByUserId","source","kind","fileName","mimeType","byteSize","sha256","metadata","createdAt","deletedAt"]}},"nextCursor":{"type":"string","format":"date-time","nullable":true}},"required":["artifacts","nextCursor"]}}}},"401":{"description":"Unauthenticated"}}}},"/api/v1/artifacts/{id}":{"get":{"summary":"Get a tenant artifact and active shares","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Artifact detail","content":{"application/json":{"schema":{"type":"object","properties":{"artifact":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"jobId":{"type":"string","format":"uuid","nullable":true},"conversationId":{"type":"string","format":"uuid","nullable":true},"createdByUserId":{"type":"string","format":"uuid","nullable":true},"source":{"type":"string","enum":["capability","sandbox","browser"]},"kind":{"type":"string","enum":["report","data","chart","image","screenshot","other"]},"fileName":{"type":"string"},"mimeType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"metadata":{"type":"object","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"deletedAt":{"type":"string","format":"date-time","nullable":true}},"required":["id","tenantId","jobId","conversationId","createdByUserId","source","kind","fileName","mimeType","byteSize","sha256","metadata","createdAt","deletedAt"]},"shares":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"artifactId":{"type":"string","format":"uuid"},"expiresAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}},"required":["id","artifactId","expiresAt","revokedAt","createdAt"]}}},"required":["artifact","shares"]}}}},"404":{"description":"Artifact not found"}}},"delete":{"summary":"Soft-delete a tenant artifact and revoke its shares","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Artifact deleted"},"404":{"description":"Artifact not found"}}}},"/api/v1/artifacts/{id}/download":{"get":{"summary":"Download a tenant artifact as an attachment","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Artifact bytes","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Artifact not found"}}}},"/api/v1/artifacts/{id}/shares":{"post":{"summary":"Create a public artifact share token","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"expiresInDays":{"type":"integer","minimum":1,"maximum":90,"default":7}},"additionalProperties":false}}}},"responses":{"201":{"description":"Share created; raw token is returned once","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"artifactId":{"type":"string","format":"uuid"},"expiresAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}},"required":["id","artifactId","expiresAt","revokedAt","createdAt"]},"token":{"type":"string"},"url":{"type":"string","format":"uri"}},"required":["share","token"]}}}},"404":{"description":"Artifact not found"}}}},"/api/v1/artifacts/{id}/shares/{shareId}":{"delete":{"summary":"Revoke an artifact share token","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"shareId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Share revoked"},"404":{"description":"Share not found"}}}},"/api/v1/artifacts/shared/{token}":{"get":{"summary":"Download an artifact through a public share token","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Artifact bytes","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Share or artifact not found"}}}},"/api/v1/mcp":{"post":{"summary":"MCP Streamable HTTP endpoint","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"MCP JSON-RPC response or stream"},"401":{"description":"Missing or invalid API key"},"403":{"description":"API key missing mcp:use scope"}}},"get":{"summary":"MCP Streamable HTTP SSE endpoint","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"MCP SSE stream"},"401":{"description":"Missing or invalid API key"},"403":{"description":"API key missing mcp:use scope"}}},"delete":{"summary":"Terminate an MCP Streamable HTTP session","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"MCP session terminated"},"401":{"description":"Missing or invalid API key"},"403":{"description":"API key missing mcp:use scope"}}}},"/api/v1/mcp/servers":{"get":{"summary":"List external MCP servers for the tenant","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"External MCP server configs without secrets"}}},"post":{"summary":"Create an external MCP server config","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"transport":{"type":"string","enum":["streamable_http","stdio"]},"url":{"type":"string","format":"uri"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"headers":{"type":"object","additionalProperties":{"type":"string"}},"env":{"type":"object","additionalProperties":{"type":"string"}},"toolPrefix":{"type":"string","pattern":"^[a-z][a-z0-9_]*$"},"enabled":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":true}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"External MCP server config created"},"400":{"description":"Invalid MCP server config"}}}},"/api/v1/mcp/servers/{id}":{"delete":{"summary":"Delete an external MCP server config","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"External MCP server config deleted"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}}}}