{"openapi":"3.1.0","info":{"title":"Minabot Public API","description":"Read-only REST API for querying sessions and knowledge articles. Requires an API key issued from the Admina admin panel.\n\n### Rate limits\nNot currently enforced at the HTTP layer. Respect upstream DynamoDB capacity when making bulk requests (keep concurrency under ~20 RPS per key).","version":"1.0.0","contact":{"name":"Minabot","url":"https://github.com/moneyforward-i/minabot"}},"servers":[{"url":"https://assist.i.moneyforward.com","description":"Production"}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API key created via the Admina admin panel (`Settings → API Keys → Create`). Format: `mb_live_<40-hex>`."}}},"security":[{"ApiKeyAuth":[]}],"paths":{"/api/v1/sessions/stats":{"get":{"operationId":"getApiV1SessionsStats","tags":["Sessions"],"summary":"Session statistics","description":"Counts grouped by status and assignee type.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Stats","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"stats":{"type":"object","properties":{"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"byStatus":{"type":"object","properties":{"open":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"in_progress":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pending_approval":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"resolved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["open","in_progress","pending_approval","resolved"]},"byAssigneeType":{"type":"object","properties":{"unassigned":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"ai_agent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"human_agent":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"requester":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["unassigned","ai_agent","human_agent","requester"]}},"required":["total","byStatus","byAssigneeType"]}},"required":["ok","stats"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}}}},"/api/v1/sessions/{sessionKey}":{"get":{"operationId":"getApiV1SessionsBySessionKey","tags":["Sessions"],"summary":"Get session by key","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Session","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"session":{"type":"object","properties":{"sessionKey":{"type":"string","description":"Composite key: channelId:threadTs"},"ticketNumber":{"description":"Tenant-scoped auto-increment ticket number. Stable, operator-facing.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"channelId":{"type":"string"},"threadTs":{"type":"string"},"status":{"type":"string","enum":["open","in_progress","pending_approval","resolved"]},"assigneeType":{"type":"string","enum":["unassigned","ai_agent","human_agent","requester"]},"title":{"type":"string"},"summary":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"closedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"closeReason":{"type":"string"},"messageCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"requesterId":{"type":"string"},"assignedUserId":{"type":"string"}},"required":["sessionKey","channelId","threadTs","status","assigneeType","createdAt","updatedAt"],"description":"Support session / ticket (tenantId stripped)"}},"required":["ok","session"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}},"parameters":[{"in":"path","name":"sessionKey","schema":{"type":"string"},"required":true,"description":"Composite key like `C123:1700000000.000001`"}]}},"/api/v1/sessions":{"get":{"operationId":"getApiV1Sessions","tags":["Sessions"],"summary":"List sessions","description":"Returns support sessions for the authenticated tenant. Optional filters by status and assignee type.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Session list","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"sessions":{"type":"array","items":{"type":"object","properties":{"sessionKey":{"type":"string","description":"Composite key: channelId:threadTs"},"ticketNumber":{"description":"Tenant-scoped auto-increment ticket number. Stable, operator-facing.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"channelId":{"type":"string"},"threadTs":{"type":"string"},"status":{"type":"string","enum":["open","in_progress","pending_approval","resolved"]},"assigneeType":{"type":"string","enum":["unassigned","ai_agent","human_agent","requester"]},"title":{"type":"string"},"summary":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"closedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"closeReason":{"type":"string"},"messageCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"requesterId":{"type":"string"},"assignedUserId":{"type":"string"}},"required":["sessionKey","channelId","threadTs","status","assigneeType","createdAt","updatedAt"],"description":"Support session / ticket (tenantId stripped)"}},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["ok","sessions","count"]}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}},"parameters":[{"in":"query","name":"status","schema":{"type":"string","enum":["open","in_progress","pending_approval","resolved"]},"description":"Filter by status (pushed to DynamoDB — accurate)"},{"in":"query","name":"assigneeType","schema":{"type":"string","enum":["unassigned","ai_agent","human_agent","requester"]},"description":"Filter by assignee. NOTE: this filter is applied in-memory AFTER `limit` is enforced at the database layer, so when `assigneeType` is set the `count` in the response reflects matches within the first `limit` rows only — not the tenant-wide total. For exhaustive enumeration, call without `assigneeType` and filter client-side."},{"in":"query","name":"limit","schema":{"default":50,"type":"number","minimum":1,"maximum":100},"description":"Max results — 1..100, default 50"}]}},"/api/v1/knowledge/{docId}":{"get":{"operationId":"getApiV1KnowledgeByDocId","tags":["Knowledge"],"summary":"Get knowledge article (with content)","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Full article with markdown body","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"article":{"type":"object","properties":{"docId":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"category":{"type":"string"},"type":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"content":{"type":"string","description":"Full markdown body"}},"required":["docId","title","createdAt","updatedAt","content"]}},"required":["ok","article"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}},"parameters":[{"in":"path","name":"docId","schema":{"type":"string"},"required":true,"description":"Knowledge article ID from list endpoint"}]}},"/api/v1/knowledge":{"get":{"operationId":"getApiV1Knowledge","tags":["Knowledge"],"summary":"List knowledge articles","description":"Returns knowledge article summaries (without full content). Optional filters by category and type.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Article summaries","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"articles":{"type":"array","items":{"type":"object","properties":{"docId":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"category":{"type":"string"},"type":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["docId","title","createdAt","updatedAt"],"description":"Knowledge article summary (without content)"}},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["ok","articles","count"]}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}},"parameters":[{"in":"query","name":"category","schema":{"type":"string"},"description":"Filter by category (pushed to DynamoDB — accurate)"},{"in":"query","name":"type","schema":{"type":"string"},"description":"Filter by knowledge type. NOTE: this filter is applied in-memory AFTER `limit` is enforced at the database layer, so when `type` is set the `count` in the response reflects matches within the first `limit` rows only — not the tenant-wide total. For exhaustive enumeration, call without `type` and filter client-side."},{"in":"query","name":"limit","schema":{"default":50,"type":"number","minimum":1,"maximum":100}}]}},"/api/v1/procedures/{typePath}":{"get":{"operationId":"getApiV1ProceduresByTypePath","tags":["Procedures"],"summary":"Get procedure (with content) by typePath","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Procedure with full markdown content","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"procedure":{"type":"object","properties":{"typePath":{"type":"string","description":"Composite key used to get the full procedure"},"type":{"type":"string","description":"Instruction type — always 'procedure' here"},"path":{"type":"string","description":"Filename — last path segment"},"description":{"type":"string"},"category":{"type":"string"},"subcategory":{"type":"string"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"proposalCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"content":{"type":"string","description":"Full procedure markdown body"}},"required":["typePath","type","path","updatedAt","proposalCount","content"]}},"required":["ok","procedure"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}},"parameters":[{"in":"path","name":"typePath","schema":{"type":"string"},"required":true,"description":"URL-encoded typePath — e.g. `procedure%23skills/triage/procedures/foo.md`"}]}},"/api/v1/procedures":{"get":{"operationId":"getApiV1Procedures","tags":["Procedures"],"summary":"List procedures","description":"Procedures are tenant-scoped triage skill documents. Returns summaries without content.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Procedure summaries","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"procedures":{"type":"array","items":{"type":"object","properties":{"typePath":{"type":"string","description":"Composite key used to get the full procedure"},"type":{"type":"string","description":"Instruction type — always 'procedure' here"},"path":{"type":"string","description":"Filename — last path segment"},"description":{"type":"string"},"category":{"type":"string"},"subcategory":{"type":"string"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"proposalCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["typePath","type","path","updatedAt","proposalCount"],"description":"Procedure summary without content"}},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["ok","procedures","count"]}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}},"parameters":[{"in":"query","name":"limit","schema":{"default":200,"type":"number","minimum":1,"maximum":500},"description":"Max results — 1..500, default 200"}]}},"/api/v1/settings/agent":{"get":{"operationId":"getApiV1SettingsAgent","tags":["Settings"],"summary":"Get agent settings (ADMIN only)","description":"Escalation fallback user IDs are stripped — only names are returned.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Agent settings","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"settings":{"type":"object","properties":{"tenantId":{"type":"string"},"notificationSettings":{"type":"object","properties":{"sessionResolved":{"type":"boolean"},"sessionAutoResolved":{"type":"boolean"}},"required":["sessionResolved","sessionAutoResolved"]},"escalationFallback":{"type":"object","properties":{"users":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"description":"Escalation fallback users — IDs are stripped for public API"}},"required":["users"]},"sessionLifecycle":{"type":"object","properties":{"reminderThresholdHours":{"type":"number"},"autoCloseThresholdHours":{"type":"number"},"autoCloseEnabled":{"type":"boolean"}},"required":["reminderThresholdHours","autoCloseThresholdHours","autoCloseEnabled"]},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["tenantId","notificationSettings","escalationFallback"]}},"required":["ok","settings"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"403":{"description":"API key lacks ADMIN role","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}}}},"/api/v1/settings/admin":{"get":{"operationId":"getApiV1SettingsAdmin","tags":["Settings"],"summary":"Get admin settings + team members (ADMIN only)","description":"Team member emails, linked accounts, and `updatedBy` are stripped.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Admin settings + sanitized team members","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"settings":{"type":"object","properties":{"systemLanguage":{"type":"string","enum":["en","ja"]},"dmEnabled":{"type":"boolean"},"organizationPrompt":{"default":"","description":"Organization-wide prompt injected between SYSTEM and BOT_SPECIFIC layers","type":"string"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["systemLanguage","dmEnabled"]},"teamMembers":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"image":{"anyOf":[{"type":"string"},{"type":"null"}]},"roles":{"type":"string","description":"JSON-encoded array of roles (e.g. '[\"ADMIN\"]')"}},"required":["userId","name","roles"]}}},"required":["ok","settings","teamMembers"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"403":{"description":"API key lacks ADMIN role","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}}}},"/api/v1/integrations/{integrationId}/tools":{"get":{"operationId":"getApiV1IntegrationsByIntegrationIdTools","tags":["Integrations"],"summary":"List MCP tools for an integration","description":"Connects to the MCP server (template command + tenant env) and returns the advertised tool list with enabled state.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Tools with enabled flags","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"tools":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"}},"required":["name"]}},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["ok","tools","count"]}}}},"400":{"description":"Integration has no command configured","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"404":{"description":"Integration not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}},"parameters":[{"in":"path","name":"integrationId","schema":{"type":"string"},"required":true,"description":"MCP server name (e.g. `admina`)"}]}},"/api/v1/integrations/{integrationId}":{"get":{"operationId":"getApiV1IntegrationsByIntegrationId","tags":["Integrations"],"summary":"Get integration (no credentials)","description":"The `env` credential map is intentionally not returned — use `hasCredentials` to know if it is populated.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Integration summary without credential values","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"integration":{"type":"object","properties":{"name":{"type":"string"},"enabled":{"type":"boolean"},"description":{"type":"string"},"hasCredentials":{"type":"boolean"}},"required":["name","enabled","hasCredentials"]}},"required":["ok","integration"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"404":{"description":"Integration not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}},"parameters":[{"in":"path","name":"integrationId","schema":{"type":"string"},"required":true,"description":"MCP server name (e.g. `admina`)"}]}},"/api/v1/integrations":{"get":{"operationId":"getApiV1Integrations","tags":["Integrations"],"summary":"List integrations","description":"Returns all MCP integrations available to the tenant (template + overrides).","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Integration summaries","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"integrations":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"enabled":{"type":"boolean"},"hasCredentials":{"type":"boolean","description":"True if at least one env credential is populated"}},"required":["name","enabled","hasCredentials"]}},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["ok","integrations","count"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}}}},"/api/v1/notifications/unread-count":{"get":{"operationId":"getApiV1NotificationsUnreadCount","tags":["Notifications"],"summary":"Count unread notifications (tenant-wide, ADMIN only)","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Unread count","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["ok","count"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"403":{"description":"API key lacks ADMIN role","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}}}},"/api/v1/notifications":{"get":{"operationId":"getApiV1Notifications","tags":["Notifications"],"summary":"List notifications (tenant-wide, ADMIN only)","description":"Returns the newest notifications across all users in the tenant.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Notification list","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"notifications":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"type":{"type":"string"},"priority":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"sessionKey":{"anyOf":[{"type":"string"},{"type":"null"}]},"sessionTitle":{"anyOf":[{"type":"string"},{"type":"null"}]},"actorName":{"anyOf":[{"type":"string"},{"type":"null"}]},"isRead":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","userId","type","priority","title","description","isRead","createdAt"]}},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["ok","notifications","count"]}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}},"403":{"description":"API key lacks ADMIN role","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message"}},"required":["ok","error"]}}}}},"parameters":[{"in":"query","name":"limit","schema":{"default":20,"type":"number","minimum":1,"maximum":100},"description":"Max results — 1..100, default 20"}]}}}}