Files
ai-gateway-go/api/openapi/gateway.yaml
T
superidou 5759c1862e AI Gateway Go 0.10.0 源码快照 + 旗舰版需求规划报告
M0-M7 已完成:核心网关(身份/RBAC/TOTP/OIDC/SAML/Provider/配额/路由/内容策略/审计/定价)+ 资源市场(MCP/Skills/数字员工)。
含 22 个 PostgreSQL 迁移、管理端/门户端前端源码、OpenAPI 契约、部署 compose。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-12 11:45:54 +08:00

1628 lines
68 KiB
YAML

openapi: 3.1.0
info:
title: AI Gateway Runtime API
version: 0.10.0
description: Go rewrite contract. OpenAI-compatible payloads remain intentionally open.
servers:
- url: /
paths:
/healthz:
get:
operationId: getHealth
responses:
"200":
description: Process is alive
content:
application/json:
schema:
$ref: "#/components/schemas/Health"
/readyz:
get:
operationId: getReadiness
responses:
"200":
description: Required dependencies are ready
"503":
description: A required dependency is unavailable
/metrics:
get:
operationId: getMetrics
responses:
"200": { description: Prometheus text metrics for runtime, audit, bootstrap and shadow traffic }
/api/v1/admin/login:
post:
operationId: loginAdmin
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/LoginRequest" }
responses:
"200": { description: Opaque Redis-backed session token }
"401": { description: Invalid credentials }
"429": { description: Account locked }
/api/v1/admin/whoami:
get:
operationId: getAdminIdentity
security: [{ bearerAuth: [] }]
responses:
"200": { description: Active administrator identity and role }
"401": { description: Invalid or expired session }
/api/v1/admin/password:
post:
operationId: changeAdminPassword
security: [{ bearerAuth: [] }]
responses:
"200": { description: Administrator password changed after current-password verification }
"401": { description: Current password invalid }
/api/v1/admin/system-info:
get:
operationId: getSystemInfo
security: [{ bearerAuth: [] }]
responses: { "200": { description: Version, runtime, uptime and enabled resource counts } }
/api/v1/admin/monitoring/overview:
get:
operationId: getMonitoringOverview
security: [{ bearerAuth: [] }]
responses: { "200": { description: PostgreSQL-backed 24-hour request, token, cost and latency summary } }
/api/v1/admin/reload:
post:
operationId: reloadRuntimeSnapshots
security: [{ bearerAuth: [] }]
responses: { "200": { description: Provider, content-policy and pricing snapshots reloaded } }
/api/v1/admin/fact-check/settings:
get:
operationId: getFactCheckSettings
security: [{ bearerAuth: [] }]
responses: { "200": { description: Fact-check Provider reference, model and timeout without duplicated credentials } }
put:
operationId: updateFactCheckSettings
security: [{ bearerAuth: [] }]
responses: { "200": { description: Fact-check settings updated } }
/api/v1/admin/fact-check/policies:
get:
operationId: listFactCheckPolicies
security: [{ bearerAuth: [] }]
responses: { "200": { description: Scoped fact-check policies } }
post:
operationId: createFactCheckPolicy
security: [{ bearerAuth: [] }]
responses: { "200": { description: Validated fact-check policy created } }
/api/v1/admin/fact-check/policies/{policy_id}:
put:
operationId: updateFactCheckPolicy
security: [{ bearerAuth: [] }]
parameters: [{ name: policy_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Fact-check policy revision updated } }
delete:
operationId: deleteFactCheckPolicy
security: [{ bearerAuth: [] }]
parameters: [{ name: policy_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Fact-check policy deleted } }
/api/v1/admin/fact-check/events:
get:
operationId: listFactCheckEvents
security: [{ bearerAuth: [] }]
responses: { "200": { description: Bounded fact-check event summaries } }
/api/v1/admin/fact-check/events/{event_id}:
get:
operationId: getFactCheckEvent
security: [{ bearerAuth: [] }]
parameters: [{ name: event_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Fact-check claims and evidence detail } }
/api/v1/admin/login/totp:
post:
operationId: completeAdminTOTPLogin
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/TOTPLoginRequest" }
responses:
"200": { description: TOTP challenge completed and session issued }
"401": { description: Invalid, reused, or consumed factor }
/api/v1/admin/totp/status:
get:
operationId: getAdminTOTPStatus
security: [{ bearerAuth: [] }]
responses:
"200": { description: TOTP enrollment status }
/api/v1/admin/totp/setup:
post:
operationId: setupAdminTOTP
security: [{ bearerAuth: [] }]
responses:
"200": { description: New secret and otpauth provisioning URI }
/api/v1/admin/totp/confirm:
post:
operationId: confirmAdminTOTP
security: [{ bearerAuth: [] }]
responses:
"200": { description: Enrollment confirmed; backup codes returned once }
/api/v1/admin/totp/disable:
post:
operationId: disableAdminTOTP
security: [{ bearerAuth: [] }]
responses:
"200": { description: TOTP disabled after password and factor verification }
/api/v1/admin/totp/backup-codes/regenerate:
post:
operationId: regenerateAdminTOTPBackupCodes
security: [{ bearerAuth: [] }]
responses:
"200": { description: Previous backup codes revoked and replacements returned once }
/api/v1/admin/logout:
post:
operationId: logoutAdmin
security: [{ bearerAuth: [] }]
responses:
"200": { description: Session revoked }
/api/v1/admin/menus:
get:
operationId: getAdminMenus
security: [{ bearerAuth: [] }]
responses:
"200": { description: Art Design Pro route tree for the active role }
/api/v1/admin/identities/admins:
get:
operationId: listAdministrators
security: [{ bearerAuth: [] }]
responses:
"200": { description: Administrator accounts with direct and effective permissions }
"403": { description: identity:manage permission required }
post:
operationId: createAdministrator
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/IdentityInput" }
responses:
"200": { description: Administrator created and outbox event committed }
"409": { description: Login already exists }
/api/v1/admin/identities/admins/{identity_id}:
put:
operationId: updateAdministrator
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/IdentityID"
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/IdentityInput" }
responses:
"200": { description: Account and permissions updated immediately }
"409": { description: Self-disable, self-role change, or duplicate login }
/api/v1/admin/identities/portal-users:
get:
operationId: listPortalUsers
security: [{ bearerAuth: [] }]
responses:
"200": { description: Portal accounts with direct and effective permissions }
post:
operationId: createPortalUser
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/IdentityInput" }
responses:
"200": { description: Local portal account created }
/api/v1/admin/identities/portal-users/{identity_id}:
put:
operationId: updatePortalUser
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/IdentityID"
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/IdentityInput" }
responses:
"200": { description: Portal account updated }
/api/v1/admin/departments:
get:
operationId: listDepartments
security: [{ bearerAuth: [] }]
responses:
"200": { description: Flat department catalog with parent names and active user counts }
post:
operationId: createDepartment
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/DepartmentInput" }
responses:
"200": { description: Department created with outbox event }
"409": { description: Duplicate code or invalid hierarchy }
/api/v1/admin/departments/{department_id}:
put:
operationId: updateDepartment
security: [{ bearerAuth: [] }]
parameters:
- name: department_id
in: path
required: true
schema: { type: string, format: uuid }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/DepartmentInput" }
responses:
"200": { description: Department updated with hierarchy validation }
"409": { description: Cycle or active users/children prevent the update }
/api/v1/admin/identity-providers:
get:
operationId: listIdentityProviders
security: [{ bearerAuth: [] }]
responses:
"200": { description: OIDC providers without client secret material }
post:
operationId: createIdentityProvider
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/OIDCProviderInput" }
responses:
"200": { description: Encrypted OIDC provider configuration created }
/api/v1/admin/identity-providers/{provider_id}:
put:
operationId: updateIdentityProvider
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/ProviderID"
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/OIDCProviderInput" }
responses:
"200": { description: OIDC provider updated; omitted secret remains unchanged }
/api/v1/admin/saml-providers:
get:
operationId: listSAMLProviders
security: [{ bearerAuth: [] }]
responses:
"200": { description: SAML identity provider configurations }
post:
operationId: createSAMLProvider
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/SAMLProviderInput" }
responses:
"200": { description: SAML provider created after metadata and signing certificate validation }
/api/v1/admin/saml-providers/{provider_id}:
put:
operationId: updateSAMLProvider
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/ProviderID"
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/SAMLProviderInput" }
responses:
"200": { description: SAML provider updated and revision incremented }
/api/v1/admin/providers:
get:
operationId: listProviders
security: [{ bearerAuth: [] }]
responses:
"200": { description: Providers with masked credentials }
post:
operationId: createProvider
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/ProviderInput" }
responses:
"200": { description: Provider created and outbox event committed }
"403": { description: Superadmin role required }
/api/v1/admin/api-keys:
get:
operationId: listAPIKeys
security: [{ bearerAuth: [] }]
responses:
"200": { description: API keys without secret material }
"403": { description: Superadmin role required }
post:
operationId: createAPIKey
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/APIKeyInput" }
responses:
"200": { description: API key secret returned exactly once }
/api/v1/admin/api-keys/{api_key_id}:
delete:
operationId: revokeAPIKey
security: [{ bearerAuth: [] }]
parameters:
- name: api_key_id
in: path
required: true
schema: { type: string, format: uuid }
responses:
"200": { description: Key revoked and shared cache invalidated }
"404": { description: Key not found or already revoked }
/api/v1/admin/api-keys/{api_key_id}/limits:
put:
operationId: updateAPIKeyLimits
security: [{ bearerAuth: [] }]
parameters:
- name: api_key_id
in: path
required: true
schema: { type: string, format: uuid }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/APIKeyLimitsInput" }
responses:
"200": { description: Request and token limits updated; authentication cache invalidated }
"404": { description: Key not found or already revoked }
/api/v1/admin/model-routes:
get:
operationId: listModelRoutes
security: [{ bearerAuth: [] }]
responses:
"200": { description: Model alias and weighted route rules }
post:
operationId: createModelRoute
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/ModelRouteInput" }
responses:
"200": { description: Route committed, snapshot refreshed, and peers notified }
"409": { description: Duplicate route }
/api/v1/admin/model-routes/{model_route_id}:
put:
operationId: updateModelRoute
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/ModelRouteID"
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/ModelRouteInput" }
responses:
"200": { description: Route updated and active snapshots refreshed }
"404": { description: Route not found }
delete:
operationId: deleteModelRoute
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/ModelRouteID"
responses:
"200": { description: Route deleted and active snapshots refreshed }
"404": { description: Route not found }
/api/v1/admin/audit-events:
get:
operationId: listAuditEvents
security: [{ bearerAuth: [] }]
parameters:
- { name: from, in: query, schema: { type: string, format: date-time } }
- { name: to, in: query, schema: { type: string, format: date-time } }
- { name: before, in: query, schema: { type: string, format: date-time } }
- { name: api_key_id, in: query, schema: { type: string, format: uuid } }
- { name: provider, in: query, schema: { type: string } }
- { name: model, in: query, schema: { type: string } }
- { name: status, in: query, schema: { type: integer, minimum: 100, maximum: 599 } }
- { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 50 } }
responses:
"200": { description: Cursor-paginated gateway audit events }
"403": { description: audit:read permission required }
/api/v1/admin/usage/daily:
get:
operationId: listDailyUsage
security: [{ bearerAuth: [] }]
parameters:
- { name: from, in: query, schema: { type: string, format: date } }
- { name: to, in: query, schema: { type: string, format: date } }
- { name: api_key_id, in: query, schema: { type: string, format: uuid } }
- { name: provider, in: query, schema: { type: string } }
- { name: model, in: query, schema: { type: string } }
responses:
"200": { description: Daily request, failure, and token aggregates }
"403": { description: usage:read permission required }
/api/v1/admin/outbox-events:
get:
operationId: listOutboxEvents
security: [{ bearerAuth: [] }]
parameters:
- { name: status, in: query, schema: { type: string, enum: [pending, dead, processed] } }
- { name: type, in: query, schema: { type: string } }
- { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 500, default: 100 } }
responses:
"200": { description: Pending, dead-lettered, or processed transactional outbox events }
"403": { description: outbox:read permission required }
/api/v1/admin/outbox-events/{event_id}/retry:
post:
operationId: retryOutboxEvent
security: [{ bearerAuth: [] }]
parameters:
- name: event_id
in: path
required: true
schema: { type: string, format: uuid }
responses:
"200": { description: Pending or dead-lettered event made immediately claimable }
"403": { description: outbox:manage permission required }
"404": { description: Unprocessed event not found }
/api/v1/admin/content-policies:
get:
operationId: listContentPolicies
security: [{ bearerAuth: [] }]
responses:
"200": { description: Ordered content policy definitions }
"403": { description: content_policy:read permission required }
post:
operationId: createContentPolicy
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/ContentPolicyInput" }
responses:
"200": { description: Policy committed, compiled, and activated locally }
"400": { description: Invalid RE2 rule or policy scope }
/api/v1/admin/content-policies/{policy_id}:
put:
operationId: updateContentPolicy
security: [{ bearerAuth: [] }]
parameters: [{ name: policy_id, in: path, required: true, schema: { type: string, format: uuid } }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/ContentPolicyInput" }
responses:
"200": { description: Policy revision updated and snapshot reloaded }
"404": { description: Policy not found }
delete:
operationId: deleteContentPolicy
security: [{ bearerAuth: [] }]
parameters: [{ name: policy_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses:
"200": { description: Policy deleted and snapshot reloaded }
/api/v1/admin/model-prices:
get:
operationId: listModelPrices
security: [{ bearerAuth: [] }]
responses:
"200": { description: Versioned model price definitions }
"403": { description: pricing:read permission required }
post:
operationId: createModelPrice
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/ModelPriceInput" }
responses:
"200": { description: Price version created and runtime snapshot reloaded }
/api/v1/admin/model-prices/{price_id}:
put:
operationId: updateModelPrice
security: [{ bearerAuth: [] }]
parameters: [{ name: price_id, in: path, required: true, schema: { type: string, format: uuid } }]
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/ModelPriceInput" }
responses:
"200": { description: Price revision updated and runtime snapshot reloaded }
delete:
operationId: deleteModelPrice
security: [{ bearerAuth: [] }]
parameters: [{ name: price_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses:
"200": { description: Price version deleted }
/api/v1/admin/prompts:
get:
operationId: listPrompts
security: [{ bearerAuth: [] }]
responses: { "200": { description: Prompt templates and active immutable versions } }
post:
operationId: createPrompt
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/PromptInput" } } } }
responses: { "200": { description: Template and initial immutable version created } }
/api/v1/admin/prompts/{prompt_id}:
get:
operationId: getPrompt
security: [{ bearerAuth: [] }]
parameters: [{ name: prompt_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Prompt metadata and current immutable version } }
put:
operationId: updatePromptMetadata
security: [{ bearerAuth: [] }]
parameters: [{ name: prompt_id, in: path, required: true, schema: { type: string, format: uuid } }]
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/PromptInput" } } } }
responses: { "200": { description: Prompt metadata updated without mutating version content } }
delete:
operationId: deletePrompt
security: [{ bearerAuth: [] }]
parameters: [{ name: prompt_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Prompt and versions deleted } }
/api/v1/admin/prompts/{prompt_id}/versions:
get:
operationId: listPromptVersions
security: [{ bearerAuth: [] }]
parameters: [{ name: prompt_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Immutable Prompt version history } }
post:
operationId: createPromptVersion
security: [{ bearerAuth: [] }]
parameters: [{ name: prompt_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: New immutable version created and optionally activated } }
/api/v1/admin/prompts/{prompt_id}/versions/{version}/activate:
post:
operationId: activatePromptVersion
security: [{ bearerAuth: [] }]
parameters:
- { name: prompt_id, in: path, required: true, schema: { type: string, format: uuid } }
- { name: version, in: path, required: true, schema: { type: integer, minimum: 1 } }
responses: { "200": { description: Historical immutable version made current } }
/api/v1/admin/prompts/{prompt_id}/render:
post:
operationId: previewPrompt
security: [{ bearerAuth: [] }]
parameters: [{ name: prompt_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Current Prompt rendered for control-plane preview } }
/api/v1/admin/prompt-categories:
get:
operationId: listPromptCategories
security: [{ bearerAuth: [] }]
responses: { "200": { description: Prompt categories with template counts } }
post:
operationId: createPromptCategory
security: [{ bearerAuth: [] }]
responses: { "200": { description: Prompt category created } }
/api/v1/admin/prompt-categories/{category_id}:
delete:
operationId: deletePromptCategory
security: [{ bearerAuth: [] }]
parameters: [{ name: category_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Category removed and templates made uncategorized } }
/api/v1/admin/knowledge-bases:
get:
operationId: listKnowledgeBases
security: [{ bearerAuth: [] }]
responses: { "200": { description: PostgreSQL-backed knowledge bases } }
post:
operationId: createKnowledgeBase
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/KnowledgeBaseInput" } } } }
responses: { "200": { description: Knowledge base created } }
/api/v1/admin/knowledge-bases/{knowledge_base_id}:
put:
operationId: updateKnowledgeBase
security: [{ bearerAuth: [] }]
parameters: [{ name: knowledge_base_id, in: path, required: true, schema: { type: string, format: uuid } }]
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/KnowledgeBaseInput" } } } }
responses: { "200": { description: Knowledge base updated } }
delete:
operationId: deleteKnowledgeBase
security: [{ bearerAuth: [] }]
parameters: [{ name: knowledge_base_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Unreferenced knowledge base deleted } }
/api/v1/admin/knowledge-bases/{knowledge_base_id}/documents:
get:
operationId: listKnowledgeDocuments
security: [{ bearerAuth: [] }]
parameters: [{ name: knowledge_base_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Bounded extracted-text documents } }
post:
operationId: addKnowledgeDocument
security: [{ bearerAuth: [] }]
parameters: [{ name: knowledge_base_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Document stored in PostgreSQL and synchronously chunked } }
/api/v1/admin/knowledge-bases/{knowledge_base_id}/documents/{document_id}:
delete:
operationId: deleteKnowledgeDocument
security: [{ bearerAuth: [] }]
parameters:
- { name: knowledge_base_id, in: path, required: true, schema: { type: string, format: uuid } }
- { name: document_id, in: path, required: true, schema: { type: string, format: uuid } }
responses: { "200": { description: Document and chunks deleted } }
/api/v1/admin/knowledge-bases/{knowledge_base_id}/documents/{document_id}/reprocess:
post:
operationId: reprocessKnowledgeDocument
security: [{ bearerAuth: [] }]
parameters:
- { name: knowledge_base_id, in: path, required: true, schema: { type: string, format: uuid } }
- { name: document_id, in: path, required: true, schema: { type: string, format: uuid } }
responses: { "200": { description: Stored bounded text re-chunked transactionally } }
/api/v1/admin/knowledge-bases/{knowledge_base_id}/search:
post:
operationId: testKnowledgeSearch
security: [{ bearerAuth: [] }]
parameters: [{ name: knowledge_base_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Retriever test results } }
/api/v1/admin/tools:
get:
operationId: listTools
security: [{ bearerAuth: [] }]
responses: { "200": { description: HTTP tool definitions without decrypted secret headers } }
post:
operationId: createTool
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/ToolInput" } } } }
responses: { "200": { description: SSRF-validated tool with encrypted headers created } }
/api/v1/admin/tools/{tool_id}:
put:
operationId: updateTool
security: [{ bearerAuth: [] }]
parameters: [{ name: tool_id, in: path, required: true, schema: { type: string, format: uuid } }]
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/ToolInput" } } } }
responses: { "200": { description: Tool revision updated } }
delete:
operationId: deleteTool
security: [{ bearerAuth: [] }]
parameters: [{ name: tool_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Unreferenced tool deleted } }
/api/v1/admin/tools/{tool_id}/test:
post:
operationId: testTool
security: [{ bearerAuth: [] }]
parameters: [{ name: tool_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Bounded SSRF-safe administrative tool test } }
/api/v1/admin/applications:
get:
operationId: listApplications
security: [{ bearerAuth: [] }]
responses: { "200": { description: Application drafts and current published versions } }
post:
operationId: createApplication
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/ApplicationInput" } } } }
responses: { "200": { description: Application draft created } }
/api/v1/admin/applications/catalog:
get:
operationId: getApplicationCompositionCatalog
security: [{ bearerAuth: [] }]
responses: { "200": { description: Prompt, knowledge and tool assets available for composition } }
/api/v1/admin/applications/asset-dependencies:
get:
operationId: getApplicationAssetDependencies
security: [{ bearerAuth: [] }]
parameters:
- { name: asset_type, in: query, required: true, schema: { type: string, enum: [prompt, knowledge, tool] } }
- { name: asset_id, in: query, required: true, schema: { type: string, format: uuid } }
responses: { "200": { description: Draft and published application references to an asset } }
/api/v1/admin/applications/{application_id}/publish:
post:
operationId: publishApplication
security: [{ bearerAuth: [] }]
parameters: [{ name: application_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Validated immutable application composition published } }
/api/v1/admin/applications/{application_id}:
get:
operationId: getApplication
security: [{ bearerAuth: [] }]
parameters: [{ name: application_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Application composition and immutable version history } }
put:
operationId: updateApplication
security: [{ bearerAuth: [] }]
parameters: [{ name: application_id, in: path, required: true, schema: { type: string, format: uuid } }]
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/ApplicationInput" } } } }
responses: { "200": { description: Application draft updated } }
delete:
operationId: deleteApplication
security: [{ bearerAuth: [] }]
parameters: [{ name: application_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Application and its versions deleted } }
/api/v1/admin/applications/{application_id}/rollback/{version}:
post:
operationId: rollbackApplication
security: [{ bearerAuth: [] }]
parameters:
- { name: application_id, in: path, required: true, schema: { type: string, format: uuid } }
- { name: version, in: path, required: true, schema: { type: integer, minimum: 1 } }
responses: { "200": { description: Historical composition copied into a new immutable published version } }
/api/v1/admin/applications/{application_id}/versions:
get:
operationId: listApplicationVersions
security: [{ bearerAuth: [] }]
parameters: [{ name: application_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Immutable application publication history } }
/api/v1/admin/applications/{application_id}/runs:
get:
operationId: listApplicationRuns
security: [{ bearerAuth: [] }]
parameters: [{ name: application_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Recent application orchestration runs } }
/api/v1/admin/notification-channels:
get:
operationId: listNotificationChannels
security: [{ bearerAuth: [] }]
responses: { "200": { description: Webhook subscriptions without decrypted signing secrets } }
post:
operationId: createNotificationChannel
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/NotificationChannelInput" } } } }
responses: { "200": { description: Signed Webhook subscription created } }
/api/v1/admin/notification-deliveries:
get:
operationId: listNotificationDeliveries
security: [{ bearerAuth: [] }]
responses: { "200": { description: Durable Webhook delivery history } }
/api/v1/admin/notification-channels/{channel_id}:
put:
operationId: updateNotificationChannel
security: [{ bearerAuth: [] }]
parameters: [{ name: channel_id, in: path, required: true, schema: { type: string, format: uuid } }]
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/NotificationChannelInput" } } } }
responses: { "200": { description: Notification channel updated } }
delete:
operationId: deleteNotificationChannel
security: [{ bearerAuth: [] }]
parameters: [{ name: channel_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Notification channel and deliveries deleted } }
/api/v1/admin/notification-deliveries/{delivery_id}/retry:
post:
operationId: retryNotificationDelivery
security: [{ bearerAuth: [] }]
parameters: [{ name: delivery_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Failed delivery attempted immediately } }
/v1/prompts:
get:
operationId: listRuntimePrompts
security: [{ apiKeyAuth: [] }]
responses: { "200": { description: Visible enabled Prompt definitions without template bodies } }
/v1/prompts/{prompt_name}/render:
post:
operationId: renderPrompt
security: [{ apiKeyAuth: [] }]
parameters: [{ name: prompt_name, in: path, required: true, schema: { type: string } }]
responses: { "200": { description: Active template rendered after required-variable validation } }
/v1/knowledge/{knowledge_base_id}/search:
post:
operationId: searchKnowledge
security: [{ apiKeyAuth: [] }]
parameters: [{ name: knowledge_base_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Department-scoped Retriever results } }
/v1/knowledge/search:
post:
operationId: searchKnowledgeLegacyShape
security: [{ apiKeyAuth: [] }]
responses: { "200": { description: Knowledge search with knowledge_base_id in the JSON body } }
/v1/tools:
get:
operationId: listRuntimeTools
security: [{ apiKeyAuth: [] }]
responses: { "200": { description: Department-scoped tool schemas without encrypted headers } }
/v1/tools/{tool_code}/invoke:
post:
operationId: invokeTool
security: [{ apiKeyAuth: [] }]
parameters: [{ name: tool_code, in: path, required: true, schema: { type: string } }]
responses: { "200": { description: Schema-validated, SSRF-safe bounded HTTP tool result } }
/v1/applications/{application_code}/chat/completions:
post:
operationId: runApplication
security: [{ apiKeyAuth: [] }]
parameters: [{ name: application_code, in: path, required: true, schema: { type: string } }]
responses: { "200": { description: Prompt, retrieval and bounded tool loop executed through the governed gateway } }
/api/v1/admin/providers/{provider_id}:
put:
operationId: updateProvider
security: [{ bearerAuth: [] }]
parameters:
- name: provider_id
in: path
required: true
schema: { type: string, format: uuid }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/ProviderInput" }
responses:
"200": { description: Provider updated and revision incremented }
"404": { description: Provider not found }
/api/v1/admin/providers/{provider_id}/test:
post:
operationId: testProviderConnection
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/ProviderID"
responses:
"200":
description: Bounded connectivity test against the upstream models endpoint
content:
application/json:
schema: { $ref: "#/components/schemas/ProviderConnectionResult" }
"404": { description: Provider not found }
"502": { description: Upstream network request failed }
/api/v1/admin/providers/{provider_id}/models:
get:
operationId: listProviderModels
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/ProviderID"
responses:
"200":
description: Current and historical provider model catalog
"404": { description: Provider not found }
/api/v1/admin/providers/{provider_id}/models/sync:
post:
operationId: syncProviderModels
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/ProviderID"
responses:
"200":
description: Model catalog transactionally synchronized and outbox event committed
content:
application/json:
schema: { $ref: "#/components/schemas/ModelSyncResult" }
"404": { description: Provider not found }
"502": { description: Upstream response failed validation }
/api/v1/admin/providers/credentials/rotate:
post:
operationId: rotateProviderCredentials
description: Re-encrypt every Provider credential not already using the active KEK version.
security: [{ bearerAuth: [] }]
responses:
"200":
description: All required credential updates and outbox events committed atomically
content:
application/json:
schema: { $ref: "#/components/schemas/CredentialRotationResult" }
/api/v1/portal/login:
post:
operationId: loginPortal
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/LoginRequest" }
responses:
"200": { description: Opaque Redis-backed portal session token }
"401": { description: Invalid credentials }
/api/v1/portal/sso/providers:
get:
operationId: listPublicSSOProviders
responses:
"200": { description: Enabled OIDC and SAML providers safe for login-page display }
/api/v1/portal/sso/{provider_code}/start:
get:
operationId: startSSOLogin
parameters:
- name: provider_code
in: path
required: true
schema: { type: string }
responses:
"302": { description: Redirect to the OIDC authorization endpoint or SAML Redirect-binding SSO endpoint }
/api/v1/portal/sso/{provider_code}/callback:
get:
operationId: completeOIDCLogin
parameters:
- name: provider_code
in: path
required: true
schema: { type: string }
responses:
"302": { description: Verified identity redirects with a one-minute single-use exchange code }
"401": { description: State or ID Token validation failed }
post:
operationId: completeSAMLLogin
parameters:
- name: provider_code
in: path
required: true
schema: { type: string }
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required: [SAMLResponse, RelayState]
properties:
SAMLResponse: { type: string, format: byte }
RelayState: { type: string }
responses:
"302": { description: Signed assertion accepted and browser redirected with a single-use exchange code }
"401": { description: Signature, request correlation, assertion, or replay validation failed }
/api/v1/portal/sso/{provider_code}/metadata:
get:
operationId: getSAMLServiceProviderMetadata
parameters:
- name: provider_code
in: path
required: true
schema: { type: string }
responses:
"200": { description: SAML Service Provider metadata XML }
"404": { description: SAML provider not found }
/api/v1/portal/sso/exchange:
post:
operationId: exchangeOIDCCode
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [code]
properties:
code: { type: string }
responses:
"200": { description: Redis-backed portal session token }
"401": { description: Exchange code invalid, expired, or already consumed }
/api/v1/portal/me:
get:
operationId: getPortalIdentity
security: [{ bearerAuth: [] }]
responses:
"200": { description: Active portal identity }
/api/v1/portal/login/totp:
post:
operationId: completePortalTOTPLogin
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/TOTPLoginRequest" }
responses:
"200": { description: TOTP challenge completed and session issued }
"401": { description: Invalid, reused, or consumed factor }
/api/v1/portal/totp/status:
get:
operationId: getPortalTOTPStatus
security: [{ bearerAuth: [] }]
responses:
"200": { description: TOTP enrollment status }
/api/v1/portal/totp/setup:
post:
operationId: setupPortalTOTP
security: [{ bearerAuth: [] }]
responses:
"200": { description: New secret and otpauth provisioning URI }
/api/v1/portal/totp/confirm:
post:
operationId: confirmPortalTOTP
security: [{ bearerAuth: [] }]
responses:
"200": { description: Enrollment confirmed; backup codes returned once }
/api/v1/portal/totp/disable:
post:
operationId: disablePortalTOTP
security: [{ bearerAuth: [] }]
responses:
"200": { description: TOTP disabled after password and factor verification }
/api/v1/portal/totp/backup-codes/regenerate:
post:
operationId: regeneratePortalTOTPBackupCodes
security: [{ bearerAuth: [] }]
responses:
"200": { description: Previous backup codes revoked and replacements returned once }
/api/v1/portal/logout:
post:
operationId: logoutPortal
security: [{ bearerAuth: [] }]
responses:
"200": { description: Session revoked }
/api/v1/portal/menus:
get:
operationId: getPortalMenus
security: [{ bearerAuth: [] }]
responses:
"200": { description: Art Design Pro portal route tree }
/api/v1/portal/password:
post:
operationId: changePortalPassword
security: [{ bearerAuth: [] }]
responses: { "200": { description: Local password changed after current-password verification } }
/api/v1/portal/applications:
get:
operationId: listPortalApplications
security: [{ bearerAuth: [] }]
responses: { "200": { description: Published applications visible to the portal user's department } }
/api/v1/portal/catalog:
get:
operationId: getPortalCatalog
security: [{ bearerAuth: [] }]
responses: { "200": { description: Department-scoped application and AI asset catalog } }
/api/v1/portal/knowledge:
get:
operationId: listPortalKnowledge
security: [{ bearerAuth: [] }]
responses: { "200": { description: Enabled visible knowledge bases } }
/api/v1/portal/tools:
get:
operationId: listPortalTools
security: [{ bearerAuth: [] }]
responses: { "200": { description: Enabled visible tool metadata without endpoint or secret headers } }
/api/v1/portal/prompts:
get:
operationId: listPortalPrompts
security: [{ bearerAuth: [] }]
responses: { "200": { description: Enabled visible prompts with favorite state } }
/api/v1/portal/prompts/{prompt_id}:
get:
operationId: getPortalPrompt
security: [{ bearerAuth: [] }]
parameters: [{ name: prompt_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Visible prompt and current immutable content } }
/api/v1/portal/prompts/{prompt_id}/favorite:
post:
operationId: favoritePortalPrompt
security: [{ bearerAuth: [] }]
parameters: [{ name: prompt_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Prompt added to favorites idempotently } }
delete:
operationId: unfavoritePortalPrompt
security: [{ bearerAuth: [] }]
parameters: [{ name: prompt_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Prompt removed from favorites idempotently } }
/api/v1/portal/model-requests/available:
get:
operationId: listPortalAvailableModels
security: [{ bearerAuth: [] }]
responses: { "200": { description: Enabled provider model catalog } }
/api/v1/portal/model-requests:
get:
operationId: listPortalModelRequests
security: [{ bearerAuth: [] }]
responses: { "200": { description: Current user's model access requests } }
post:
operationId: createPortalModelRequest
security: [{ bearerAuth: [] }]
responses: { "200": { description: Pending model access request created with outbox event } }
/api/v1/portal/logs:
get:
operationId: listPortalAuditEvents
security: [{ bearerAuth: [] }]
responses: { "200": { description: Bounded audit events owned through portal API keys } }
/api/v1/portal/logs/{audit_event_id}:
get:
operationId: getPortalAuditEvent
security: [{ bearerAuth: [] }]
parameters: [{ name: audit_event_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Owned audit event with bounded previews } }
/api/v1/portal/stats:
get:
operationId: getPortalStats
security: [{ bearerAuth: [] }]
responses: { "200": { description: Personal requests, tokens, cost and latency aggregate } }
/api/v1/portal/cost:
get:
operationId: getPortalCost
security: [{ bearerAuth: [] }]
responses: { "200": { description: Personal month-to-date cost in integer microunits } }
/api/v1/portal/docs-info:
get:
operationId: getPortalIntegrationDocs
security: [{ bearerAuth: [] }]
responses: { "200": { description: Safe runtime protocol and authentication overview } }
/api/v1/portal/apps/{application_code}/chat:
post:
operationId: runPortalApplicationCompatibilityChat
security: [{ bearerAuth: [] }]
parameters: [{ name: application_code, in: path, required: true, schema: { type: string } }]
responses: { "200": { description: Single user message executed with a server-held encrypted application credential } }
/api/v1/portal/apps/{application_code}/conversations:
post:
operationId: createPortalApplicationConversation
security: [{ bearerAuth: [] }]
parameters: [{ name: application_code, in: path, required: true, schema: { type: string } }]
responses: { "200": { description: Server-managed conversation created } }
/api/v1/portal/apps/{application_code}/conversations/{conversation_id}:
get:
operationId: getPortalApplicationConversation
security: [{ bearerAuth: [] }]
parameters:
- { name: application_code, in: path, required: true, schema: { type: string } }
- { name: conversation_id, in: path, required: true, schema: { type: string, format: uuid } }
responses: { "200": { description: Ownership-checked conversation with verified immutable hash chain } }
/api/v1/portal/apps/{application_code}/conversations/{conversation_id}/messages:
post:
operationId: appendPortalApplicationConversationMessage
security: [{ bearerAuth: [] }]
parameters:
- { name: application_code, in: path, required: true, schema: { type: string } }
- { name: conversation_id, in: path, required: true, schema: { type: string, format: uuid } }
responses: { "200": { description: Leased serial message execution with verified server-side history } }
/api/v1/admin/models:
get:
operationId: listAdministrativeModels
security: [{ bearerAuth: [] }]
responses: { "200": { description: Enabled provider model catalog } }
/api/v1/admin/model-requests:
get:
operationId: listAdministrativeModelRequests
security: [{ bearerAuth: [] }]
responses: { "200": { description: Portal model access requests by status } }
/api/v1/admin/model-requests/{request_id}/approve:
post:
operationId: approveModelRequest
security: [{ bearerAuth: [] }]
parameters: [{ name: request_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Pending request approved transactionally } }
/api/v1/admin/model-requests/{request_id}/reject:
post:
operationId: rejectModelRequest
security: [{ bearerAuth: [] }]
parameters: [{ name: request_id, in: path, required: true, schema: { type: string, format: uuid } }]
responses: { "200": { description: Pending request rejected transactionally } }
/v1/models:
get:
operationId: listModels
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/GatewayProvider"
responses:
"200": { description: OpenAI-compatible model list }
"429": { description: Per-minute, monthly request, or monthly token quota exceeded }
"503": { description: Authentication, admission control, or provider configuration unavailable }
/v1/chat/completions:
post:
operationId: createChatCompletion
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/GatewayProvider"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema: { type: object, additionalProperties: true }
responses:
"200": { description: JSON response or SSE stream }
"429": { description: Per-minute, monthly request, or monthly token quota exceeded }
"503": { description: Authentication, admission control, or provider configuration unavailable }
/v1/responses:
post:
operationId: createResponse
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/GatewayProvider"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema: { type: object, additionalProperties: true }
responses:
"200": { description: JSON response or SSE stream }
"429": { description: Per-minute, monthly request, or monthly token quota exceeded }
"503": { description: Authentication, admission control, or provider configuration unavailable }
/v1/embeddings:
post:
operationId: createEmbedding
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/GatewayProvider"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema: { type: object, additionalProperties: true }
responses:
"200": { description: OpenAI-compatible embedding response }
"429": { description: Per-minute, monthly request, or monthly token quota exceeded }
"503": { description: Authentication, admission control, or provider configuration unavailable }
/v1/messages:
post:
operationId: createAnthropicMessage
security: [{ bearerAuth: [] }]
parameters:
- $ref: "#/components/parameters/GatewayProvider"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema: { type: object, additionalProperties: true }
responses:
"200": { description: Anthropic-compatible response or SSE stream }
"429": { description: Per-minute, monthly request, or monthly token quota exceeded }
"503": { description: Authentication, admission control, or provider configuration unavailable }
components:
parameters:
ModelRouteID:
name: model_route_id
in: path
required: true
schema: { type: string, format: uuid }
IdempotencyKey:
name: Idempotency-Key
in: header
required: false
description: Enables bounded retries for replayable POST requests. Reusing a key is the caller's idempotency contract.
schema: { type: string, minLength: 1, maxLength: 255 }
IdentityID:
name: identity_id
in: path
required: true
schema: { type: string, format: uuid }
ProviderID:
name: provider_id
in: path
required: true
schema: { type: string, format: uuid }
GatewayProvider:
name: X-Gateway-Provider
in: header
required: false
description: Enabled database Provider code. Omit to use the current default snapshot entry.
schema: { type: string }
securitySchemes:
bearerAuth:
type: http
scheme: bearer
apiKeyAuth:
type: http
scheme: bearer
description: Gateway API Key with gateway:invoke scope; X-Gateway-API-Key is also accepted.
schemas:
Health:
type: object
required: [status, version]
properties:
status: { type: string, const: ok }
version: { type: string }
LoginRequest:
type: object
required: [userName, password]
properties:
userName: { type: string, minLength: 1, maxLength: 128 }
password: { type: string, minLength: 1, maxLength: 1024 }
TOTPLoginRequest:
type: object
required: [temp_token]
properties:
temp_token: { type: string, minLength: 1 }
code: { type: string, pattern: "^[0-9]{6}$" }
backup_code: { type: string, pattern: "^[A-Za-z2-9]{4}-?[A-Za-z2-9]{4}$" }
anyOf:
- required: [code]
- required: [backup_code]
ProviderInput:
type: object
required: [code, adapter, base_url, capabilities, config, enabled]
properties:
code:
type: string
pattern: "^[a-z][a-z0-9_-]{1,63}$"
adapter:
type: string
enum: [openai-compatible]
base_url: { type: string, format: uri }
api_key:
type: string
description: Omit during update to retain the existing encrypted credential.
capabilities:
type: array
items: { type: string }
config: { type: object, additionalProperties: true }
enabled: { type: boolean }
IdentityInput:
type: object
required: [login, display_name, role, permissions, active]
properties:
login: { type: string, minLength: 2, maxLength: 128 }
display_name: { type: string, maxLength: 64 }
role: { type: string, enum: [superadmin, operator, auditor, member] }
password:
type: string
minLength: 12
maxLength: 1024
description: Required on create; omit on update to retain the current password.
permissions:
type: array
uniqueItems: true
items:
type: string
pattern: "^[a-z][a-z0-9_.:-]{2,127}$|^\\*$"
active: { type: boolean }
department_id:
type: [string, "null"]
format: uuid
description: Portal accounts may bind to an active department.
DepartmentInput:
type: object
required: [code, name, description, active]
properties:
code: { type: string, pattern: "^[a-z][a-z0-9_-]{1,63}$" }
name: { type: string, minLength: 1, maxLength: 128 }
description: { type: string, maxLength: 1024 }
parent_id: { type: [string, "null"], format: uuid }
active: { type: boolean }
OIDCProviderInput:
type: object
required:
[code, display_name, issuer_url, client_id, redirect_uri, portal_return_url, scopes, auto_provision, enabled]
properties:
code: { type: string, pattern: "^[a-z][a-z0-9_-]{1,63}$" }
display_name: { type: string, minLength: 1, maxLength: 128 }
issuer_url: { type: string, format: uri }
client_id: { type: string, minLength: 1 }
client_secret:
type: string
description: Required on create and omitted on update to retain the encrypted value.
redirect_uri: { type: string, format: uri }
portal_return_url: { type: string, format: uri }
scopes:
type: array
contains: { const: openid }
items: { type: string }
auto_provision: { type: boolean }
default_department_id: { type: [string, "null"], format: uuid }
enabled: { type: boolean }
SAMLProviderInput:
type: object
required:
[code, display_name, metadata_url, sp_entity_id, acs_url, portal_return_url, email_attribute, name_attribute, auto_provision, enabled]
properties:
code: { type: string, pattern: "^[a-z][a-z0-9_-]{1,63}$" }
display_name: { type: string, minLength: 1, maxLength: 128 }
metadata_url: { type: string, format: uri }
sp_entity_id:
type: string
minLength: 1
maxLength: 512
description: Absolute URI used as the SAML audience.
acs_url:
type: string
format: uri
description: Must end with /api/v1/portal/sso/{code}/callback.
portal_return_url: { type: string, format: uri }
email_attribute: { type: string, maxLength: 256 }
name_attribute: { type: string, maxLength: 256 }
auto_provision: { type: boolean }
default_department_id: { type: [string, "null"], format: uuid }
enabled: { type: boolean }
ProviderConnectionResult:
type: object
required: [connected, latency_ms, message]
properties:
connected: { type: boolean }
status_code: { type: integer }
latency_ms: { type: integer, format: int64, minimum: 0 }
message: { type: string }
ProviderModel:
type: object
required:
[id, provider_id, provider_model_id, metadata, enabled, discovered_at, last_seen_at]
properties:
id: { type: string, format: uuid }
provider_id: { type: string, format: uuid }
provider_model_id: { type: string, minLength: 1, maxLength: 512 }
owned_by: { type: string }
metadata: { type: object, additionalProperties: true }
enabled: { type: boolean }
discovered_at: { type: string, format: date-time }
last_seen_at: { type: string, format: date-time }
ModelSyncResult:
type: object
required: [discovered, active, disabled, synced_at]
properties:
discovered: { type: integer, minimum: 0 }
active: { type: integer, minimum: 0 }
disabled: { type: integer, minimum: 0 }
synced_at: { type: string, format: date-time }
CredentialRotationResult:
type: object
required: [active_version, loaded_versions, rotated, skipped]
properties:
active_version: { type: integer, minimum: 1 }
loaded_versions:
type: array
items: { type: integer, minimum: 1 }
rotated: { type: integer, minimum: 0 }
skipped: { type: integer, minimum: 0 }
APIKeyInput:
type: object
required: [name, scopes, requests_per_minute, monthly_request_quota, monthly_token_quota]
properties:
name: { type: string, minLength: 1, maxLength: 128 }
scopes:
type: array
minItems: 1
items: { type: string, enum: [gateway:invoke, "*"] }
requests_per_minute:
type: integer
minimum: 0
maximum: 1000000
description: Per-API-key UTC minute request limit; zero means unlimited.
monthly_request_quota:
type: integer
format: int64
minimum: 0
maximum: 1000000000000
description: Accepted requests per UTC calendar month; zero means unlimited.
monthly_token_quota:
type: integer
format: int64
minimum: 0
maximum: 1000000000000000
description: Input plus output tokens per UTC calendar month; zero means unlimited.
expires_at: { type: [string, "null"], format: date-time }
APIKeyLimitsInput:
type: object
required: [requests_per_minute, monthly_request_quota, monthly_token_quota]
properties:
requests_per_minute: { type: integer, minimum: 0, maximum: 1000000 }
monthly_request_quota: { type: integer, format: int64, minimum: 0, maximum: 1000000000000 }
monthly_token_quota: { type: integer, format: int64, minimum: 0, maximum: 1000000000000000 }
ModelRouteInput:
type: object
required: [name, source_model, target_model, provider_id, weight, priority, conditions, enabled]
properties:
name: { type: string, minLength: 1, maxLength: 128 }
source_model: { type: string, minLength: 1, maxLength: 512 }
target_model: { type: string, minLength: 1, maxLength: 512 }
provider_id: { type: string, format: uuid }
weight: { type: integer, minimum: 1, maximum: 10000 }
priority: { type: integer, minimum: -100000, maximum: 100000 }
enabled: { type: boolean }
conditions:
type: object
additionalProperties: true
properties:
endpoints:
type: array
items: { type: string, enum: [/v1/chat/completions, /v1/responses, /v1/embeddings, /v1/messages] }
api_key_ids:
type: array
items: { type: string, format: uuid }
tenant_ids:
type: array
items: { type: string, format: uuid }
ContentPolicyInput:
type: object
required: [name, description, action, priority, paths, models, api_key_ids, rules, enabled]
properties:
name: { type: string, minLength: 1, maxLength: 128 }
description: { type: string, maxLength: 1000 }
action: { type: string, enum: [audit, block, redact] }
priority: { type: integer, minimum: -100000, maximum: 100000 }
paths: { type: array, items: { type: string } }
models: { type: array, items: { type: string } }
api_key_ids: { type: array, items: { type: string, format: uuid } }
enabled: { type: boolean }
rules:
type: array
minItems: 1
maxItems: 20
items:
type: object
required: [name, pattern, replacement]
properties:
name: { type: string, minLength: 1 }
pattern: { type: string, minLength: 1, maxLength: 512, description: Go RE2 expression }
replacement: { type: string }
ModelPriceInput:
type: object
required: [provider_code, model_pattern, input_microunits_per_million, output_microunits_per_million, currency, effective_from, enabled]
properties:
provider_code: { type: string, pattern: "^[a-z][a-z0-9_-]{1,63}$" }
model_pattern: { type: string, description: Exact model name or a prefix ending in one asterisk }
input_microunits_per_million: { type: integer, format: int64, minimum: 0 }
output_microunits_per_million: { type: integer, format: int64, minimum: 0 }
currency: { type: string, minLength: 3, maxLength: 3, default: USD }
effective_from: { type: string, format: date-time }
effective_to: { type: [string, "null"], format: date-time }
enabled: { type: boolean }
PromptVariable:
type: object
required: [name, required]
properties:
name: { type: string, pattern: "^[A-Za-z_][A-Za-z0-9_]*$" }
label: { type: string, maxLength: 128 }
default: { type: string, maxLength: 10000 }
required: { type: boolean }
PromptInput:
type: object
required: [name, description, tags, department_ids, enabled]
properties:
name: { type: string, minLength: 1, maxLength: 128 }
description: { type: string, maxLength: 4000 }
category_id: { type: [string, "null"], format: uuid }
tags: { type: array, maxItems: 30, items: { type: string } }
department_ids: { type: array, maxItems: 100, items: { type: string, format: uuid } }
enabled: { type: boolean }
content: { type: string, maxLength: 100000, description: Required only when creating the initial version. }
variables: { type: array, maxItems: 100, items: { $ref: "#/components/schemas/PromptVariable" } }
change_note: { type: string }
KnowledgeBaseInput:
type: object
required: [name, description, retrieval_mode, chunk_size, chunk_overlap, department_ids, enabled]
properties:
name: { type: string, minLength: 1, maxLength: 128 }
description: { type: string, maxLength: 4000 }
retrieval_mode: { type: string, enum: [postgres_fts] }
chunk_size: { type: integer, minimum: 200, maximum: 8000 }
chunk_overlap: { type: integer, minimum: 0 }
department_ids: { type: array, maxItems: 100, items: { type: string, format: uuid } }
enabled: { type: boolean }
ToolInput:
type: object
required: [code, name, description, endpoint_url, http_method, input_schema, timeout_seconds, department_ids, enabled]
properties:
code: { type: string, pattern: "^[a-z][a-z0-9_-]{1,63}$" }
name: { type: string, minLength: 1, maxLength: 128 }
description: { type: string, maxLength: 4000 }
endpoint_url: { type: string, format: uri }
http_method: { type: string, enum: [GET, POST, PUT, PATCH, DELETE] }
headers:
type: object
writeOnly: true
additionalProperties: { type: string }
description: Omit during update to preserve the existing KEK-encrypted headers.
input_schema: { type: object, additionalProperties: true }
timeout_seconds: { type: integer, minimum: 1, maximum: 120 }
department_ids: { type: array, maxItems: 100, items: { type: string, format: uuid } }
enabled: { type: boolean }
ApplicationConfig:
type: object
required: [model, knowledge_base_ids, tool_ids, retrieval_top_k, temperature, max_tool_rounds]
properties:
model: { type: string, maxLength: 255 }
prompt_template_id: { type: string, format: uuid }
knowledge_base_ids: { type: array, maxItems: 20, items: { type: string, format: uuid } }
tool_ids: { type: array, maxItems: 20, items: { type: string, format: uuid } }
retrieval_top_k: { type: integer, minimum: 1, maximum: 20 }
temperature: { type: number, minimum: 0, maximum: 2 }
max_tool_rounds: { type: integer, minimum: 0, maximum: 8 }
ApplicationInput:
type: object
required: [code, name, description, status, department_ids, draft_config]
properties:
code: { type: string, pattern: "^[a-z][a-z0-9_-]{2,63}$" }
name: { type: string, minLength: 1, maxLength: 128 }
description: { type: string, maxLength: 4000 }
status: { type: string, enum: [draft, active, suspended, retired] }
department_ids: { type: array, maxItems: 100, items: { type: string, format: uuid } }
draft_config: { $ref: "#/components/schemas/ApplicationConfig" }
NotificationChannelInput:
type: object
required: [name, webhook_url, event_patterns, enabled]
properties:
name: { type: string, minLength: 1, maxLength: 128 }
webhook_url: { type: string, format: uri }
signing_secret:
type: string
writeOnly: true
maxLength: 4096
description: Omit during update to preserve the existing KEK-encrypted signing secret.
event_patterns:
type: array
minItems: 1
maxItems: 100
items: { type: string, description: Exact event type or a prefix ending in one asterisk. }
enabled: { type: boolean }