{"openapi":"3.1.0","info":{"title":"Dictiva API","version":"1.0.0","description":"Programmatic access to governance data — statements, assemblies, glossary, controls, regulations, and more.\n\n## Authentication\nAuthenticate via API key (Bearer token) or browser session cookie.\n\n## Versioning\nAll public API endpoints are available under `/api/v1/`. For example: `GET /api/v1/statements`.\nUnversioned paths (`/api/statements`) continue to work as aliases.\nInternal routes (`/api/auth/*`, `/api/health/*`) are not versioned.\n\n## Rate Limiting\nAPI key-authenticated requests are rate-limited per key using a fixed-window counter (60-second window):\n\n| Plan Tier | Requests per Minute |\n|-----------|-------------------|\n| Community (free) | 5 |\n| Professional | 20 |\n| Business | 100 |\n| Enterprise | 500 |\n\nRate limit headers are included in every API key-authenticated response:\n- `X-RateLimit-Limit` — maximum requests allowed per window\n- `X-RateLimit-Remaining` — requests remaining in the current window\n- `X-RateLimit-Reset` — Unix timestamp (seconds) when the window resets\n- `X-RateLimit-Window` — window duration in seconds (60)\n\nWhen the limit is exceeded, the API returns `429 Too Many Requests` with a `Retry-After` header.\nSession-based (browser) requests are exempt from rate limiting.\n\n## MCP Agent Access\nAgent endpoints under `/agent/*` require the `mcp_access` entitlement, available on Business and Enterprise plans.\nRequests without the required entitlement receive a `403 Forbidden` response with `reason: \"mcp_access_required\"`.\nMCP requests are metered separately from standard API requests.\n\n---\n\n*Patent Pending.*","contact":{"name":"Dictiva","url":"https://dictiva.com"}},"servers":[{"url":"{baseUrl}/api/v1","description":"Versioned API (recommended)","variables":{"baseUrl":{"default":"http://localhost:3100","description":"Base URL of the Dictiva instance"}}},{"url":"{baseUrl}/api","description":"Unversioned API (alias)","variables":{"baseUrl":{"default":"http://localhost:3100","description":"Base URL of the Dictiva instance"}}}],"security":[{"bearerAuth":[]},{"cookieAuth":[]}],"tags":[{"name":"Statements","description":"Governance statements — CRUD, search, lifecycle transitions"},{"name":"Policies & Standards","description":"Policy assemblies — collections of pinned statement versions"},{"name":"Actions","description":"Task inbox — action items for review, acknowledgement, etc."},{"name":"Glossary","description":"Tenant glossary — terms, relationships, external links"},{"name":"Library","description":"Unified content library — statements, glossary, regulations"},{"name":"Regulations","description":"Regulation registry — requirements, mappings, annotations"},{"name":"Settings","description":"Tenant settings — API keys, tags, members, domains"},{"name":"Auth","description":"Authentication — sign-in method resolution, SSO routing"},{"name":"Health","description":"Health checks — liveness, readiness, service status"},{"name":"Billing","description":"Billing — checkout, portal, usage, credit packs"},{"name":"Agent","description":"Agent API — machine-readable governance bundles, ontology, and policy search for AI agents"},{"name":"Platform Admin","description":"Platform admin endpoints — tenant management, plan overrides, credit adjustments, trial extensions"},{"name":"Releases","description":"Release version management — changelog, version tracking, auto-generation"},{"name":"Invitation Requests","description":"Early access — public invitation request submission"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key authentication. Pass your key as `Authorization: Bearer dv_live_...`. Keys are created in Settings → API Keys. Each key is scoped to specific read permissions (e.g. `statement:read`, `glossary:read`)."},"cookieAuth":{"type":"apiKey","in":"cookie","name":"better-auth.session_token","description":"Browser session cookie (set automatically on login)."}},"schemas":{"ValidationError":{"type":"object","properties":{"error":{"type":"string","example":"Validation failed"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"}]}},"message":{"type":"string"},"code":{"type":"string"}},"required":["path","message","code"]}}},"required":["error","details"]},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","example":"Not found"}},"required":["error"]},"RateLimitError":{"type":"object","properties":{"error":{"type":"string","example":"Rate limit exceeded"},"retryAfter":{"type":"integer","example":42,"description":"Seconds until the rate limit window resets"}},"required":["error"]},"McpAccessDenied":{"type":"object","properties":{"error":{"type":"string","example":"MCP access requires Business or Enterprise plan"},"reason":{"type":"string","enum":["mcp_access_required"],"example":"mcp_access_required"},"upgradeUrl":{"type":"string","format":"uri","example":"https://app.dictiva.com/settings?tab=billing","description":"URL where the tenant admin can upgrade their plan"}},"required":["error","reason"]},"PaginationParams":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"default":1,"example":1},"per_page":{"type":"integer","minimum":1,"maximum":100,"default":20,"example":20}}},"PaginationMeta":{"type":"object","properties":{"page":{"type":"integer","example":1},"perPage":{"type":"integer","example":20},"total":{"type":"integer","example":142},"totalPages":{"type":"integer","example":8}},"required":["page","perPage","total","totalPages"]},"FacetCount":{"type":"object","properties":{"field":{"type":"string","example":"lifecycle_state"},"counts":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string","example":"effective"},"count":{"type":"integer","example":23}},"required":["value","count"]}}},"required":["field","counts"]},"InvitationRequestBody":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":255,"description":"Full name"},"email":{"type":"string","maxLength":255,"format":"email","description":"Corporate email address"},"company":{"type":"string","minLength":2,"maxLength":255,"description":"Company or organization name"},"jobTitle":{"type":"string","maxLength":255,"description":"Job title or role"},"useCases":{"type":"string","maxLength":2000,"description":"Use cases, interest, or details about your governance needs"},"isUrgent":{"type":"boolean","default":false,"description":"Whether you need an expedited response"},"urgencyExplanation":{"type":"string","maxLength":2000,"description":"Required if isUrgent is true — explain the urgency (min 20 chars)"}},"required":["name","email","company"]},"InvitationRequestResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Request ID"},"message":{"type":"string","description":"Confirmation message"}},"required":["id","message"]},"InvitationRequestError":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"]}},"parameters":{}},"paths":{"/api/statements":{"get":{"tags":["Statements"],"summary":"Search statements","description":"Full-text search via Typesense with Postgres ILIKE fallback. Supports filtering by domain, lifecycle, modality, type, risk tier, and adoption status. Returns faceted results.","parameters":[{"schema":{"type":"string","description":"Search query (default: *)","example":"data retention"},"required":false,"description":"Search query (default: *)","name":"q","in":"query"},{"schema":{"type":"integer","minimum":1,"default":1,"example":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"example":20},"required":false,"name":"per_page","in":"query"},{"schema":{"type":"string","description":"Filter by domain name"},"required":false,"description":"Filter by domain name","name":"domain","in":"query"},{"schema":{"type":"string","description":"Filter by lifecycle state","example":"effective"},"required":false,"description":"Filter by lifecycle state","name":"lifecycle","in":"query"},{"schema":{"type":"string","description":"Filter by modality","example":"must"},"required":false,"description":"Filter by modality","name":"modality","in":"query"},{"schema":{"type":"string","description":"Filter by statement type","example":"obligation"},"required":false,"description":"Filter by statement type","name":"type","in":"query"},{"schema":{"type":"string","description":"Filter by risk tier","example":"high"},"required":false,"description":"Filter by risk tier","name":"risk_tier","in":"query"},{"schema":{"type":"string","description":"Filter by adoption status: adopted, diverged, native"},"required":false,"description":"Filter by adoption status: adopted, diverged, native","name":"adoption","in":"query"},{"schema":{"type":"string","description":"Sort order (default: updated_at:desc)","example":"updated_at:desc"},"required":false,"description":"Sort order (default: updated_at:desc)","name":"sort","in":"query"}],"responses":{"200":{"description":"Search results with facets and pagination metadata","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"document":{"type":"object","additionalProperties":{}},"highlights":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["document"]}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"perPage":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["page","perPage","total","totalPages"]},"facets":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"counts":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"count":{"type":"integer"}},"required":["value","count"]}}},"required":["field","counts"]}}},"required":["data","meta","facets"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Statements"],"summary":"Create a statement","description":"Create a new governance statement in draft lifecycle state.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":500},"body":{"type":"string","minLength":1,"maxLength":10000},"modality":{"type":"string","enum":["must","should","may"]},"statementType":{"type":"string","enum":["obligation","prohibition","permission","responsibility"]},"domainId":{"type":"string","format":"uuid"},"riskTier":{"type":"string","enum":["low","medium","high","critical"]},"maturityLevel":{"type":"string","enum":["foundational","intermediate","advanced","exemplary"]},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"annotations":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["rationale","justification","example","note","guidance"]},"content":{"type":"string","minLength":1}},"required":["type","content"]}},"effectiveAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"}]},"reviewAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"}]},"sunsetAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"}]}},"required":["title","body","modality","statementType"]}}}},"responses":{"201":{"description":"Statement created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/statements/{id}":{"get":{"tags":["Statements"],"summary":"Get a statement","description":"Retrieve a single statement by ID, including current version, domain, annotations, and relationships.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Statement detail","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"patch":{"tags":["Statements"],"summary":"Update a statement","description":"Partially update a statement. Creates a new version when title or body changes.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"displayId":{"type":"string","minLength":1,"maxLength":50},"title":{"type":"string","minLength":1,"maxLength":500},"body":{"type":"string","minLength":1,"maxLength":10000},"modality":{"type":"string","enum":["must","should","may"]},"statementType":{"type":"string","enum":["obligation","prohibition","permission","responsibility"]},"riskTier":{"type":["string","null"],"enum":["low","medium","high","critical",null]},"maturityLevel":{"type":["string","null"],"enum":["foundational","intermediate","advanced","exemplary",null]},"lifecycleState":{"type":"string","enum":["draft","in_review","approved","effective","retired","archived"]},"domainId":{"type":["string","null"],"format":"uuid"},"annotations":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["rationale","justification","example","note","guidance"]},"content":{"type":"string","minLength":1}},"required":["type","content"]}},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"effectiveAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"},{"type":"null"}]},"reviewAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"},{"type":"null"}]},"sunsetAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"},{"type":"null"}]},"appliesTo":{"type":"string","enum":["human","agent","both"]},"actorScope":{"type":["array","null"],"items":{"type":"string","enum":["employee","reviewer","service-account","agent","agent-workflow","external-tool"]}},"enforcementMode":{"type":"string","enum":["informational","human_review_required","machine_readable","machine_enforceable"]},"agentGuidance":{"type":["object","null"],"properties":{"allowedActions":{"type":"array","items":{"type":"string"}},"prohibitedActions":{"type":"array","items":{"type":"string"}},"requiredContext":{"type":"array","items":{"type":"string"}},"requiredApprovals":{"type":"array","items":{"type":"string"}},"evidenceRequirements":{"type":"array","items":{"type":"string"}},"escalationRules":{"type":"array","items":{"type":"string"}},"failureMode":{"type":"string"}}}}}}}},"responses":{"200":{"description":"Statement updated"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"delete":{"tags":["Statements"],"summary":"Delete a statement","description":"Soft-delete a statement (sets deleted_at timestamp).","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Statement deleted"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/statements/{id}/transitions":{"post":{"tags":["Statements"],"summary":"Transition lifecycle state","description":"Move a statement through its lifecycle (submit, approve, reject, activate, retire, reinstate, archive). Validates allowed transitions.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","enum":["submit","approve","reject","activate","retire","reinstate","archive"]},"comment":{"type":"string","maxLength":2000}},"required":["action"]}}}},"responses":{"200":{"description":"Transition applied"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/statements/{id}/history":{"get":{"tags":["Statements"],"summary":"Get governance event history","description":"Paginated governance events for a statement. Filterable by action type (comma-separated). Returns standardized { data, meta } envelope.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"default":1,"example":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"example":50},"required":false,"name":"per_page","in":"query"},{"schema":{"type":"string","description":"Comma-separated action filter","example":"approved,submitted"},"required":false,"description":"Comma-separated action filter","name":"action","in":"query"}],"responses":{"200":{"description":"Paginated governance events","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"action":{"type":"string"},"entityType":{"type":"string"},"entityId":{"type":"string","format":"uuid"},"actorName":{"type":"string"},"summary":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","action","entityType","entityId","actorName","summary","createdAt"],"additionalProperties":{}}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"perPage":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["page","perPage","total","totalPages"]}},"required":["data","meta"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/statements/{id}/relationships":{"get":{"tags":["Statements"],"summary":"List statement relationships","description":"Get all relationships (parent, child, related) for a statement.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Statement relationships","content":{"application/json":{"schema":{"type":"object","properties":{"relationships":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["relationships"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/statements/{id}/mappings":{"get":{"tags":["Statements"],"summary":"List control mappings","description":"Get all control framework mappings for a statement.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Control mappings","content":{"application/json":{"schema":{"type":"object","properties":{"mappings":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["mappings"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/statements/{id}/comprehension-points":{"get":{"tags":["Statements","Comprehension"],"summary":"List comprehension points","description":"Get atomic comprehension points for a statement's current version. Points are AI-generated (source: ai) or manually created (source: manual). Each point is a testable assertion used in the comprehension verification engine.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Comprehension points for the current version","content":{"application/json":{"schema":{"type":"object","properties":{"points":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"sortOrder":{"type":"number"},"pointText":{"type":"string"},"questionText":{"type":"string"},"questionType":{"type":"string","enum":["true_false","multiple_choice"]},"correctAnswer":{"type":"string"},"distractors":{"type":"array","items":{"type":"string"}},"source":{"type":"string","enum":["ai","manual"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","sortOrder","pointText","questionText","questionType","correctAnswer","distractors","source","createdAt"]}},"total":{"type":"number"}},"required":["points","total"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Statements","Comprehension"],"summary":"Regenerate comprehension points","description":"Re-run AI decomposition to generate new comprehension points for the statement's current version. Replaces existing AI-generated points but preserves manually created ones. Requires statement:edit permission.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Points regenerated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"statementTitle":{"type":"string"},"pointsGenerated":{"type":"number"},"manualPointsPreserved":{"type":"number"}},"required":["success","statementTitle","pointsGenerated","manualPointsPreserved"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/assemblies":{"get":{"tags":["Policies & Standards"],"summary":"List assemblies","description":"List all assemblies for the current tenant with pagination and optional search.","parameters":[{"schema":{"type":"string","description":"Search query"},"required":false,"description":"Search query","name":"q","in":"query"},{"schema":{"type":"integer","minimum":1,"default":1,"example":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"example":20},"required":false,"name":"per_page","in":"query"}],"responses":{"200":{"description":"Paginated assembly list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}},"total":{"type":"number"},"page":{"type":"number"},"perPage":{"type":"number"}},"required":["items","total","page","perPage"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Policies & Standards"],"summary":"Create an assembly","description":"Create a new policy assembly (policy, standard, procedure, or guideline).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":500},"description":{"type":"string","maxLength":5000},"assemblyType":{"type":"string","enum":["policy","standard","procedure","guideline"]},"domainId":{"type":"string","format":"uuid"}},"required":["title","assemblyType"]}}}},"responses":{"201":{"description":"Assembly created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/assemblies/{id}":{"get":{"tags":["Policies & Standards"],"summary":"Get an assembly","description":"Retrieve an assembly by ID with its items (pinned statement versions).","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Assembly detail with items","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"patch":{"tags":["Policies & Standards"],"summary":"Update an assembly","description":"Partially update an assembly's title, description, domain, or state.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"displayId":{"type":"string","minLength":1,"maxLength":50},"title":{"type":"string","minLength":1,"maxLength":500},"description":{"type":"string","maxLength":5000},"footerContent":{"type":["object","null"],"properties":{"content":{"type":"string","maxLength":5000},"format":{"type":"string","enum":["markdown"],"default":"markdown"}},"required":["content"]},"assemblyType":{"type":"string","enum":["policy","standard","procedure","guideline"]},"domainId":{"type":["string","null"],"format":"uuid"},"assemblyState":{"type":"string","enum":["draft","under_review","published","superseded","archived"]},"approvedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"},{"type":"null"}]},"publishedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"},{"type":"null"}]},"effectiveAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"},{"type":"null"}]},"reviewAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"},{"type":"null"}]},"sunsetAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"},{"type":"null"}]},"renewalPeriodMonths":{"type":["integer","null"],"minimum":1,"maximum":120}}}}}},"responses":{"200":{"description":"Assembly updated"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"delete":{"tags":["Policies & Standards"],"summary":"Delete an assembly","description":"Soft-delete an assembly.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Assembly deleted"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/assemblies/{id}/items":{"post":{"tags":["Policies & Standards"],"summary":"Add item to assembly","description":"Pin a specific statement version to the assembly.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"statementVersionId":{"type":"string","format":"uuid"},"sortOrder":{"type":"integer","minimum":0}},"required":["statementVersionId"]}}}},"responses":{"201":{"description":"Item added to assembly"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/assemblies/{id}/publish":{"post":{"tags":["Policies & Standards"],"summary":"Publish an assembly","description":"Transition an assembly to the published state, creating a manifest snapshot.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Assembly published"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/assemblies/{id}/export":{"get":{"tags":["Policies & Standards"],"summary":"Export assembly as PDF","description":"Generate and download a PDF export of the assembly with all included statements.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"PDF document","content":{"application/pdf":{"schema":{"type":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/actions":{"get":{"tags":["Actions"],"summary":"List action items","description":"List action items for the current user with optional filtering by status, type, and priority.","parameters":[{"schema":{"type":"integer","minimum":1,"default":1,"example":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"example":20},"required":false,"name":"per_page","in":"query"},{"schema":{"type":"string","description":"Filter by status: pending, in_progress, completed, dismissed, snoozed"},"required":false,"description":"Filter by status: pending, in_progress, completed, dismissed, snoozed","name":"status","in":"query"},{"schema":{"type":"string","description":"Filter by action type"},"required":false,"description":"Filter by action type","name":"type","in":"query"},{"schema":{"type":"string","description":"Filter by priority: low, normal, high, urgent"},"required":false,"description":"Filter by priority: low, normal, high, urgent","name":"priority","in":"query"}],"responses":{"200":{"description":"Paginated action items","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":{}}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"perPage":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["page","perPage","total","totalPages"]}},"required":["data","meta"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Actions"],"summary":"Create an action item","description":"Create a new action item assigned to a user.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"actionType":{"type":"string","enum":["review_statement","review_assembly","comprehension_check","acknowledgement_request","exception_decision","exception_expiring","attestation_pending","attestation_followup","draft_stale","divergence_available","evidence_gap","system_alert","profile_completion","tag_automation"]},"title":{"type":"string","minLength":1,"maxLength":500},"description":{"type":"string","maxLength":2000},"sourceType":{"type":"string","enum":["statement","assembly","exception","attestation_campaign","comprehension_session","acknowledgement_request","system","domain_tag"]},"sourceId":{"type":"string","format":"uuid"},"priority":{"type":"string","enum":["low","normal","high","urgent"],"default":"normal"},"dueDate":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"}]}},"required":["userId","actionType","title","sourceType"]}}}},"responses":{"201":{"description":"Action item created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/actions/{id}":{"get":{"tags":["Actions"],"summary":"Get an action item","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Action item detail","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"patch":{"tags":["Actions"],"summary":"Update an action item","description":"Update status, priority, or snooze an action item.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["pending","in_progress","completed","dismissed","snoozed"]},"priority":{"type":"string","enum":["low","normal","high","urgent"]},"snoozedUntil":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"}]}}}}}},"responses":{"200":{"description":"Action item updated"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"delete":{"tags":["Actions"],"summary":"Delete an action item","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Action item deleted"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/actions/bulk":{"post":{"tags":["Actions"],"summary":"Bulk update action items","description":"Complete, dismiss, or snooze multiple action items at once (max 100).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":100},"action":{"type":"string","enum":["complete","dismiss","snooze"]},"snoozedUntil":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"}]}},"required":["ids","action"]}}}},"responses":{"200":{"description":"Bulk update result","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"number"}},"required":["updated"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/actions/count":{"get":{"tags":["Actions"],"summary":"Count action items","description":"Get counts of action items grouped by status for the current user.","responses":{"200":{"description":"Action item counts by status","content":{"application/json":{"schema":{"type":"object","properties":{"pending":{"type":"number"},"in_progress":{"type":"number"},"total":{"type":"number"}},"required":["pending","in_progress","total"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/glossaries":{"get":{"tags":["Glossary"],"summary":"List glossaries","description":"List all glossaries accessible to the current tenant (tenant-owned + adopted library glossaries).","responses":{"200":{"description":"Glossary list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["items"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/glossaries/{id}":{"get":{"tags":["Glossary"],"summary":"Get a glossary","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Glossary detail with term count","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/glossaries/{id}/terms":{"get":{"tags":["Glossary"],"summary":"List glossary terms","description":"List all terms in a glossary with pagination and optional search.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","description":"Search query"},"required":false,"description":"Search query","name":"q","in":"query"},{"schema":{"type":"integer","minimum":1,"default":1,"example":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"example":20},"required":false,"name":"per_page","in":"query"}],"responses":{"200":{"description":"Paginated term list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}},"total":{"type":"number"},"page":{"type":"number"},"perPage":{"type":"number"}},"required":["items","total","page","perPage"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Glossary"],"summary":"Create a glossary term","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"term":{"type":"string","minLength":1,"maxLength":500},"definition":{"type":"string","minLength":1,"maxLength":10000},"abbreviation":{"type":"string","maxLength":50},"context":{"type":"string","maxLength":2000}},"required":["term","definition"]}}}},"responses":{"201":{"description":"Term created"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/glossaries/{id}/terms/{termId}":{"get":{"tags":["Glossary"],"summary":"Get a glossary term","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"termId","in":"path"}],"responses":{"200":{"description":"Term detail with relationships and external links","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"patch":{"tags":["Glossary"],"summary":"Update a glossary term","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"termId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"term":{"type":"string","minLength":1,"maxLength":500},"definition":{"type":"string","minLength":1,"maxLength":10000},"abbreviation":{"type":["string","null"],"maxLength":50},"context":{"type":["string","null"],"maxLength":2000}}}}}},"responses":{"200":{"description":"Term updated"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"delete":{"tags":["Glossary"],"summary":"Delete a glossary term","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"termId","in":"path"}],"responses":{"200":{"description":"Term deleted"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/glossaries/{id}/terms/{termId}/relationships":{"get":{"tags":["Glossary"],"summary":"List term relationships","description":"Get all relationships (broader, narrower, synonym, related, variant) for a term.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"termId","in":"path"}],"responses":{"200":{"description":"Term relationships","content":{"application/json":{"schema":{"type":"object","properties":{"relationships":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["relationships"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Glossary"],"summary":"Create term relationship","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"termId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"targetTermId":{"type":"string","format":"uuid"},"relationshipType":{"type":"string","enum":["broader","narrower","synonym","related","variant"]},"description":{"type":"string","maxLength":500},"displayOrder":{"type":"integer","minimum":0,"maximum":999,"default":0}},"required":["targetTermId","relationshipType"]}}}},"responses":{"201":{"description":"Relationship created"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/glossaries/{id}/terms/{termId}/external-links":{"get":{"tags":["Glossary"],"summary":"List external links for a term","description":"Get all external links (URLs to authoritative sources like Collibra, articles, videos).","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"termId","in":"path"}],"responses":{"200":{"description":"External links","content":{"application/json":{"schema":{"type":"object","properties":{"links":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["links"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Glossary"],"summary":"Add external link to a term","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"termId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"title":{"type":"string","minLength":1,"maxLength":500},"description":{"type":"string","maxLength":2000}},"required":["url","title"]}}}},"responses":{"201":{"description":"External link added"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/library":{"get":{"tags":["Library"],"summary":"Search the content library","description":"Unified search across library statements, glossary terms, and regulations. Supports tab-based filtering (statements, glossary, regulations).","parameters":[{"schema":{"type":"string","description":"Search query (default: *)"},"required":false,"description":"Search query (default: *)","name":"q","in":"query"},{"schema":{"type":"string","description":"Filter by tab: statements, glossary, regulations"},"required":false,"description":"Filter by tab: statements, glossary, regulations","name":"tab","in":"query"},{"schema":{"type":"integer","minimum":1,"default":1,"example":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"example":20},"required":false,"name":"per_page","in":"query"},{"schema":{"type":"string","description":"Filter by domain"},"required":false,"description":"Filter by domain","name":"domain","in":"query"}],"responses":{"200":{"description":"Library search results with facets and pagination metadata","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"document":{"type":"object","additionalProperties":{}},"highlights":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["document"]}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"perPage":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["page","perPage","total","totalPages"]},"facets":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"counts":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"count":{"type":"integer"}},"required":["value","count"]}}},"required":["field","counts"]}}},"required":["data","meta","facets"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/library/statements/{id}":{"get":{"tags":["Library"],"summary":"Get a library statement","description":"Retrieve a single library statement with its current version, domain, and metadata.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Library statement detail","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/library/statements/{id}/term-links":{"get":{"tags":["Library"],"summary":"Get term links for a library statement","description":"Retrieve glossary terms linked to a specific library statement version.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Linked glossary terms","content":{"application/json":{"schema":{"type":"object","properties":{"termLinks":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["termLinks"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/library/glossary":{"get":{"tags":["Library"],"summary":"Browse library glossary","description":"Browse the shared governance glossary with search and pagination.","parameters":[{"schema":{"type":"string"},"required":false,"name":"q","in":"query"},{"schema":{"type":"integer","minimum":1,"default":1,"example":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"example":20},"required":false,"name":"per_page","in":"query"}],"responses":{"200":{"description":"Library glossary terms with pagination metadata","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":{}}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"perPage":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["page","perPage","total","totalPages"]}},"required":["data","meta"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/library/glossary/{id}":{"get":{"tags":["Library"],"summary":"Get a library glossary term","description":"Retrieve a single library glossary term with relationships, external links, and statement links.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Library glossary term detail","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/regulations":{"get":{"tags":["Regulations"],"security":[],"summary":"List regulations","description":"List all regulations in the registry with optional filtering by region, category, and sector.","parameters":[{"schema":{"type":"string","description":"Search query"},"required":false,"description":"Search query","name":"q","in":"query"},{"schema":{"type":"string","description":"Filter by region","example":"EU"},"required":false,"description":"Filter by region","name":"region","in":"query"},{"schema":{"type":"string","description":"Filter by category"},"required":false,"description":"Filter by category","name":"category","in":"query"},{"schema":{"type":"string","description":"Filter by sector (general, financial_services, healthcare, education, public)"},"required":false,"description":"Filter by sector (general, financial_services, healthcare, education, public)","name":"sector","in":"query"},{"schema":{"type":"integer","minimum":1,"default":1,"example":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"example":20},"required":false,"name":"per_page","in":"query"}],"responses":{"200":{"description":"Regulation list","content":{"application/json":{"schema":{"type":"object","properties":{"regulations":{"type":"array","items":{"type":"object","additionalProperties":{}}},"found":{"type":"number"},"facets":{"type":"array","items":{"type":"object","additionalProperties":{}}},"families":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"memberSlugs":{"type":"array","items":{"type":"string"}},"region":{"type":"string"}},"required":["id","label","memberSlugs","region"]}}},"required":["regulations","found","facets","families"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/regulations/{slug}":{"get":{"tags":["Regulations"],"security":[],"summary":"Get a regulation","description":"Retrieve a regulation by slug with its requirements and metadata.","parameters":[{"schema":{"type":"string","description":"Regulation slug","example":"gdpr"},"required":true,"description":"Regulation slug","name":"slug","in":"path"}],"responses":{"200":{"description":"Regulation detail with requirements","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string"}},"required":["slug"],"additionalProperties":{}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/regulations/{slug}/annotations":{"get":{"tags":["Regulations"],"summary":"List regulation annotations","description":"Get all annotations (rationale, guidance, examples) for a regulation.","parameters":[{"schema":{"type":"string"},"required":true,"name":"slug","in":"path"}],"responses":{"200":{"description":"Regulation annotations","content":{"application/json":{"schema":{"type":"object","properties":{"annotations":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["annotations"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Regulations"],"summary":"Add a regulation annotation","parameters":[{"schema":{"type":"string"},"required":true,"name":"slug","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"annotationType":{"type":"string","enum":["rationale","justification","example","note","guidance"]},"content":{"type":"string","minLength":1,"maxLength":10000}},"required":["annotationType","content"]}}}},"responses":{"201":{"description":"Annotation created"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/regulations/{slug}/requirements/adopt":{"post":{"tags":["Regulations"],"summary":"Adopt regulation requirements","description":"Adopt selected regulation requirements as tenant statements, optionally assigning to a domain.","parameters":[{"schema":{"type":"string"},"required":true,"name":"slug","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"requirementIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1},"targetDomainId":{"type":"string","format":"uuid"}},"required":["requirementIds"]}}}},"responses":{"201":{"description":"Requirements adopted as statements","content":{"application/json":{"schema":{"type":"object","properties":{"adopted":{"type":"number"},"statementIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["adopted","statementIds"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/regulations/{slug}/requirements/{reqId}/mappings":{"get":{"tags":["Regulations"],"summary":"List requirement mappings","description":"Get all statement mappings for a specific regulation requirement.","parameters":[{"schema":{"type":"string"},"required":true,"name":"slug","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"reqId","in":"path"}],"responses":{"200":{"description":"Requirement-to-statement mappings","content":{"application/json":{"schema":{"type":"object","properties":{"mappings":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["mappings"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Regulations"],"summary":"Create requirement mapping","description":"Map a library statement to a regulation requirement.","parameters":[{"schema":{"type":"string"},"required":true,"name":"slug","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"reqId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"libraryStatementId":{"type":"string","format":"uuid"},"mappingType":{"type":"string","enum":["satisfies","partially_satisfies","implements","addresses"]},"notes":{"type":["string","null"],"maxLength":2000}},"required":["libraryStatementId","mappingType"]}}}},"responses":{"201":{"description":"Mapping created"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/settings/api-keys":{"get":{"tags":["Settings"],"summary":"List API keys","description":"List all API keys for the current tenant. Only key prefixes are returned (hashes are never exposed).","responses":{"200":{"description":"API key list","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"keyPrefix":{"type":"string","example":"dv_live_AbCdEf"},"scopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","description","keyPrefix","scopes","lastUsedAt","expiresAt","revokedAt","createdAt"]}}},"required":["keys"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Settings"],"summary":"Create an API key","description":"Generate a new API key. The full key is returned **only once** in the response — store it securely. Subsequent reads only show the prefix.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":1000},"scopes":{"type":"array","items":{"type":"string","enum":["statement:read","assembly:read","glossary:read","control:read","exception:read","attestation:read","library:browse","action:read","report:read","regulation:read"]},"minItems":1},"expiresAt":{"type":"string","format":"date-time"}},"required":["name","scopes"]}}}},"responses":{"201":{"description":"API key created — full key returned only once","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"key":{"type":"string","description":"Full API key — store securely, shown only once","example":"dv_live_AbCdEfGhIjKlMnOpQrStUvWxYz0123456789abc"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"expiresAt":{"type":["string","null"],"format":"date-time"}},"required":["id","key","name","scopes","expiresAt"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"patch":{"tags":["Settings"],"summary":"Update an API key","description":"Update an API key's name, description, or scopes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":1000},"scopes":{"type":"array","items":{"type":"string","enum":["statement:read","assembly:read","glossary:read","control:read","exception:read","attestation:read","library:browse","action:read","report:read","regulation:read"]},"minItems":1}},"required":["id"]}}}},"responses":{"200":{"description":"API key updated"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"delete":{"tags":["Settings"],"summary":"Revoke an API key","description":"Permanently revoke an API key. This cannot be undone.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}}}},"responses":{"200":{"description":"API key revoked"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/settings/tags":{"get":{"tags":["Settings"],"summary":"List governed tags","description":"List all governed tags for the current tenant, with their rules and usage counts.","responses":{"200":{"description":"Tag list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["items"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"post":{"tags":["Settings"],"summary":"Create a governed tag","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domainId":{"type":"string","format":"uuid"},"tag":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","maxLength":2000},"lifecycle":{"type":"string","enum":["active","deprecated","retired"],"default":"active"},"color":{"type":"string","maxLength":50},"scope":{"type":"string","enum":["tenant","domain","assembly"],"default":"tenant"},"ownerId":{"type":"string","format":"uuid"}},"required":["domainId","tag"]}}}},"responses":{"201":{"description":"Tag created"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/settings/tags/{id}":{"patch":{"tags":["Settings"],"summary":"Update a governed tag","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tag":{"type":"string","minLength":1,"maxLength":100},"description":{"type":["string","null"],"maxLength":2000},"lifecycle":{"type":"string","enum":["active","deprecated","retired"]},"color":{"type":["string","null"],"maxLength":50},"scope":{"type":"string","enum":["tenant","domain","assembly"]},"ownerId":{"type":["string","null"],"format":"uuid"}}}}}},"responses":{"200":{"description":"Tag updated"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}},"delete":{"tags":["Settings"],"summary":"Delete a governed tag","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Tag deleted"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/settings/admin/activity":{"get":{"tags":["Settings"],"summary":"List admin activity","description":"Paginated governance event audit log. Filterable by entity type, action, and actor.","parameters":[{"schema":{"type":"integer","minimum":1,"default":1,"example":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"example":50},"required":false,"name":"per_page","in":"query"},{"schema":{"type":"string","description":"Filter by entity type","example":"statement"},"required":false,"description":"Filter by entity type","name":"entityType","in":"query"},{"schema":{"type":"string","description":"Filter by action","example":"approved"},"required":false,"description":"Filter by action","name":"action","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Filter by actor user ID"},"required":false,"description":"Filter by actor user ID","name":"actorId","in":"query"}],"responses":{"200":{"description":"Paginated governance events","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"actorName":{"type":"string"},"action":{"type":"string"},"entityType":{"type":"string"},"summary":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","actorName","action","entityType","summary","createdAt"],"additionalProperties":{}}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"perPage":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["page","perPage","total","totalPages"]}},"required":["data","meta"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/settings/members":{"get":{"tags":["Settings"],"summary":"List tenant members","description":"List all users who are members of the current tenant.","responses":{"200":{"description":"Member list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["items"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/settings/domains":{"get":{"tags":["Settings"],"summary":"List governance domains","description":"List all governance domains configured for the tenant.","responses":{"200":{"description":"Domain list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["items"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/auth/resolve-method":{"post":{"tags":["Auth"],"summary":"Resolve sign-in method","description":"Determine the authentication method for a given email address. Returns `credential` for magic link sign-in, or `sso` with provider details for domains with verified SSO configuration. This is a pre-authentication endpoint — no session or API key required.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","example":"alice@acme.com"}},"required":["email"]}}}},"responses":{"200":{"description":"Authentication method resolved","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"method":{"type":"string","enum":["credential"]}},"required":["method"]},{"type":"object","properties":{"method":{"type":"string","enum":["sso"]},"providerId":{"type":"string","example":"sso_abc123"},"tenantName":{"type":"string","example":"Acme Corp"}},"required":["method","providerId","tenantName"]}]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}}}}},"/api/health":{"get":{"tags":["Health"],"summary":"Overall health check","description":"Returns aggregate health status of all backend services (Postgres, Typesense, Redis, schema).","security":[],"responses":{"200":{"description":"All services healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded"]},"timestamp":{"type":"string"},"version":{"type":"string"},"services":{"type":"object","properties":{"webapp":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"]},"latency_ms":{"type":"integer"}},"required":["status","latency_ms"]},"postgres":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"]},"latency_ms":{"type":"integer"}},"required":["status","latency_ms"]},"typesense":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"]},"latency_ms":{"type":"integer"}},"required":["status","latency_ms"]},"schema":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"]},"latency_ms":{"type":"integer"}},"required":["status","latency_ms"]},"redis":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"]},"latency_ms":{"type":"integer"}},"required":["status","latency_ms"]}},"required":["webapp","postgres","typesense","schema","redis"]}},"required":["status","timestamp","version","services"]}}}},"503":{"description":"One or more services unhealthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded"]},"timestamp":{"type":"string"},"version":{"type":"string"},"services":{"type":"object","additionalProperties":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"]},"latency_ms":{"type":"integer"}},"required":["status","latency_ms"]}}},"required":["status","timestamp","version","services"]}}}}}}},"/api/health/live":{"get":{"tags":["Health"],"summary":"Liveness probe","description":"Simple liveness check — always returns 200 if the process is running. Used by orchestrators (Kubernetes, Docker).","security":[],"responses":{"200":{"description":"Process alive","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]}},"required":["status"]}}}}}}},"/api/health/redis":{"get":{"tags":["Health"],"summary":"Redis health check","security":[],"responses":{"200":{"description":"Redis connected","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["healthy"]},"latency_ms":{"type":"integer"}},"required":["status","latency_ms"]}}}},"503":{"description":"Redis unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["unhealthy"]},"error":{"type":"string"}},"required":["status","error"]}}}}}}},"/api/health/typesense":{"get":{"tags":["Health"],"summary":"Typesense health check","security":[],"responses":{"200":{"description":"Typesense connected","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["healthy"]},"latency_ms":{"type":"integer"}},"required":["status","latency_ms"]}}}},"503":{"description":"Typesense unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["unhealthy"]},"error":{"type":"string"}},"required":["status","error"]}}}}}}},"/api/billing/checkout":{"post":{"tags":["Billing"],"summary":"Create Stripe Checkout session for plan upgrade","description":"Creates a Stripe Checkout session for upgrading to Professional or Business. Promotion codes enabled. Returns a redirect URL to the Stripe-hosted checkout page.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"planTier":{"type":"string","enum":["professional","business"]},"billingInterval":{"type":"string","enum":["monthly","annual"]}},"required":["planTier","billingInterval"]}}}},"responses":{"200":{"description":"Checkout session created","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"}},"required":["url"]}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/billing/portal":{"post":{"tags":["Billing"],"summary":"Create Stripe Customer Portal session","description":"Creates a Customer Portal session for managing subscription, payment methods, invoice history, and cancellation. Requires an active Stripe customer.","responses":{"200":{"description":"Portal session created","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"}},"required":["url"]}}}},"400":{"description":"No billing account found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/billing/usage":{"get":{"tags":["Billing"],"summary":"Get tenant billing state","description":"Returns the full billing state: current plan, subscription status, usage metrics for the current period, remaining credits, plan limits, and the complete entitlement map.","responses":{"200":{"description":"Billing state","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"tier":{"type":"string","enum":["community","professional","business","enterprise"]},"monthlyPriceCents":{"type":["number","null"]},"annualPriceCents":{"type":["number","null"]}},"required":["id","name","slug","tier","monthlyPriceCents","annualPriceCents"]},"subscription":{"type":["object","null"],"properties":{"status":{"type":"string"},"billingInterval":{"type":"string","enum":["monthly","annual"]},"currentPeriodStart":{"type":["string","null"],"format":"date-time"},"currentPeriodEnd":{"type":["string","null"],"format":"date-time"},"cancelAt":{"type":["string","null"],"format":"date-time"}},"required":["status","billingInterval","currentPeriodStart","currentPeriodEnd","cancelAt"]},"usage":{"type":"object","properties":{"aiCreditsUsed":{"type":"number"},"purchasedCreditsUsed":{"type":"number"},"statementsCreated":{"type":"number"},"assembliesCreated":{"type":"number"},"usersActive":{"type":"number"},"apiRequests":{"type":"number"},"periodStart":{"type":"string"}},"required":["aiCreditsUsed","purchasedCreditsUsed","statementsCreated","assembliesCreated","usersActive","apiRequests","periodStart"]},"credits":{"type":"object","properties":{"monthly":{"type":"number"},"purchased":{"type":"number"},"total":{"type":"number"}},"required":["monthly","purchased","total"]},"limits":{"type":"object","properties":{"maxUsers":{"type":["number","null"]},"maxAssemblies":{"type":["number","null"]},"maxStatements":{"type":["number","null"]},"maxGlossaryTerms":{"type":["number","null"]},"maxFrameworks":{"type":["number","null"]},"monthlyAiCredits":{"type":["number","null"]}},"required":["maxUsers","maxAssemblies","maxStatements","maxGlossaryTerms","maxFrameworks","monthlyAiCredits"]},"entitlements":{"type":"object","additionalProperties":{"type":"object","properties":{"allowed":{"type":"boolean"},"reason":{"type":"string"},"limit":{"type":["number","null"]},"current":{"type":"number"},"upgradeTarget":{"type":"string"}},"required":["allowed"]}}},"required":["plan","subscription","usage","credits","limits","entitlements"]}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/billing/credits":{"post":{"tags":["Billing"],"summary":"Create Stripe Checkout session for credit pack purchase","description":"Creates a one-time payment Checkout session for purchasing an AI credit pack. Packs: Starter (500 credits / $9), Growth (1,000 / $15), Scale (5,000 / $59). Credits are added to the tenant balance after successful payment via webhook.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"pack":{"type":"string","enum":["starter","growth","scale"]}},"required":["pack"]}}}},"responses":{"200":{"description":"Checkout session created","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"}},"required":["url"]}}}},"400":{"description":"Invalid pack","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/billing/api-usage":{"get":{"tags":["Billing"],"summary":"Get API and MCP usage metrics for the current billing period","description":"Returns API and MCP request counts for the current period, daily breakdown over the last 30 days, rate limit utilization, and top endpoints. Used by the usage dashboard in Settings > Billing.","responses":{"200":{"description":"API usage metrics","content":{"application/json":{"schema":{"type":"object","properties":{"period":{"type":"object","properties":{"start":{"type":"string","example":"2026-03-01"},"end":{"type":"string","example":"2026-03-31"}},"required":["start","end"]},"apiRequests":{"type":"integer","example":142},"mcpRequests":{"type":"integer","example":38},"rateLimit":{"type":"object","properties":{"tier":{"type":"string","enum":["community","professional","business","enterprise"]},"requestsPerMinute":{"type":"integer","example":20},"utilizationPercent":{"type":"number","example":12.5}},"required":["tier","requestsPerMinute","utilizationPercent"]},"daily":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","example":"2026-03-25"},"apiRequests":{"type":"integer"},"mcpRequests":{"type":"integer"}},"required":["date","apiRequests","mcpRequests"]}}},"required":["period","apiRequests","mcpRequests","rateLimit","daily"]}}}},"401":{"description":"Unauthorized — missing or invalid API key / session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/agent/bundles/{assemblyId}":{"get":{"tags":["Agent"],"summary":"Get compiled assembly bundle","description":"Compiles an assembly into a machine-readable governance bundle with statements, glossary, agent guidance, and a signed content manifest.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Assembly UUID"},"required":true,"description":"Assembly UUID","name":"assemblyId","in":"path"},{"schema":{"type":"string","enum":["json","json-ld"],"description":"Output format","example":"json"},"required":false,"description":"Output format","name":"format","in":"query"},{"schema":{"type":"string","enum":["human","agent","both"],"description":"Filter statements by actor applicability"},"required":false,"description":"Filter statements by actor applicability","name":"actor","in":"query"}],"responses":{"200":{"description":"Compiled governance bundle","content":{"application/json":{"schema":{"type":"object","properties":{"bundleVersion":{"type":"string"},"format":{"type":"string","enum":["json","json-ld"]},"compiledAt":{"type":"string"},"assembly":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"displayId":{"type":"string"},"title":{"type":"string"},"assemblyType":{"type":"string"},"assemblyState":{"type":"string"}},"required":["id","displayId","title","assemblyType","assemblyState"],"additionalProperties":{}},"statements":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"displayId":{"type":"string"},"title":{"type":["string","null"]},"body":{"type":["string","null"]},"modality":{"type":["string","null"]},"statementType":{"type":["string","null"]},"lifecycleState":{"type":"string"},"appliesTo":{"type":"string"},"actorScope":{"type":["array","null"],"items":{"type":"string"}},"enforcementMode":{"type":["string","null"]},"domain":{"type":["string","null"]},"agentGuidance":{"type":["object","null"],"properties":{"allowedActions":{"type":["array","null"],"items":{"type":"string"}},"prohibitedActions":{"type":["array","null"],"items":{"type":"string"}},"requiredContext":{"type":["array","null"],"items":{"type":"string"}},"requiredApprovals":{},"evidenceRequirements":{"type":["array","null"],"items":{"type":"string"}},"escalationRules":{"type":["object","null"],"additionalProperties":{}},"failureMode":{"type":["object","null"],"additionalProperties":{}}},"required":["allowedActions","prohibitedActions","requiredContext","evidenceRequirements","escalationRules","failureMode"]},"updatedAt":{"type":"string"}},"required":["id","displayId","title","body","modality","statementType","lifecycleState","appliesTo","actorScope","enforcementMode","domain","agentGuidance","updatedAt"],"additionalProperties":{}}},"glossary":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"term":{"type":"string"}},"required":["id","term"],"additionalProperties":{}}},"manifest":{"type":"object","properties":{"statementCount":{"type":"integer"},"glossaryTermCount":{"type":"integer"},"contentHash":{"type":"string"},"algorithm":{"type":"string","enum":["sha256"]}},"required":["statementCount","glossaryTermCount","contentHash","algorithm"]}},"required":["bundleVersion","format","compiledAt","assembly","statements","glossary","manifest"],"additionalProperties":{}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden — MCP agent access requires Business or Enterprise plan. Upgrade to enable agent endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpAccessDenied"}}}},"404":{"description":"Assembly not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"Assembly not found"}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/agent/statements":{"get":{"tags":["Agent"],"summary":"Search statements by governance dimension","description":"Returns statements filtered by actor applicability, enforcement mode, domain, and actor scope. Includes structured agent guidance fields.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["human","agent","both"],"description":"Filter by actor applicability"},"required":false,"description":"Filter by actor applicability","name":"applies_to","in":"query"},{"schema":{"type":"string","enum":["informational","human_review_required","machine_readable","machine_enforceable"],"description":"Filter by enforcement mode"},"required":false,"description":"Filter by enforcement mode","name":"enforcement_mode","in":"query"},{"schema":{"type":"string","description":"Comma-separated actor scopes (e.g. agent,agent-workflow)"},"required":false,"description":"Comma-separated actor scopes (e.g. agent,agent-workflow)","name":"actor_scope","in":"query"},{"schema":{"type":"string","description":"Filter by governance domain name"},"required":false,"description":"Filter by governance domain name","name":"domain","in":"query"},{"schema":{"type":"string","description":"Text search"},"required":false,"description":"Text search","name":"q","in":"query"},{"schema":{"type":"integer","minimum":1,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"per_page","in":"query"}],"responses":{"200":{"description":"Paginated list of statements with agent guidance","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"displayId":{"type":"string"},"title":{"type":["string","null"]},"body":{"type":["string","null"]},"modality":{"type":["string","null"]},"statementType":{"type":["string","null"]},"lifecycleState":{"type":"string"},"appliesTo":{"type":"string"},"actorScope":{"type":["array","null"],"items":{"type":"string"}},"enforcementMode":{"type":["string","null"]},"domain":{"type":["string","null"]},"agentGuidance":{"type":["object","null"],"properties":{"allowedActions":{"type":["array","null"],"items":{"type":"string"}},"prohibitedActions":{"type":["array","null"],"items":{"type":"string"}},"requiredContext":{"type":["array","null"],"items":{"type":"string"}},"requiredApprovals":{},"evidenceRequirements":{"type":["array","null"],"items":{"type":"string"}},"escalationRules":{"type":["object","null"],"additionalProperties":{}},"failureMode":{"type":["object","null"],"additionalProperties":{}}},"required":["allowedActions","prohibitedActions","requiredContext","evidenceRequirements","escalationRules","failureMode"]},"updatedAt":{"type":"string"}},"required":["id","displayId","title","body","modality","statementType","lifecycleState","appliesTo","actorScope","enforcementMode","domain","agentGuidance","updatedAt"]}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"perPage":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["page","perPage","total","totalPages"]}},"required":["data","meta"]}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden — MCP agent access requires Business or Enterprise plan. Upgrade to enable agent endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpAccessDenied"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/agent/glossary":{"get":{"tags":["Agent"],"summary":"Search glossary terms with ontology metadata","description":"Returns glossary terms with machine keys, aliases, term types, and ontology relationships. Filtered by actor applicability and term type.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["human","agent","both"],"description":"Filter by actor applicability"},"required":false,"description":"Filter by actor applicability","name":"applies_to","in":"query"},{"schema":{"type":"string","enum":["concept","role","action","constraint","metric"],"description":"Filter by term type"},"required":false,"description":"Filter by term type","name":"term_type","in":"query"},{"schema":{"type":"string","description":"Text search"},"required":false,"description":"Text search","name":"q","in":"query"},{"schema":{"type":"integer","minimum":1,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"per_page","in":"query"}],"responses":{"200":{"description":"Paginated list of glossary terms with ontology metadata","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"term":{"type":"string"},"definition":{"type":["string","null"]},"status":{"type":["string","null"]},"machineKey":{"type":["string","null"]},"aliases":{"type":["array","null"],"items":{"type":"string"}},"termType":{"type":["string","null"]},"appliesTo":{"type":"string"},"actorScope":{"type":["array","null"],"items":{"type":"string"}},"broaderTermId":{"type":["string","null"],"format":"uuid"},"glossary":{"type":"string"},"relationships":{"type":"array","items":{"type":"object","properties":{"targetTermId":{"type":"string","format":"uuid"},"relationshipType":{"type":"string"}},"required":["targetTermId","relationshipType"]}},"updatedAt":{"type":"string"}},"required":["id","term","definition","status","machineKey","aliases","termType","appliesTo","actorScope","broaderTermId","glossary","relationships","updatedAt"]}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"perPage":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["page","perPage","total","totalPages"]}},"required":["data","meta"]}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden — MCP agent access requires Business or Enterprise plan. Upgrade to enable agent endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpAccessDenied"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/agent/ontology":{"get":{"tags":["Agent"],"summary":"Export glossary as ontology graph","description":"Returns the full glossary as a typed ontology graph with hierarchical and associative relationships between terms.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["json","json-ld"],"description":"Output format","example":"json"},"required":false,"description":"Output format","name":"format","in":"query"},{"schema":{"type":"string","enum":["human","agent","both"],"description":"Filter by actor applicability"},"required":false,"description":"Filter by actor applicability","name":"applies_to","in":"query"}],"responses":{"200":{"description":"Ontology graph with terms and relationships","content":{"application/json":{"schema":{"type":"object","properties":{"ontologyVersion":{"type":"string"},"compiledAt":{"type":"string"},"tenant":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"]},"terms":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"term":{"type":"string"},"definition":{"type":["string","null"]},"machineKey":{"type":["string","null"]},"aliases":{"type":["array","null"],"items":{"type":"string"}},"termType":{"type":["string","null"]},"appliesTo":{"type":"string"},"actorScope":{"type":["array","null"],"items":{"type":"string"}},"broaderTermId":{"type":["string","null"],"format":"uuid"}},"required":["id","term","definition","machineKey","aliases","termType","appliesTo","actorScope","broaderTermId"]}},"relationships":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","format":"uuid"},"target":{"type":"string","format":"uuid"},"type":{"type":"string"},"description":{"type":["string","null"]}},"required":["source","target","type","description"]}},"stats":{"type":"object","properties":{"termCount":{"type":"integer"},"relationshipCount":{"type":"integer"},"termTypes":{"type":"object","additionalProperties":{"type":"integer"}},"actorApplicability":{"type":"object","additionalProperties":{"type":"integer"}}},"required":["termCount","relationshipCount","termTypes","actorApplicability"]}},"required":["ontologyVersion","compiledAt","tenant","terms","relationships","stats"],"additionalProperties":{}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden — MCP agent access requires Business or Enterprise plan. Upgrade to enable agent endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpAccessDenied"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/mcp":{"post":{"summary":"MCP governance server (Streamable HTTP)","description":"Model Context Protocol endpoint over Streamable HTTP, stateless JSON mode. Accepts JSON-RPC 2.0 requests (initialize, tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get). Same 6 tools as the stdio transport, gated by the same API-key auth and Business+ entitlement. Pairs with scripts/mcp-governance-server.ts for local stdio use.","tags":["Agent"],"security":[{"bearerAuth":[]}],"requestBody":{"description":"JSON-RPC 2.0 request per MCP Streamable HTTP spec","content":{"application/json":{"schema":{"type":"object","properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"anyOf":[{"type":"string"},{"type":"number"}]},"method":{"type":"string","description":"MCP method name (initialize, tools/list, tools/call, etc.)","example":"tools/list"},"params":{"type":"object","additionalProperties":{}}},"required":["jsonrpc","method"],"additionalProperties":{}}}}},"responses":{"200":{"description":"JSON-RPC 2.0 response or SSE stream","content":{"application/json":{"schema":{"type":"object","properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"anyOf":[{"type":"string"},{"type":"number"}]},"result":{"type":"object","additionalProperties":{}},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}},"required":["code","message"]}},"required":["jsonrpc","id"]}}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"Forbidden — MCP agent access requires Business or Enterprise plan. Upgrade to enable agent endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpAccessDenied"}}}},"429":{"description":"Rate limit exceeded — too many requests for this API key. Check `Retry-After` header.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per window (varies by plan tier)","schema":{"type":"integer","example":20}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current 60-second window","schema":{"type":"integer","example":0}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit window resets","schema":{"type":"integer","example":1742342460}},"X-RateLimit-Window":{"description":"Window duration in seconds","schema":{"type":"integer","example":60}},"Retry-After":{"description":"Seconds until the rate limit window resets","schema":{"type":"integer","example":42}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitError"}}}}}}},"/api/platform/tenants/{id}/billing":{"get":{"tags":["Platform Admin"],"summary":"Get tenant billing overview","description":"Returns the full billing state for a tenant: plan, subscription, usage metrics, recent billing events, credit transactions, and all available plans for override. Platform admin only.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Tenant billing overview","content":{"application/json":{"schema":{"type":"object","properties":{"tenant":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"purchasedCredits":{"type":["number","null"]},"subscriptionStatus":{"type":["string","null"]},"stripeCustomerId":{"type":["string","null"]}},"required":["id","name","slug","purchasedCredits","subscriptionStatus","stripeCustomerId"]},"plan":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"tier":{"type":"string"},"monthlyAiCredits":{"type":["number","null"]}},"required":["id","name","slug","tier","monthlyAiCredits"]},"allPlans":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"tier":{"type":"string"}},"required":["id","name","slug","tier"]}},"subscription":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"billingInterval":{"type":"string","enum":["monthly","annual"]},"currentPeriodStart":{"type":["string","null"],"format":"date-time"},"currentPeriodEnd":{"type":["string","null"],"format":"date-time"},"cancelAt":{"type":["string","null"],"format":"date-time"},"canceledAt":{"type":["string","null"],"format":"date-time"},"stripeSubscriptionId":{"type":["string","null"]}},"required":["id","status","billingInterval","currentPeriodStart","currentPeriodEnd","cancelAt","canceledAt","stripeSubscriptionId"]},"usage":{"type":["object","null"],"properties":{"aiCreditsUsed":{"type":"number"},"purchasedCreditsUsed":{"type":"number"},"statementsCreated":{"type":"number"},"assembliesCreated":{"type":"number"},"usersActive":{"type":"number"},"apiRequests":{"type":"number"},"periodStart":{"type":"string"},"periodEnd":{"type":"string"}},"required":["aiCreditsUsed","purchasedCreditsUsed","statementsCreated","assembliesCreated","usersActive","apiRequests","periodStart","periodEnd"]},"billingEvents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"action":{"type":"string"},"summary":{"type":["string","null"]},"actorName":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","action","summary","actorName","createdAt"]}},"creditTransactions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"amount":{"type":"number"},"balanceAfter":{"type":"number"},"description":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","type","amount","balanceAfter","description","createdAt"]}}},"required":["tenant","plan","allPlans","subscription","usage","billingEvents","creditTransactions"]}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"Not a platform admin","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Tenant not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/platform/tenants/{id}/plan-override":{"post":{"tags":["Platform Admin"],"summary":"Override tenant plan","description":"Directly set a tenant's plan without Stripe subscription change. Used for partner/enterprise grants. Sets subscriptionStatus to active. Platform admin only.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"planId":{"type":"string","format":"uuid"},"reason":{"type":"string","minLength":1,"maxLength":500}},"required":["planId","reason"]}}}},"responses":{"200":{"description":"Plan overridden","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"fromPlan":{"type":"string"},"toPlan":{"type":"string"}},"required":["ok","fromPlan","toPlan"]}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"Not a platform admin","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Tenant or plan not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/platform/tenants/{id}/credit-adjustment":{"post":{"tags":["Platform Admin"],"summary":"Adjust tenant credits","description":"Add or remove purchased credits from a tenant's balance (bonus, refund, or adjustment). Atomic transaction: balance update + ledger entry. Balance cannot go below zero. Platform admin only.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"integer","description":"Credits to add (positive) or remove (negative)"},"type":{"type":"string","enum":["bonus","refund","adjustment"]},"description":{"type":"string","minLength":1,"maxLength":500}},"required":["amount","type","description"]}}}},"responses":{"200":{"description":"Credits adjusted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"previousBalance":{"type":"number"},"newBalance":{"type":"number"},"transactionId":{"type":"string","format":"uuid"}},"required":["ok","previousBalance","newBalance","transactionId"]}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"Not a platform admin","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Tenant not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/releases":{"get":{"tags":["Releases"],"summary":"List releases","description":"Returns all releases. Platform admins see drafts and silent releases; non-admins see only published, non-silent entries.","responses":{"200":{"description":"List of releases","content":{"application/json":{"schema":{"type":"object","properties":{"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"version":{"type":"string"},"title":{"type":"string"},"internalBody":{"type":["string","null"]},"customerBody":{"type":["string","null"]},"linkedIssues":{"type":["array","null"],"items":{"type":"object","properties":{"number":{"type":"number"},"title":{"type":"string"},"url":{"type":"string"}},"required":["number","title","url"]}},"visibility":{"type":"string","enum":["customer","internal","silent"]},"deployedAt":{"type":"string","format":"date-time"},"publishedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","version","title","internalBody","customerBody","linkedIssues","visibility","deployedAt","publishedAt","createdAt","updatedAt"]}}},"required":["releases"]}}}},"401":{"description":"Unauthorized"}}},"post":{"tags":["Releases"],"summary":"Create release","description":"Creates a new release entry. Platform admin only. Version must be unique and follow YYYY.MM.DD[.N] format.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string"},"title":{"type":"string"},"internalBody":{"type":"string"},"customerBody":{"type":"string"},"linkedIssues":{"type":"array","items":{"type":"object","properties":{"number":{"type":"number"},"title":{"type":"string"},"url":{"type":"string"}},"required":["number","title","url"]}},"visibility":{"type":"string","enum":["customer","internal","silent"]},"deployedAt":{"type":"string","format":"date-time"},"publishedAt":{"type":["string","null"],"format":"date-time"}},"required":["version","title","deployedAt"]}}}},"responses":{"201":{"description":"Release created","content":{"application/json":{"schema":{"type":"object","properties":{"release":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"version":{"type":"string"},"title":{"type":"string"},"internalBody":{"type":["string","null"]},"customerBody":{"type":["string","null"]},"linkedIssues":{"type":["array","null"],"items":{"type":"object","properties":{"number":{"type":"number"},"title":{"type":"string"},"url":{"type":"string"}},"required":["number","title","url"]}},"visibility":{"type":"string","enum":["customer","internal","silent"]},"deployedAt":{"type":"string","format":"date-time"},"publishedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","version","title","internalBody","customerBody","linkedIssues","visibility","deployedAt","publishedAt","createdAt","updatedAt"]}},"required":["release"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden — platform admin required"},"409":{"description":"Version already exists"}}}},"/api/releases/latest":{"get":{"tags":["Releases"],"summary":"Latest release version","description":"Returns the most recent release version and deploy timestamp. Public endpoint (no auth required). Used by client-side hot swap polling. Cached for 60 seconds.","security":[],"responses":{"200":{"description":"Latest release","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":["string","null"]},"deployedAt":{"type":["string","null"],"format":"date-time"}},"required":["version","deployedAt"]}}}}}}},"/api/releases/{version}":{"get":{"tags":["Releases"],"summary":"Get release by version","description":"Returns a single release. Non-admins only see published, non-silent releases.","parameters":[{"schema":{"type":"string"},"required":true,"name":"version","in":"path"}],"responses":{"200":{"description":"Release detail","content":{"application/json":{"schema":{"type":"object","properties":{"release":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"version":{"type":"string"},"title":{"type":"string"},"internalBody":{"type":["string","null"]},"customerBody":{"type":["string","null"]},"linkedIssues":{"type":["array","null"],"items":{"type":"object","properties":{"number":{"type":"number"},"title":{"type":"string"},"url":{"type":"string"}},"required":["number","title","url"]}},"visibility":{"type":"string","enum":["customer","internal","silent"]},"deployedAt":{"type":"string","format":"date-time"},"publishedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","version","title","internalBody","customerBody","linkedIssues","visibility","deployedAt","publishedAt","createdAt","updatedAt"]}},"required":["release"]}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not found"}}},"patch":{"tags":["Releases"],"summary":"Update release","description":"Updates an existing release. Platform admin only. Set publishedAt to make visible on changelog, null to unpublish.","parameters":[{"schema":{"type":"string"},"required":true,"name":"version","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"internalBody":{"type":["string","null"]},"customerBody":{"type":["string","null"]},"linkedIssues":{"type":["array","null"],"items":{"type":"object","properties":{"number":{"type":"number"},"title":{"type":"string"},"url":{"type":"string"}},"required":["number","title","url"]}},"visibility":{"type":"string","enum":["customer","internal","silent"]},"deployedAt":{"type":"string","format":"date-time"},"publishedAt":{"type":["string","null"],"format":"date-time"}}}}}},"responses":{"200":{"description":"Release updated","content":{"application/json":{"schema":{"type":"object","properties":{"release":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"version":{"type":"string"},"title":{"type":"string"},"internalBody":{"type":["string","null"]},"customerBody":{"type":["string","null"]},"linkedIssues":{"type":["array","null"],"items":{"type":"object","properties":{"number":{"type":"number"},"title":{"type":"string"},"url":{"type":"string"}},"required":["number","title","url"]}},"visibility":{"type":"string","enum":["customer","internal","silent"]},"deployedAt":{"type":"string","format":"date-time"},"publishedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","version","title","internalBody","customerBody","linkedIssues","visibility","deployedAt","publishedAt","createdAt","updatedAt"]}},"required":["release"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden — platform admin required"},"404":{"description":"Not found"}}}},"/api/releases/generate":{"post":{"tags":["Releases"],"summary":"Auto-generate release notes","description":"Generates a draft release entry from merged commits since the last release. Groups by conventional commit prefix. Platform admin only.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"sinceVersion":{"type":"string"}}}}}},"responses":{"201":{"description":"Draft release generated","content":{"application/json":{"schema":{"type":"object","properties":{"release":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"version":{"type":"string"},"title":{"type":"string"},"internalBody":{"type":["string","null"]},"customerBody":{"type":["string","null"]},"linkedIssues":{"type":["array","null"],"items":{"type":"object","properties":{"number":{"type":"number"},"title":{"type":"string"},"url":{"type":"string"}},"required":["number","title","url"]}},"visibility":{"type":"string","enum":["customer","internal","silent"]},"deployedAt":{"type":"string","format":"date-time"},"publishedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","version","title","internalBody","customerBody","linkedIssues","visibility","deployedAt","publishedAt","createdAt","updatedAt"]},"generated":{"type":"boolean","enum":[true]}},"required":["release","generated"]}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden — platform admin required"}}}},"/api/invitation-requests":{"post":{"tags":["Invitation Requests"],"summary":"Submit an invitation request","description":"Public endpoint for requesting early access to Dictiva. Requires a corporate email (free email providers are rejected). Sends a notification to the Dictiva team for review.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationRequestBody"}}}},"responses":{"201":{"description":"Invitation request submitted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationRequestResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationRequestError"}}}},"409":{"description":"Duplicate request — email already submitted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationRequestError"}}}},"422":{"description":"Corporate email required — free email providers rejected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationRequestError"}}}}}}}},"webhooks":{}}