first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
clear-by-request-id:
delete:
operationId: clearCacheByRequestId
summary: Clear cache by request ID
description: Clears cache entries associated with a specific request ID.
tags:
- Cache
parameters:
- name: requestId
in: path
required: true
description: Request ID to clear cache for
schema:
type: string
responses:
'200':
description: Cache cleared successfully
content:
application/json:
schema:
$ref: '../../schemas/management/cache.yaml#/ClearCacheResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
clear-by-cache-key:
delete:
operationId: clearCacheByCacheKey
summary: Clear cache by cache key
description: Clears a cache entry by its direct cache key.
tags:
- Cache
parameters:
- name: cacheKey
in: path
required: true
description: Cache key to clear
schema:
type: string
responses:
'200':
description: Cache cleared successfully
content:
application/json:
schema:
$ref: '../../schemas/management/cache.yaml#/ClearCacheResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'

View File

@@ -0,0 +1,136 @@
config:
get:
operationId: getConfig
summary: Get configuration
description: |
Retrieves the current Bifrost configuration including client config, framework config,
auth config, and connection status for various stores.
tags:
- Configuration
parameters:
- name: from_db
in: query
description: If true, fetch configuration directly from the database
schema:
type: string
enum: ["true", "false"]
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/config.yaml#/GetConfigResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
put:
operationId: updateConfig
summary: Update configuration
description: |
Updates the Bifrost configuration. Supports hot-reloading of certain settings
like drop_excess_requests. Some settings may require a restart to take effect.
tags:
- Configuration
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/config.yaml#/UpdateConfigRequest'
responses:
'200':
description: Configuration updated successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/SuccessResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
version:
get:
operationId: getVersion
summary: Get version
description: Returns the current Bifrost version information.
tags:
- Configuration
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/config.yaml#/Version'
proxy-config:
get:
operationId: getProxyConfig
summary: Get proxy configuration
description: Retrieves the current global proxy configuration.
tags:
- Configuration
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/config.yaml#/ProxyConfig'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
'503':
description: Config store not available
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
put:
operationId: updateProxyConfig
summary: Update proxy configuration
description: Updates the global proxy configuration.
tags:
- Configuration
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/config.yaml#/ProxyConfig'
responses:
'200':
description: Proxy configuration updated successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/SuccessResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
force-sync-pricing:
post:
operationId: forceSyncPricing
summary: Force pricing sync
description: Triggers an immediate pricing sync and resets the pricing sync timer.
tags:
- Configuration
responses:
'200':
description: Pricing sync triggered successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/SuccessResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
'503':
description: Config store not available
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
health:
get:
operationId: getHealth
summary: Health check
description: |
Returns the health status of the Bifrost server. Checks connectivity to config store,
log store, and vector store if configured.
tags:
- Health
responses:
'200':
description: Server is healthy
content:
application/json:
schema:
$ref: '../../schemas/management/health.yaml#/HealthResponse'
'503':
description: Service unavailable
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'

View File

@@ -0,0 +1,122 @@
# Infrastructure endpoints (WebSocket, MCP Server, Metrics)
websocket:
get:
operationId: websocketConnect
summary: WebSocket connection
description: |
Upgrades to a WebSocket connection for real-time updates.
Server pushes log events, MCP log events, and store update notifications.
Heartbeat pings are sent every 30 seconds.
tags:
- Infrastructure
responses:
'101':
description: WebSocket upgrade successful
mcp-server:
post:
operationId: mcpServerMessage
summary: MCP protocol message
description: |
Receives a JSON-RPC 2.0 message for the MCP protocol server.
Returns a JSON-RPC 2.0 response, or null for notifications.
tags:
- Infrastructure
requestBody:
required: true
content:
application/json:
schema:
type: object
description: JSON-RPC 2.0 request
properties:
jsonrpc:
type: string
enum: ["2.0"]
method:
type: string
params:
type: object
id:
oneOf:
- type: string
- type: integer
responses:
'200':
description: JSON-RPC 2.0 response
content:
application/json:
schema:
type: object
properties:
jsonrpc:
type: string
enum: ["2.0"]
result:
type: object
error:
type: object
properties:
code:
type: integer
message:
type: string
id:
oneOf:
- type: string
- type: integer
security:
- BearerAuth: []
- BasicAuth: []
- VirtualKeyAuth: []
- ApiKeyAuth: []
get:
operationId: mcpServerSSE
summary: MCP protocol SSE stream
description: |
Opens a Server-Sent Events stream for the MCP protocol server.
Returns `Content-Type: text/event-stream`.
tags:
- Infrastructure
responses:
'200':
description: SSE stream opened
content:
text/event-stream:
schema:
type: string
security:
- BearerAuth: []
- BasicAuth: []
- VirtualKeyAuth: []
- ApiKeyAuth: []
metrics:
get:
operationId: getMetrics
summary: Prometheus metrics
description: Returns Prometheus-formatted metrics for monitoring.
tags:
- Infrastructure
responses:
'200':
description: Prometheus metrics
content:
text/plain:
schema:
type: string
websocket-responses:
get:
operationId: websocketResponses
summary: WebSocket Responses API
description: |
Upgrades to a WebSocket connection for the streaming Responses API.
Clients send `response.create` events and receive streaming response events.
Supports authentication via Bearer token, x-api-key, or x-bf-vk headers.
tags:
- Infrastructure
responses:
'101':
description: WebSocket upgrade successful

View File

@@ -0,0 +1,997 @@
logs:
get:
operationId: getLogs
summary: Get logs
description: |
Retrieves logs with filtering, search, and pagination via query parameters.
tags:
- Logging
parameters:
- name: providers
in: query
description: Comma-separated list of providers to filter by
schema:
type: string
- name: models
in: query
description: Comma-separated list of models to filter by
schema:
type: string
- name: status
in: query
description: Comma-separated list of statuses to filter by
schema:
type: string
- name: objects
in: query
description: Comma-separated list of object types to filter by
schema:
type: string
- name: selected_key_ids
in: query
description: Comma-separated list of selected key IDs to filter by
schema:
type: string
- name: virtual_key_ids
in: query
description: Comma-separated list of virtual key IDs to filter by
schema:
type: string
- name: routing_rule_ids
in: query
description: Comma-separated list of routing rule IDs to filter by
schema:
type: string
- name: routing_engine_used
in: query
description: Comma-separated list of routing engines to filter by (routing-rule, governance, or loadbalancing)
schema:
type: string
- name: start_time
in: query
description: Start time filter (RFC3339 format)
schema:
type: string
format: date-time
- name: end_time
in: query
description: End time filter (RFC3339 format)
schema:
type: string
format: date-time
- name: min_latency
in: query
description: Minimum latency filter
schema:
type: number
- name: max_latency
in: query
description: Maximum latency filter
schema:
type: number
- name: min_tokens
in: query
description: Minimum tokens filter
schema:
type: integer
- name: max_tokens
in: query
description: Maximum tokens filter
schema:
type: integer
- name: min_cost
in: query
description: Minimum cost filter
schema:
type: number
- name: max_cost
in: query
description: Maximum cost filter
schema:
type: number
- name: missing_cost_only
in: query
description: Only show logs with missing cost
schema:
type: boolean
- name: content_search
in: query
description: Search in request/response content
schema:
type: string
- name: limit
in: query
description: Number of logs to return (default 50, max 1000)
schema:
type: integer
default: 50
maximum: 1000
- name: offset
in: query
description: Number of logs to skip
schema:
type: integer
default: 0
- name: sort_by
in: query
description: Field to sort by
schema:
type: string
enum: [timestamp, latency, tokens, cost]
default: timestamp
- name: order
in: query
description: Sort order
schema:
type: string
enum: [asc, desc]
default: desc
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/SearchLogsResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: deleteLogs
summary: Delete logs
description: Deletes logs by their IDs.
tags:
- Logging
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/DeleteLogsRequest'
responses:
'200':
description: Logs deleted successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-stats:
get:
operationId: getLogsStats
summary: Get log statistics
description: Returns statistics for logs matching the specified filters.
tags:
- Logging
parameters:
- name: providers
in: query
description: Comma-separated list of providers to filter by
schema:
type: string
- name: models
in: query
description: Comma-separated list of models to filter by
schema:
type: string
- name: status
in: query
description: Comma-separated list of statuses to filter by
schema:
type: string
- name: objects
in: query
description: Comma-separated list of object types to filter by
schema:
type: string
- name: selected_key_ids
in: query
description: Comma-separated list of selected key IDs to filter by
schema:
type: string
- name: virtual_key_ids
in: query
description: Comma-separated list of virtual key IDs to filter by
schema:
type: string
- name: routing_rule_ids
in: query
description: Comma-separated list of routing rule IDs to filter by
schema:
type: string
- name: routing_engine_used
in: query
description: Comma-separated list of routing engines to filter by (routing-rule, governance, or loadbalancing)
schema:
type: string
- name: start_time
in: query
description: Start time filter (RFC3339 format)
schema:
type: string
format: date-time
- name: end_time
in: query
description: End time filter (RFC3339 format)
schema:
type: string
format: date-time
- name: min_latency
in: query
description: Minimum latency filter
schema:
type: number
- name: max_latency
in: query
description: Maximum latency filter
schema:
type: number
- name: min_tokens
in: query
description: Minimum tokens filter
schema:
type: integer
- name: max_tokens
in: query
description: Maximum tokens filter
schema:
type: integer
- name: min_cost
in: query
description: Minimum cost filter
schema:
type: number
- name: max_cost
in: query
description: Maximum cost filter
schema:
type: number
- name: missing_cost_only
in: query
description: Only show logs with missing cost
schema:
type: boolean
- name: content_search
in: query
description: Search in request/response content
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/LogStats'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-dropped:
get:
operationId: getDroppedRequests
summary: Get dropped requests count
description: Returns the number of dropped requests.
tags:
- Logging
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/DroppedRequestsResponse'
logs-filterdata:
get:
operationId: getAvailableFilterData
summary: Get available filter data
description: Returns all unique filter data from logs (models, keys, virtual keys).
tags:
- Logging
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/FilterDataResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-by-id:
get:
operationId: getLogById
summary: Get a single log entry
description: Retrieves a single log entry by its ID.
tags:
- Logging
parameters:
- name: id
in: path
required: true
description: Log entry ID
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/LogEntry'
'404':
description: Log not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-histogram:
get:
operationId: getLogsHistogram
summary: Get request count histogram
description: |
Returns time-bucketed request counts. Bucket size is auto-calculated from the time range.
tags:
- Logging
parameters:
- $ref: '#/_histogram-parameters/providers'
- $ref: '#/_histogram-parameters/models'
- $ref: '#/_histogram-parameters/status'
- $ref: '#/_histogram-parameters/objects'
- $ref: '#/_histogram-parameters/selected_key_ids'
- $ref: '#/_histogram-parameters/virtual_key_ids'
- $ref: '#/_histogram-parameters/routing_rule_ids'
- $ref: '#/_histogram-parameters/routing_engine_used'
- $ref: '#/_histogram-parameters/start_time'
- $ref: '#/_histogram-parameters/end_time'
- $ref: '#/_histogram-parameters/min_latency'
- $ref: '#/_histogram-parameters/max_latency'
- $ref: '#/_histogram-parameters/min_tokens'
- $ref: '#/_histogram-parameters/max_tokens'
- $ref: '#/_histogram-parameters/min_cost'
- $ref: '#/_histogram-parameters/max_cost'
- $ref: '#/_histogram-parameters/missing_cost_only'
- $ref: '#/_histogram-parameters/content_search'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/HistogramResult'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-histogram-tokens:
get:
operationId: getLogsTokenHistogram
summary: Get token usage histogram
description: Returns time-bucketed token usage (prompt, completion, total).
tags:
- Logging
parameters:
- $ref: '#/_histogram-parameters/providers'
- $ref: '#/_histogram-parameters/models'
- $ref: '#/_histogram-parameters/status'
- $ref: '#/_histogram-parameters/objects'
- $ref: '#/_histogram-parameters/selected_key_ids'
- $ref: '#/_histogram-parameters/virtual_key_ids'
- $ref: '#/_histogram-parameters/routing_rule_ids'
- $ref: '#/_histogram-parameters/routing_engine_used'
- $ref: '#/_histogram-parameters/start_time'
- $ref: '#/_histogram-parameters/end_time'
- $ref: '#/_histogram-parameters/min_latency'
- $ref: '#/_histogram-parameters/max_latency'
- $ref: '#/_histogram-parameters/min_tokens'
- $ref: '#/_histogram-parameters/max_tokens'
- $ref: '#/_histogram-parameters/min_cost'
- $ref: '#/_histogram-parameters/max_cost'
- $ref: '#/_histogram-parameters/missing_cost_only'
- $ref: '#/_histogram-parameters/content_search'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/TokenHistogramResult'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-histogram-cost:
get:
operationId: getLogsCostHistogram
summary: Get cost histogram
description: Returns time-bucketed cost data with model breakdown.
tags:
- Logging
parameters:
- $ref: '#/_histogram-parameters/providers'
- $ref: '#/_histogram-parameters/models'
- $ref: '#/_histogram-parameters/status'
- $ref: '#/_histogram-parameters/objects'
- $ref: '#/_histogram-parameters/selected_key_ids'
- $ref: '#/_histogram-parameters/virtual_key_ids'
- $ref: '#/_histogram-parameters/routing_rule_ids'
- $ref: '#/_histogram-parameters/routing_engine_used'
- $ref: '#/_histogram-parameters/start_time'
- $ref: '#/_histogram-parameters/end_time'
- $ref: '#/_histogram-parameters/min_latency'
- $ref: '#/_histogram-parameters/max_latency'
- $ref: '#/_histogram-parameters/min_tokens'
- $ref: '#/_histogram-parameters/max_tokens'
- $ref: '#/_histogram-parameters/min_cost'
- $ref: '#/_histogram-parameters/max_cost'
- $ref: '#/_histogram-parameters/missing_cost_only'
- $ref: '#/_histogram-parameters/content_search'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/CostHistogramResult'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-histogram-models:
get:
operationId: getLogsModelHistogram
summary: Get model usage histogram
description: Returns time-bucketed model usage with success/error breakdown.
tags:
- Logging
parameters:
- $ref: '#/_histogram-parameters/providers'
- $ref: '#/_histogram-parameters/models'
- $ref: '#/_histogram-parameters/status'
- $ref: '#/_histogram-parameters/objects'
- $ref: '#/_histogram-parameters/selected_key_ids'
- $ref: '#/_histogram-parameters/virtual_key_ids'
- $ref: '#/_histogram-parameters/routing_rule_ids'
- $ref: '#/_histogram-parameters/routing_engine_used'
- $ref: '#/_histogram-parameters/start_time'
- $ref: '#/_histogram-parameters/end_time'
- $ref: '#/_histogram-parameters/min_latency'
- $ref: '#/_histogram-parameters/max_latency'
- $ref: '#/_histogram-parameters/min_tokens'
- $ref: '#/_histogram-parameters/max_tokens'
- $ref: '#/_histogram-parameters/min_cost'
- $ref: '#/_histogram-parameters/max_cost'
- $ref: '#/_histogram-parameters/missing_cost_only'
- $ref: '#/_histogram-parameters/content_search'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/ModelHistogramResult'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-histogram-latency:
get:
operationId: getLogsLatencyHistogram
summary: Get latency histogram
description: Returns time-bucketed latency percentiles (avg, p90, p95, p99).
tags:
- Logging
parameters:
- $ref: '#/_histogram-parameters/providers'
- $ref: '#/_histogram-parameters/models'
- $ref: '#/_histogram-parameters/status'
- $ref: '#/_histogram-parameters/objects'
- $ref: '#/_histogram-parameters/selected_key_ids'
- $ref: '#/_histogram-parameters/virtual_key_ids'
- $ref: '#/_histogram-parameters/routing_rule_ids'
- $ref: '#/_histogram-parameters/routing_engine_used'
- $ref: '#/_histogram-parameters/start_time'
- $ref: '#/_histogram-parameters/end_time'
- $ref: '#/_histogram-parameters/min_latency'
- $ref: '#/_histogram-parameters/max_latency'
- $ref: '#/_histogram-parameters/min_tokens'
- $ref: '#/_histogram-parameters/max_tokens'
- $ref: '#/_histogram-parameters/min_cost'
- $ref: '#/_histogram-parameters/max_cost'
- $ref: '#/_histogram-parameters/missing_cost_only'
- $ref: '#/_histogram-parameters/content_search'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/LatencyHistogramResult'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-histogram-cost-by-provider:
get:
operationId: getLogsProviderCostHistogram
summary: Get cost histogram by provider
description: Returns time-bucketed cost data with provider breakdown.
tags:
- Logging
parameters:
- $ref: '#/_histogram-parameters/providers'
- $ref: '#/_histogram-parameters/models'
- $ref: '#/_histogram-parameters/status'
- $ref: '#/_histogram-parameters/objects'
- $ref: '#/_histogram-parameters/selected_key_ids'
- $ref: '#/_histogram-parameters/virtual_key_ids'
- $ref: '#/_histogram-parameters/routing_rule_ids'
- $ref: '#/_histogram-parameters/routing_engine_used'
- $ref: '#/_histogram-parameters/start_time'
- $ref: '#/_histogram-parameters/end_time'
- $ref: '#/_histogram-parameters/min_latency'
- $ref: '#/_histogram-parameters/max_latency'
- $ref: '#/_histogram-parameters/min_tokens'
- $ref: '#/_histogram-parameters/max_tokens'
- $ref: '#/_histogram-parameters/min_cost'
- $ref: '#/_histogram-parameters/max_cost'
- $ref: '#/_histogram-parameters/missing_cost_only'
- $ref: '#/_histogram-parameters/content_search'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/ProviderCostHistogramResult'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-histogram-tokens-by-provider:
get:
operationId: getLogsProviderTokenHistogram
summary: Get token histogram by provider
description: Returns time-bucketed token usage with provider breakdown.
tags:
- Logging
parameters:
- $ref: '#/_histogram-parameters/providers'
- $ref: '#/_histogram-parameters/models'
- $ref: '#/_histogram-parameters/status'
- $ref: '#/_histogram-parameters/objects'
- $ref: '#/_histogram-parameters/selected_key_ids'
- $ref: '#/_histogram-parameters/virtual_key_ids'
- $ref: '#/_histogram-parameters/routing_rule_ids'
- $ref: '#/_histogram-parameters/routing_engine_used'
- $ref: '#/_histogram-parameters/start_time'
- $ref: '#/_histogram-parameters/end_time'
- $ref: '#/_histogram-parameters/min_latency'
- $ref: '#/_histogram-parameters/max_latency'
- $ref: '#/_histogram-parameters/min_tokens'
- $ref: '#/_histogram-parameters/max_tokens'
- $ref: '#/_histogram-parameters/min_cost'
- $ref: '#/_histogram-parameters/max_cost'
- $ref: '#/_histogram-parameters/missing_cost_only'
- $ref: '#/_histogram-parameters/content_search'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/ProviderTokenHistogramResult'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logs-histogram-latency-by-provider:
get:
operationId: getLogsProviderLatencyHistogram
summary: Get latency histogram by provider
description: Returns time-bucketed latency percentiles with provider breakdown.
tags:
- Logging
parameters:
- $ref: '#/_histogram-parameters/providers'
- $ref: '#/_histogram-parameters/models'
- $ref: '#/_histogram-parameters/status'
- $ref: '#/_histogram-parameters/objects'
- $ref: '#/_histogram-parameters/selected_key_ids'
- $ref: '#/_histogram-parameters/virtual_key_ids'
- $ref: '#/_histogram-parameters/routing_rule_ids'
- $ref: '#/_histogram-parameters/routing_engine_used'
- $ref: '#/_histogram-parameters/start_time'
- $ref: '#/_histogram-parameters/end_time'
- $ref: '#/_histogram-parameters/min_latency'
- $ref: '#/_histogram-parameters/max_latency'
- $ref: '#/_histogram-parameters/min_tokens'
- $ref: '#/_histogram-parameters/max_tokens'
- $ref: '#/_histogram-parameters/min_cost'
- $ref: '#/_histogram-parameters/max_cost'
- $ref: '#/_histogram-parameters/missing_cost_only'
- $ref: '#/_histogram-parameters/content_search'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/ProviderLatencyHistogramResult'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
# Shared histogram filter parameters
_histogram-parameters:
providers:
name: providers
in: query
description: Comma-separated list of providers to filter by
schema:
type: string
models:
name: models
in: query
description: Comma-separated list of models to filter by
schema:
type: string
status:
name: status
in: query
description: Comma-separated list of statuses to filter by
schema:
type: string
objects:
name: objects
in: query
description: Comma-separated list of object types to filter by
schema:
type: string
selected_key_ids:
name: selected_key_ids
in: query
description: Comma-separated list of selected key IDs to filter by
schema:
type: string
virtual_key_ids:
name: virtual_key_ids
in: query
description: Comma-separated list of virtual key IDs to filter by
schema:
type: string
routing_rule_ids:
name: routing_rule_ids
in: query
description: Comma-separated list of routing rule IDs to filter by
schema:
type: string
routing_engine_used:
name: routing_engine_used
in: query
description: Comma-separated list of routing engines to filter by
schema:
type: string
start_time:
name: start_time
in: query
description: Start time filter (RFC3339 format)
schema:
type: string
format: date-time
end_time:
name: end_time
in: query
description: End time filter (RFC3339 format)
schema:
type: string
format: date-time
min_latency:
name: min_latency
in: query
description: Minimum latency filter
schema:
type: number
max_latency:
name: max_latency
in: query
description: Maximum latency filter
schema:
type: number
min_tokens:
name: min_tokens
in: query
description: Minimum tokens filter
schema:
type: integer
max_tokens:
name: max_tokens
in: query
description: Maximum tokens filter
schema:
type: integer
min_cost:
name: min_cost
in: query
description: Minimum cost filter
schema:
type: number
max_cost:
name: max_cost
in: query
description: Maximum cost filter
schema:
type: number
missing_cost_only:
name: missing_cost_only
in: query
description: Only show logs with missing cost
schema:
type: boolean
content_search:
name: content_search
in: query
description: Search in request/response content
schema:
type: string
logs-recalculate-cost:
post:
operationId: recalculateLogCosts
summary: Recalculate log costs
description: |
Recomputes missing costs in batches. Processes logs with missing cost values
and updates them based on current pricing data.
tags:
- Logging
requestBody:
required: false
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/RecalculateCostRequest'
responses:
'200':
description: Costs recalculated successfully
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/RecalculateCostResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
mcp-logs:
get:
operationId: getMCPLogs
summary: Get MCP tool logs
description: |
Retrieves MCP tool execution logs with filtering, search, and pagination via query parameters.
tags:
- Logging
parameters:
- name: tool_names
in: query
description: Comma-separated list of tool names to filter by
schema:
type: string
- name: server_labels
in: query
description: Comma-separated list of server labels to filter by
schema:
type: string
- name: status
in: query
description: Comma-separated list of statuses to filter by (processing, success, error)
schema:
type: string
enum: [processing, success, error]
- name: virtual_key_ids
in: query
description: Comma-separated list of virtual key IDs to filter by
schema:
type: string
- name: llm_request_ids
in: query
description: Comma-separated list of LLM request IDs to filter by
schema:
type: string
- name: start_time
in: query
description: Start time filter (RFC3339 format)
schema:
type: string
format: date-time
- name: end_time
in: query
description: End time filter (RFC3339 format)
schema:
type: string
format: date-time
- name: min_latency
in: query
description: Minimum latency filter (milliseconds)
schema:
type: number
- name: max_latency
in: query
description: Maximum latency filter (milliseconds)
schema:
type: number
- name: content_search
in: query
description: Search in tool arguments and results
schema:
type: string
- name: limit
in: query
description: Number of logs to return (default 50, max 1000)
schema:
type: integer
default: 50
maximum: 1000
- name: offset
in: query
description: Number of logs to skip
schema:
type: integer
default: 0
- name: sort_by
in: query
description: Field to sort by
schema:
type: string
enum: [timestamp, latency, cost]
default: timestamp
- name: order
in: query
description: Sort order
schema:
type: string
enum: [asc, desc]
default: desc
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/SearchMCPLogsResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: deleteMCPLogs
summary: Delete MCP tool logs
description: Deletes MCP tool logs by their IDs.
tags:
- Logging
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/DeleteMCPLogsRequest'
responses:
'200':
description: MCP tool logs deleted successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
mcp-logs-stats:
get:
operationId: getMCPLogsStats
summary: Get MCP tool log statistics
description: Returns statistics for MCP tool logs matching the specified filters.
tags:
- Logging
parameters:
- name: tool_names
in: query
description: Comma-separated list of tool names to filter by
schema:
type: string
- name: server_labels
in: query
description: Comma-separated list of server labels to filter by
schema:
type: string
- name: status
in: query
description: Comma-separated list of statuses to filter by
schema:
type: string
enum: [processing, success, error]
- name: virtual_key_ids
in: query
description: Comma-separated list of virtual key IDs to filter by
schema:
type: string
- name: llm_request_ids
in: query
description: Comma-separated list of LLM request IDs to filter by
schema:
type: string
- name: start_time
in: query
description: Start time filter (RFC3339 format)
schema:
type: string
format: date-time
- name: end_time
in: query
description: End time filter (RFC3339 format)
schema:
type: string
format: date-time
- name: min_latency
in: query
description: Minimum latency filter
schema:
type: number
- name: max_latency
in: query
description: Maximum latency filter
schema:
type: number
- name: content_search
in: query
description: Search in tool arguments and results
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/MCPToolLogStats'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
mcp-logs-filterdata:
get:
operationId: getMCPLogsFilterData
summary: Get available MCP log filter data
description: Returns all unique filter data from MCP tool logs (tool names, server labels).
tags:
- Logging
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/logging.yaml#/MCPLogsFilterDataResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'

View File

@@ -0,0 +1,240 @@
execute-tool:
post:
operationId: executeMCPTool
summary: Execute MCP tool
description: Executes an MCP tool and returns the result.
tags:
- MCP
parameters:
- name: format
in: query
required: false
description: |
Format of the tool execution request/response.
schema:
type: string
enum: [chat, responses]
default: chat
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/mcp.yaml#/ExecuteToolRequest'
examples:
chat:
summary: Chat format example
value:
id: "call_123"
type: "function"
function:
name: "get_weather"
arguments: '{"location": "San Francisco"}'
responses:
summary: Responses format example
value:
call_id: "call_123"
name: "get_weather"
arguments: '{"location": "San Francisco"}'
responses:
'200':
description: Tool executed successfully
content:
application/json:
schema:
$ref: '../../schemas/management/mcp.yaml#/ExecuteToolResponse'
examples:
chat:
summary: Chat format response
value:
name: "get_weather"
role: "tool"
tool_call_id: "call_123"
content: "The weather in San Francisco is 72°F and sunny."
responses:
summary: Responses format response
value:
id: "msg_123"
type: "function_call_output"
status: "completed"
role: "assistant"
call_id: "call_123"
name: "get_weather"
arguments: '{"location": "San Francisco"}'
content: "The weather in San Francisco is 72°F and sunny."
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
security:
- BearerAuth: []
- BasicAuth: []
- VirtualKeyAuth: []
- ApiKeyAuth: []
clients:
get:
operationId: getMCPClients
summary: List MCP clients
description: Returns a list of all configured MCP clients with their tools and connection state.
tags:
- MCP
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: '../../schemas/management/mcp.yaml#/MCPClient'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
client:
post:
operationId: addMCPClient
summary: Add MCP client
description: |
Adds a new MCP client with the specified configuration.
Note: tool_pricing is not available when creating a new client as tools are fetched after client creation.
tags:
- MCP
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/mcp.yaml#/MCPClientCreateRequest'
responses:
'200':
description: MCP client added successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/SuccessResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
client-by-id:
put:
operationId: editMCPClient
summary: Edit MCP client
description: |
Updates an existing MCP client's configuration.
Unlike client creation, tool_pricing can be included to set per-tool execution costs since tools are already fetched.
Optionally provide vk_configs to manage which virtual keys have access to this MCP server and with which tools. When provided, this fully replaces all existing VK assignments in a single atomic transaction.
tags:
- MCP
parameters:
- name: id
in: path
required: true
description: MCP client ID
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/mcp.yaml#/MCPClientUpdateRequest'
responses:
'200':
description: MCP client updated successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/SuccessResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: removeMCPClient
summary: Remove MCP client
description: Removes an MCP client from the configuration.
tags:
- MCP
parameters:
- name: id
in: path
required: true
description: MCP client ID
schema:
type: string
responses:
'200':
description: MCP client removed successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/SuccessResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
client-reconnect:
post:
operationId: reconnectMCPClient
summary: Reconnect MCP client
description: Reconnects an MCP client that is in an error or disconnected state.
tags:
- MCP
parameters:
- name: id
in: path
required: true
description: MCP client ID
schema:
type: string
responses:
'200':
description: MCP client reconnected successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/SuccessResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
client-complete-oauth:
post:
operationId: completeMCPClientOAuth
summary: Complete MCP client OAuth flow
description: |
Completes the OAuth flow for an MCP client after the user has authorized the request.
This endpoint should be called after the OAuth provider redirects back to the callback endpoint
and the OAuth token has been stored. It retrieves the pending MCP client configuration and
establishes the connection with the OAuth-provided credentials.
tags:
- MCP
- OAuth
parameters:
- name: id
in: path
required: true
description: MCP client ID
schema:
type: string
responses:
'200':
description: MCP client connected successfully with OAuth
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/SuccessResponse'
'400':
description: OAuth not authorized yet or MCP client not found in pending OAuth clients
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: MCP client not found in pending OAuth clients or OAuth config not found
$ref: '../../openapi.yaml#/components/responses/NotFound'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'

View File

@@ -0,0 +1,769 @@
oauth-callback:
get:
operationId: handleOAuthCallback
summary: OAuth callback endpoint
description: |
Handles the OAuth provider callback after user authorization.
This endpoint processes the authorization code and exchanges it for an access token.
On success, displays an HTML page that closes the authorization window.
tags:
- OAuth
parameters:
- name: state
in: query
required: true
description: State parameter for OAuth security (CSRF protection)
schema:
type: string
- name: code
in: query
required: true
description: Authorization code from the OAuth provider
schema:
type: string
- name: error
in: query
required: false
description: Error code if authorization failed
schema:
type: string
- name: error_description
in: query
required: false
description: Error description if authorization failed
schema:
type: string
responses:
'200':
description: OAuth authorization successful. Returns HTML page that closes the authorization window.
content:
text/html:
schema:
type: string
'400':
description: OAuth authorization failed or missing required parameters
content:
text/html:
schema:
type: string
oauth-config-status:
get:
operationId: getOAuthConfigStatus
summary: Get OAuth config status
description: |
Retrieves the current status of an OAuth configuration.
Shows whether the OAuth flow is pending, authorized, or failed,
and includes token expiration and scopes if authorized.
tags:
- OAuth
parameters:
- name: id
in: path
required: true
description: OAuth config ID
schema:
type: string
responses:
'200':
description: OAuth config status retrieved successfully
content:
application/json:
schema:
$ref: '../../schemas/management/oauth.yaml#/OAuthConfigStatus'
'404':
description: OAuth config not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: revokeOAuthConfig
summary: Revoke OAuth config
description: |
Revokes an OAuth configuration and its associated access token.
After revocation, the MCP client will no longer be able to use this OAuth token.
tags:
- OAuth
parameters:
- name: id
in: path
required: true
description: OAuth config ID
schema:
type: string
responses:
'200':
description: OAuth token revoked successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/SuccessResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
# ─── Per-User OAuth 2.1 Authorization Server ───────────────────────────────
# These endpoints implement RFC 7591 (dynamic registration), RFC 7636 (PKCE),
# and the OAuth 2.1 authorization code flow. MCP clients use them automatically
# when connecting to Bifrost's /mcp endpoint. Only active when at least one MCP
# client is configured with auth_type: per_user_oauth.
per-user-oauth-register:
post:
operationId: registerPerUserOAuthClient
summary: Register OAuth client (RFC 7591)
description: |
Dynamic Client Registration per RFC 7591. MCP clients (Claude Code, Cursor, etc.)
call this endpoint to obtain a `client_id` before initiating the authorization flow.
This endpoint is only available when at least one MCP client is configured with
`auth_type: per_user_oauth`. Returns `404` otherwise.
Authentication is not required — this is part of the unauthenticated OAuth bootstrap flow.
tags:
- OAuth
- Per-User OAuth
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/oauth.yaml#/PerUserOAuthClientRegistrationRequest'
example:
client_name: "Claude Code"
redirect_uris: ["http://localhost:54321/callback"]
grant_types: ["authorization_code"]
response_types: ["code"]
token_endpoint_auth_method: "none"
responses:
'201':
description: Client registered successfully
content:
application/json:
schema:
$ref: '../../schemas/management/oauth.yaml#/PerUserOAuthClientRegistrationResponse'
example:
client_id: "550e8400-e29b-41d4-a716-446655440000"
client_name: "Claude Code"
redirect_uris: ["http://localhost:54321/callback"]
grant_types: ["authorization_code"]
token_endpoint_auth_method: "none"
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: No per-user OAuth MCP clients configured
content:
text/plain:
schema:
type: string
'503':
description: Config store is disabled
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
per-user-oauth-authorize:
get:
operationId: authorizePerUserOAuth
summary: Authorization endpoint (OAuth 2.1)
description: |
OAuth 2.1 authorization endpoint. Validates the request parameters, creates a
browser-bound `PendingFlow` record (15-minute TTL), and redirects the user to
the Bifrost consent screen at `/oauth/consent?flow_id=xxx`.
**PKCE is required** — `code_challenge` and `code_challenge_method=S256` must
be provided. Plain code challenges are not supported.
A `__bifrost_flow_secret` HttpOnly SameSite=Lax cookie is set on redirect to
bind the consent flow to the initiating browser session (CSRF protection).
Authentication is not required — this is part of the unauthenticated OAuth bootstrap flow.
tags:
- OAuth
- Per-User OAuth
parameters:
- name: response_type
in: query
required: true
description: Must be `code`
schema:
type: string
enum: [code]
- name: client_id
in: query
required: true
description: Client ID obtained from the registration endpoint
schema:
type: string
- name: redirect_uri
in: query
required: true
description: Must match a URI registered for this client
schema:
type: string
- name: code_challenge
in: query
required: true
description: PKCE code challenge (Base64URL-encoded SHA-256 of the code verifier)
schema:
type: string
- name: code_challenge_method
in: query
required: true
description: Must be `S256`
schema:
type: string
enum: [S256]
- name: state
in: query
required: false
description: Opaque value to maintain state between request and callback (CSRF protection)
schema:
type: string
responses:
'302':
description: Redirect to consent screen at `/oauth/consent?flow_id=xxx`
headers:
Location:
schema:
type: string
description: URL of the consent screen
Set-Cookie:
schema:
type: string
description: "`__bifrost_flow_secret` HttpOnly SameSite=Lax cookie for browser binding"
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: No per-user OAuth MCP clients configured, or unknown client_id
content:
text/plain:
schema:
type: string
'503':
description: Config store is disabled
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
per-user-oauth-token:
post:
operationId: exchangePerUserOAuthToken
summary: Token endpoint (OAuth 2.1)
description: |
OAuth 2.1 token endpoint. Exchanges a single-use authorization code (5-minute TTL)
for a Bifrost-issued access token (24-hour TTL) using PKCE verification.
The request body must be `application/x-www-form-urlencoded`.
The returned `access_token` is the Bearer token to use on subsequent `/mcp` requests.
It carries the user's upstream service tokens (Notion, GitHub, etc.) linked to their
identity (Virtual Key or User ID) from the consent flow.
Authentication is not required — this is part of the unauthenticated OAuth bootstrap flow.
tags:
- OAuth
- Per-User OAuth
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required:
- grant_type
- code
- code_verifier
properties:
grant_type:
type: string
description: Must be `authorization_code`
enum: [authorization_code]
code:
type: string
description: Authorization code received in the redirect callback
redirect_uri:
type: string
description: Must match the redirect_uri used in the authorize request (if provided)
client_id:
type: string
description: Client ID (optional — code is already bound to the client)
code_verifier:
type: string
description: PKCE code verifier — the raw secret whose SHA-256 matches the code_challenge
responses:
'200':
description: Token issued successfully
content:
application/json:
schema:
$ref: '../../schemas/management/oauth.yaml#/PerUserOAuthTokenResponse'
example:
access_token: "abc123xyz..."
token_type: "Bearer"
expires_in: 86400
scope: "mcp:read mcp:write"
'400':
description: Invalid grant, expired code, PKCE failure, or unsupported grant type
content:
application/json:
schema:
type: object
properties:
error:
type: string
enum: [invalid_grant, invalid_request, unsupported_grant_type]
error_description:
type: string
'404':
description: No per-user OAuth MCP clients configured
content:
text/plain:
schema:
type: string
'500':
description: Server error or session creation failed
content:
application/json:
schema:
type: object
properties:
error:
type: string
enum: [server_error]
error_description:
type: string
per-user-oauth-upstream-authorize:
get:
operationId: authorizeUpstreamPerUserOAuth
summary: Upstream OAuth proxy — authorize with upstream service
description: |
Initiates an OAuth flow with an upstream MCP service (Notion, GitHub, etc.)
on behalf of the current user. Used during the consent flow (via "Connect" buttons
on the MCPs page) and at runtime when a tool call is made to an unauthenticated service.
**Consent flow** — provide `flow_id` (from the pending consent flow). The browser-binding
cookie (`__bifrost_flow_secret`) is validated.
**Runtime flow** — provide `session` (the Bifrost session ID from the token endpoint).
Used when a service was skipped during consent and needs to be connected later.
On success, redirects the user to the upstream provider's authorize URL. After the user
grants access, the upstream callback lands at `/api/oauth/callback`, stores the upstream
token against the user's identity, and redirects back to the consent screen (consent flow)
or returns an authorization success page (runtime flow).
Authentication is not required — cookie/session validation is performed instead.
tags:
- OAuth
- Per-User OAuth
parameters:
- name: mcp_client_id
in: query
required: true
description: ID of the per-user OAuth MCP client to authenticate with
schema:
type: string
- name: flow_id
in: query
required: false
description: |
Pending consent flow ID. Required if `session` is not provided.
The `__bifrost_flow_secret` cookie must be present and match the flow.
schema:
type: string
- name: session
in: query
required: false
description: |
Bifrost session ID (from the token endpoint). Required if `flow_id` is not provided.
Used for runtime (post-consent) upstream authorization.
schema:
type: string
responses:
'302':
description: Redirect to upstream OAuth provider's authorize URL
headers:
Location:
schema:
type: string
description: Upstream provider authorization URL with PKCE parameters
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'401':
description: Invalid or expired flow/session
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'403':
description: Browser-binding cookie mismatch (CSRF protection)
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'404':
description: MCP client not found or not configured for per-user OAuth
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'503':
description: Config store is disabled
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
# ─── Per-User OAuth Consent Flow (browser UI) ──────────────────────────────
# These endpoints serve HTML pages and handle form submissions for the
# multi-step consent flow. They are browser-facing, not JSON API endpoints.
# All endpoints validate the __bifrost_flow_secret browser-binding cookie.
consent-identity-page:
get:
operationId: getConsentIdentityPage
summary: Consent identity selection page
description: |
Renders the identity selection screen where the user chooses how to identify
themselves for the session: Virtual Key, User ID, or Skip (session-only auth).
The `__bifrost_flow_secret` HttpOnly cookie set during `/api/oauth/per-user/authorize`
must be present — it binds the consent flow to the initiating browser.
The Skip option is only shown when `enforce_auth_on_inference` is `false` in config.
tags:
- Per-User OAuth
- Consent Flow
parameters:
- name: flow_id
in: query
required: true
description: Pending flow ID from the authorize redirect
schema:
type: string
- name: error
in: query
required: false
description: Error message to display (used on redirect-back from failed form submissions)
schema:
type: string
responses:
'200':
description: Identity selection HTML page
content:
text/html:
schema:
type: string
'400':
description: Missing or expired flow_id
content:
text/plain:
schema:
type: string
'403':
description: Browser-binding cookie mismatch
content:
text/plain:
schema:
type: string
consent-mcps-page:
get:
operationId: getConsentMCPsPage
summary: Consent MCP services page
description: |
Renders the MCP services connection screen. Shows all per-user OAuth MCP servers
available on the user's Virtual Key (or all servers if no VK was selected).
Each service shows a "Connect" link or a "Connected ✓" badge.
Requires the `__bifrost_flow_secret` browser-binding cookie.
tags:
- Per-User OAuth
- Consent Flow
parameters:
- name: flow_id
in: query
required: true
description: Pending flow ID
schema:
type: string
responses:
'200':
description: MCP services connection HTML page
content:
text/html:
schema:
type: string
'400':
description: Missing or expired flow_id
content:
text/plain:
schema:
type: string
'403':
description: Browser-binding cookie mismatch
content:
text/plain:
schema:
type: string
consent-submit-vk:
post:
operationId: submitConsentVirtualKey
summary: Submit Virtual Key identity
description: |
Validates the submitted Virtual Key and links it to the pending flow as the user's
identity. On success, redirects to the MCPs page. On failure, redirects back to the
identity page with an error message.
Request body is `application/x-www-form-urlencoded` (browser form submission).
tags:
- Per-User OAuth
- Consent Flow
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required: [flow_id, vk]
properties:
flow_id:
type: string
description: Pending flow ID
vk:
type: string
description: Virtual Key value (validated against the database)
responses:
'302':
description: |
Redirect to `/oauth/consent/mcps?flow_id=xxx` on success, or back to
`/oauth/consent?flow_id=xxx&error=...` on failure.
headers:
Location:
schema:
type: string
consent-submit-user-id:
post:
operationId: submitConsentUserID
summary: Submit User ID identity
description: |
Links a self-declared User ID to the pending flow as the user's identity.
On success, redirects to the MCPs page.
The User ID is self-declared with no server-side verification — it matches
the trust model of the `X-Bf-User-Id` header in the LLM Gateway path.
Request body is `application/x-www-form-urlencoded` (browser form submission).
tags:
- Per-User OAuth
- Consent Flow
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required: [flow_id, user_id]
properties:
flow_id:
type: string
description: Pending flow ID
user_id:
type: string
description: Self-declared user identifier (max 255 characters)
responses:
'302':
description: |
Redirect to `/oauth/consent/mcps?flow_id=xxx` on success, or back to
`/oauth/consent?flow_id=xxx&error=...` on failure.
headers:
Location:
schema:
type: string
consent-skip:
post:
operationId: skipConsentIdentity
summary: Skip identity selection
description: |
Skips identity selection and proceeds directly to the MCPs page. Upstream service
tokens will be stored against the session token only (not a persistent identity),
so they will not carry over to other sessions or the LLM Gateway.
Only available when `enforce_auth_on_inference` is `false` in config. Returns a
redirect back to the identity page with an error if auth enforcement is enabled.
Request body is `application/x-www-form-urlencoded` (browser form submission).
tags:
- Per-User OAuth
- Consent Flow
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required: [flow_id]
properties:
flow_id:
type: string
description: Pending flow ID
responses:
'302':
description: |
Redirect to `/oauth/consent/mcps?flow_id=xxx` on success, or back to
`/oauth/consent?flow_id=xxx&error=...` if identity enforcement is required.
headers:
Location:
schema:
type: string
consent-submit:
post:
operationId: submitConsent
summary: Finalize consent flow
description: |
Finalizes the consent flow atomically:
1. Creates a `TablePerUserOAuthSession` (24h Bifrost session token)
2. Transfers upstream tokens from the flow proxy to the session
3. Issues a single-use `TablePerUserOAuthCode` (5-minute TTL, PKCE-bound)
4. Deletes the `PendingFlow`
5. Redirects to the MCP client's `redirect_uri` with `code` and `state`
The MCP client then exchanges the code at `/api/oauth/per-user/token`.
Request body is `application/x-www-form-urlencoded` (browser form submission).
tags:
- Per-User OAuth
- Consent Flow
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required: [flow_id]
properties:
flow_id:
type: string
description: Pending flow ID
responses:
'302':
description: |
Redirect to the MCP client's registered `redirect_uri` with
`?code=xxx&state=yyy` query parameters.
headers:
Location:
schema:
type: string
description: MCP client callback URL with code and state
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'403':
description: Browser-binding cookie mismatch
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'409':
description: Consent flow already submitted (duplicate submission prevention)
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'410':
description: Consent flow expired
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
# ─── OAuth Discovery (RFC 9728 + RFC 8414) ─────────────────────────────────
# These well-known endpoints enable MCP clients to auto-discover Bifrost's
# OAuth configuration. Only active when at least one MCP client is configured
# with auth_type: per_user_oauth.
oauth-protected-resource-metadata:
get:
operationId: getOAuthProtectedResourceMetadata
summary: Protected Resource Metadata (RFC 9728)
description: |
Returns the OAuth 2.0 Protected Resource Metadata document per RFC 9728.
MCP clients fetch this after receiving a `401` response from `/mcp` (with a
`WWW-Authenticate: Bearer resource_metadata=".../.well-known/oauth-protected-resource"`
header). The response tells the client which authorization server(s) protect the
`/mcp` resource so it can proceed with discovery.
Returns `404` when no MCP clients are configured with `auth_type: per_user_oauth`.
tags:
- OAuth
- Per-User OAuth
responses:
'200':
description: Protected resource metadata
content:
application/json:
schema:
$ref: '../../schemas/management/oauth.yaml#/ProtectedResourceMetadata'
example:
resource: "https://your-bifrost-domain.com/mcp"
authorization_servers: ["https://your-bifrost-domain.com"]
scopes_supported: ["mcp:read", "mcp:write"]
bearer_methods_supported: ["header"]
'404':
description: No per-user OAuth MCP clients configured
content:
text/plain:
schema:
type: string
oauth-authorization-server-metadata:
get:
operationId: getOAuthAuthorizationServerMetadata
summary: Authorization Server Metadata (RFC 8414)
description: |
Returns the OAuth 2.0 Authorization Server Metadata document per RFC 8414.
After fetching the Protected Resource Metadata, MCP clients fetch this endpoint
to discover Bifrost's OAuth endpoints (register, authorize, token) and capabilities
(PKCE methods, grant types, etc.).
Returns `404` when no MCP clients are configured with `auth_type: per_user_oauth`.
tags:
- OAuth
- Per-User OAuth
responses:
'200':
description: Authorization server metadata
content:
application/json:
schema:
$ref: '../../schemas/management/oauth.yaml#/AuthorizationServerMetadata'
example:
issuer: "https://your-bifrost-domain.com"
authorization_endpoint: "https://your-bifrost-domain.com/api/oauth/per-user/authorize"
token_endpoint: "https://your-bifrost-domain.com/api/oauth/per-user/token"
registration_endpoint: "https://your-bifrost-domain.com/api/oauth/per-user/register"
response_types_supported: ["code"]
grant_types_supported: ["authorization_code"]
code_challenge_methods_supported: ["S256"]
token_endpoint_auth_methods_supported: ["none"]
scopes_supported: ["mcp:read", "mcp:write"]
'404':
description: No per-user OAuth MCP clients configured
content:
text/plain:
schema:
type: string

View File

@@ -0,0 +1,157 @@
plugins:
get:
operationId: listPlugins
summary: List all plugins
description: |
Returns a list of all plugins with their configurations and status.
The `actualName` field contains the plugin name from `GetName()` (used as the map key),
while `name` contains the display name from the configuration.
The `types` array in the status shows which interfaces the plugin implements (llm, mcp, http).
tags:
- Plugins
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/plugins.yaml#/ListPluginsResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
post:
operationId: createPlugin
summary: Create a new plugin
description: Creates a new plugin with the specified configuration.
tags:
- Plugins
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/plugins.yaml#/CreatePluginRequest'
responses:
'201':
description: Plugin created successfully
content:
application/json:
schema:
$ref: '../../schemas/management/plugins.yaml#/PluginResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'409':
description: Plugin already exists
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
/plugins/{name}:
get:
operationId: getPlugin
summary: Get a specific plugin
description: |
Returns the configuration for a specific plugin.
The response includes the plugin status with types array showing which interfaces
the plugin implements (llm, mcp, http). The `actualName` field shows the plugin name
from GetName() (used as the map key), which may differ from the display name (`name`).
tags:
- Plugins
parameters:
- name: name
in: path
required: true
description: Plugin display name (the config field `name`, not the internal `actualName` from GetName())
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/plugins.yaml#/Plugin'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Plugin not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
put:
operationId: updatePlugin
summary: Update a plugin
description: |
Updates a plugin's configuration. Will reload or stop the plugin based on enabled status.
The response `actualName` field shows the plugin name from GetName() (used as the map key),
which may differ from the display name (`name`).
tags:
- Plugins
parameters:
- name: name
in: path
required: true
description: Plugin display name (the config field `name`, not the internal `actualName` from GetName())
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/plugins.yaml#/UpdatePluginRequest'
responses:
'200':
description: Plugin updated successfully
content:
application/json:
schema:
$ref: '../../schemas/management/plugins.yaml#/PluginResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Plugin not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: deletePlugin
summary: Delete a plugin
description: Removes a plugin from the configuration and stops it if running.
tags:
- Plugins
parameters:
- name: name
in: path
required: true
description: Plugin display name (the config field `name`, not the internal `actualName` from GetName())
schema:
type: string
responses:
'200':
description: Plugin deleted successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Plugin not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'

View File

@@ -0,0 +1,651 @@
# Prompt Repository paths
folders:
get:
operationId: listFolders
summary: List folders
description: Returns all prompt folders.
tags:
- Prompt Repository
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
folders:
type: array
items:
$ref: '../../schemas/management/prompts.yaml#/Folder'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
post:
operationId: createFolder
summary: Create folder
description: Creates a new prompt folder.
tags:
- Prompt Repository
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/prompts.yaml#/CreateFolderRequest'
responses:
'200':
description: Folder created
content:
application/json:
schema:
type: object
properties:
folder:
$ref: '../../schemas/management/prompts.yaml#/Folder'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
folders-by-id:
get:
operationId: getFolder
summary: Get folder
description: Returns a folder by ID.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
folder:
$ref: '../../schemas/management/prompts.yaml#/Folder'
'404':
description: Folder not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
put:
operationId: updateFolder
summary: Update folder
description: Updates a folder's name or description.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/prompts.yaml#/UpdateFolderRequest'
responses:
'200':
description: Folder updated
content:
application/json:
schema:
type: object
properties:
folder:
$ref: '../../schemas/management/prompts.yaml#/Folder'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Folder not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: deleteFolder
summary: Delete folder
description: Deletes a folder and cascades to contained prompts.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Folder deleted
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'404':
description: Folder not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
prompts:
get:
operationId: listPrompts
summary: List prompts
description: Returns all prompts, optionally filtered by folder.
tags:
- Prompt Repository
parameters:
- name: folder_id
in: query
description: Filter by folder ID
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
prompts:
type: array
items:
$ref: '../../schemas/management/prompts.yaml#/Prompt'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
post:
operationId: createPrompt
summary: Create prompt
description: Creates a new prompt.
tags:
- Prompt Repository
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/prompts.yaml#/CreatePromptRequest'
responses:
'200':
description: Prompt created
content:
application/json:
schema:
type: object
properties:
prompt:
$ref: '../../schemas/management/prompts.yaml#/Prompt'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
prompts-by-id:
get:
operationId: getPrompt
summary: Get prompt
description: Returns a prompt by ID with its latest version.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
prompt:
$ref: '../../schemas/management/prompts.yaml#/Prompt'
'404':
description: Prompt not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
put:
operationId: updatePrompt
summary: Update prompt
description: Updates a prompt's name or folder.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/prompts.yaml#/UpdatePromptRequest'
responses:
'200':
description: Prompt updated
content:
application/json:
schema:
type: object
properties:
prompt:
$ref: '../../schemas/management/prompts.yaml#/Prompt'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: deletePrompt
summary: Delete prompt
description: Deletes a prompt and all its versions and sessions.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Prompt deleted
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'404':
description: Prompt not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
prompt-versions:
get:
operationId: listPromptVersions
summary: List prompt versions
description: Returns all versions for a prompt.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Prompt ID
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
versions:
type: array
items:
$ref: '../../schemas/management/prompts.yaml#/PromptVersion'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
post:
operationId: createPromptVersion
summary: Create prompt version
description: Creates a new version for a prompt.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Prompt ID
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/prompts.yaml#/CreateVersionRequest'
responses:
'200':
description: Version created
content:
application/json:
schema:
type: object
properties:
version:
$ref: '../../schemas/management/prompts.yaml#/PromptVersion'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
versions-by-id:
get:
operationId: getPromptVersion
summary: Get prompt version
description: Returns a specific version by ID.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Version ID
schema:
type: integer
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
version:
$ref: '../../schemas/management/prompts.yaml#/PromptVersion'
'404':
description: Version not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: deletePromptVersion
summary: Delete prompt version
description: Deletes a specific version.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Version ID
schema:
type: integer
responses:
'200':
description: Version deleted
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'404':
description: Version not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
prompt-sessions:
get:
operationId: listPromptSessions
summary: List prompt sessions
description: Returns all sessions for a prompt.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Prompt ID
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
sessions:
type: array
items:
$ref: '../../schemas/management/prompts.yaml#/PromptSession'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
post:
operationId: createPromptSession
summary: Create prompt session
description: Creates a new playground session for a prompt.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Prompt ID
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/prompts.yaml#/CreateSessionRequest'
responses:
'200':
description: Session created
content:
application/json:
schema:
type: object
properties:
session:
$ref: '../../schemas/management/prompts.yaml#/PromptSession'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
sessions-by-id:
get:
operationId: getPromptSession
summary: Get prompt session
description: Returns a specific session by ID.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Session ID
schema:
type: integer
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
session:
$ref: '../../schemas/management/prompts.yaml#/PromptSession'
'404':
description: Session not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
put:
operationId: updatePromptSession
summary: Update prompt session
description: Updates a session's messages, model params, etc.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Session ID
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/prompts.yaml#/UpdateSessionRequest'
responses:
'200':
description: Session updated
content:
application/json:
schema:
type: object
properties:
session:
$ref: '../../schemas/management/prompts.yaml#/PromptSession'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: deletePromptSession
summary: Delete prompt session
description: Deletes a specific session.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Session ID
schema:
type: integer
responses:
'200':
description: Session deleted
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'404':
description: Session not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
sessions-rename:
put:
operationId: renamePromptSession
summary: Rename prompt session
description: Renames a session.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Session ID
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/prompts.yaml#/RenameSessionRequest'
responses:
'200':
description: Session renamed
content:
application/json:
schema:
type: object
properties:
session:
$ref: '../../schemas/management/prompts.yaml#/PromptSession'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
sessions-commit:
post:
operationId: commitPromptSession
summary: Commit session as version
description: Commits the current session state as a new prompt version.
tags:
- Prompt Repository
parameters:
- name: id
in: path
required: true
description: Session ID
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/prompts.yaml#/CommitSessionRequest'
responses:
'200':
description: Version created from session
content:
application/json:
schema:
type: object
properties:
version:
$ref: '../../schemas/management/prompts.yaml#/PromptVersion'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'

View File

@@ -0,0 +1,512 @@
providers:
get:
operationId: listProviders
summary: List all providers
description: Returns a list of all configured providers with their configurations and status.
tags:
- Providers
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/ListProvidersResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
post:
operationId: addProvider
summary: Add a new provider
description: Adds a new provider with the specified configuration.
tags:
- Providers
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/AddProviderRequest'
responses:
'200':
description: Provider added successfully
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/ProviderResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'409':
description: Provider already exists
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
providers-by-name:
get:
operationId: getProvider
summary: Get a specific provider
description: Returns the configuration for a specific provider.
tags:
- Providers
parameters:
- name: provider
in: path
required: true
description: Provider name
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/ProviderResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Provider not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
put:
operationId: updateProvider
summary: Update a provider
description: |
Updates a provider's configuration. Expects ALL fields to be provided,
including both edited and non-edited fields. Partial updates are not supported.
tags:
- Providers
parameters:
- name: provider
in: path
required: true
description: Provider name
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/UpdateProviderRequest'
responses:
'200':
description: Provider updated successfully
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/ProviderResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: deleteProvider
summary: Delete a provider
description: Removes a provider from the configuration.
tags:
- Providers
parameters:
- name: provider
in: path
required: true
description: Provider name
schema:
type: string
responses:
'200':
description: Provider deleted successfully
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/ProviderResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Provider not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
provider-keys:
get:
operationId: listProviderKeys
summary: List keys for a provider
description: Returns all keys configured for a specific provider.
tags:
- Providers
parameters:
- name: provider
in: path
required: true
description: Provider name
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/ListProviderKeysResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Provider not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
post:
operationId: createProviderKey
summary: Create a key for a provider
description: |
Creates a new API key for the specified provider. The key `id` is auto-generated
if omitted. `enabled` defaults to `true` if omitted. `value` is required and must
not be empty. Keys cannot be created on keyless providers.
tags:
- Providers
parameters:
- name: provider
in: path
required: true
description: Provider name
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/Key'
responses:
'200':
description: Key created successfully
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/Key'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Provider not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'409':
description: Key ID already exists
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
provider-key-by-id:
get:
operationId: getProviderKey
summary: Get a specific key for a provider
description: Returns a single key for the specified provider.
tags:
- Providers
parameters:
- name: provider
in: path
required: true
description: Provider name
schema:
type: string
- name: key_id
in: path
required: true
description: Key ID
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/Key'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Provider or key not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
put:
operationId: updateProviderKey
summary: Update a key for a provider
description: |
Updates an existing key. Send the full key object. Redacted values sent back
unchanged are automatically preserved (the server merges them with the stored
raw values).
tags:
- Providers
parameters:
- name: provider
in: path
required: true
description: Provider name
schema:
type: string
- name: key_id
in: path
required: true
description: Key ID
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/Key'
responses:
'200':
description: Key updated successfully
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/Key'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Provider or key not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: deleteProviderKey
summary: Delete a key from a provider
description: Deletes a key from the specified provider. Returns the deleted key.
tags:
- Providers
parameters:
- name: provider
in: path
required: true
description: Provider name
schema:
type: string
- name: key_id
in: path
required: true
description: Key ID
schema:
type: string
responses:
'200':
description: Key deleted successfully
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/Key'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Provider or key not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
keys:
get:
operationId: listKeys
summary: List all keys
description: Returns a list of all configured API keys across all providers.
tags:
- Providers
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: '../../schemas/management/providers.yaml#/Key'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
models:
get:
operationId: listModelsManagement
summary: List models
description: |
Lists available models with optional filtering by query, provider, or keys.
tags:
- Providers
parameters:
- name: query
in: query
description: Filter models by name (case-insensitive partial match)
schema:
type: string
- name: provider
in: query
description: Filter by specific provider name
schema:
type: string
- name: keys
in: query
description: Comma-separated list of key IDs to filter models accessible by those keys
style: form
explode: false
schema:
type: array
items:
type: string
- name: limit
in: query
description: Maximum number of results to return (default 5)
schema:
type: integer
default: 5
- name: unfiltered
in: query
description: If true, return all models including those filtered out by provider-level restrictions
schema:
type: boolean
default: false
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/ListModelsResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
models-details:
get:
operationId: listModelDetailsManagement
summary: List model details
description: |
Lists available models with capability metadata, when available from the model catalog, with optional filtering by query, provider, or keys.
tags:
- Providers
parameters:
- name: query
in: query
description: Filter models by name (case-insensitive partial match)
schema:
type: string
- name: provider
in: query
description: Filter by specific provider name
schema:
type: string
- name: keys
in: query
description: Comma-separated list of key IDs to filter models accessible by those keys
style: form
explode: false
schema:
type: array
items:
type: string
- name: limit
in: query
description: Maximum number of results to return (default 20)
schema:
type: integer
default: 20
- name: unfiltered
in: query
description: If true, return all models including those filtered out by provider-level restrictions
schema:
type: boolean
default: false
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/providers.yaml#/ListModelDetailsResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
models-parameters:
get:
operationId: getModelParameters
summary: Get model parameters
description: Returns the available parameter definitions for models.
tags:
- Providers
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
additionalProperties: true
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
models-base:
get:
operationId: listBaseModels
summary: List base models
description: Returns a list of base models from the model catalog.
tags:
- Providers
parameters:
- name: query
in: query
description: Filter models by name
schema:
type: string
- name: provider
in: query
description: Filter by provider
schema:
type: string
- name: limit
in: query
description: Maximum number of results to return
schema:
type: integer
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
additionalProperties: true
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'

View File

@@ -0,0 +1,105 @@
login:
post:
operationId: login
summary: Login
description: |
Authenticates a user and returns a session token.
Sets a cookie with the session token for subsequent requests.
tags:
- Session
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/session.yaml#/LoginRequest'
responses:
'200':
description: Login successful
content:
application/json:
schema:
$ref: '../../schemas/management/session.yaml#/LoginResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'401':
description: Invalid credentials
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'403':
description: Authentication is not enabled
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
logout:
post:
operationId: logout
summary: Logout
description: Logs out the current user and invalidates the session token.
tags:
- Session
responses:
'200':
description: Logout successful
content:
application/json:
schema:
$ref: '../../schemas/management/session.yaml#/LogoutResponse'
'403':
description: Authentication is not enabled
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
is-auth-enabled:
get:
operationId: isAuthEnabled
summary: Check if authentication is enabled
description: Returns whether authentication is enabled and if the current token is valid.
tags:
- Session
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/session.yaml#/IsAuthEnabledResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
ws-ticket:
post:
operationId: issueWSTicket
summary: Issue WebSocket ticket
description: |
Issues a short-lived ticket for authenticating WebSocket connections.
The ticket can be used as a query parameter when upgrading to WebSocket.
tags:
- Session
responses:
'200':
description: Ticket issued successfully
content:
application/json:
schema:
type: object
properties:
ticket:
type: string
description: Short-lived WebSocket authentication ticket
'403':
description: Authentication is not enabled
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'

View File

@@ -0,0 +1,534 @@
users:
get:
operationId: listUsers
summary: List users
description: Returns a paginated list of users with optional search.
tags:
- Users
parameters:
- name: page
in: query
description: Page number (1-based)
schema:
type: integer
minimum: 1
default: 1
- name: limit
in: query
description: Number of users per page (max 100)
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: search
in: query
description: Search by name or email
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/ListUsersResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
post:
operationId: createUser
summary: Create user
description: Manually creates a new user in the organization.
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/CreateUserRequest'
responses:
'200':
description: User created successfully
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/UserResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'409':
description: User with this email already exists
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
users-by-id:
delete:
operationId: deleteUser
summary: Delete user
description: >
Permanently removes a user from the organization. This cascades to delete
the user's governance settings (budget/rate limits), team memberships,
access profiles, and OIDC sessions. Cannot delete yourself.
tags:
- Users
parameters:
- name: id
in: path
required: true
description: User ID
schema:
type: string
responses:
'200':
description: User deleted successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'400':
description: Bad request (e.g. cannot delete yourself)
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'404':
description: User not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
users-me-permissions:
get:
operationId: getCurrentUserPermissions
summary: Get current user permissions
description: >
Returns the RBAC permissions for the authenticated user. When SCIM is not
enabled, returns full permissions for all resources. Otherwise returns the
permissions associated with the user's assigned role.
tags:
- Users
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/PermissionsResponse'
'401':
description: Unauthorized (user not authenticated)
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'404':
description: User not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
users-role:
put:
operationId: assignUserRole
summary: Assign role to user
description: >
Assigns an RBAC role to a user. This also auto-assigns the default
access profile for the new role and reloads the RBAC permission cache.
tags:
- Users
parameters:
- name: id
in: path
required: true
description: User ID
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/AssignUserRoleRequest'
responses:
'200':
description: Role assigned successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: User or role not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
users-teams:
get:
operationId: getUserTeams
summary: Get user's teams
description: Returns the list of teams a user belongs to, including the membership source.
tags:
- Users
parameters:
- name: id
in: path
required: true
description: User ID
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/UserTeamsResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: User not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
put:
operationId: updateUserTeams
summary: Update user's team assignments
description: >
Replaces the user's manual team assignments. Synced team memberships
(from SCIM providers) are preserved and cannot be removed via this endpoint.
tags:
- Users
parameters:
- name: id
in: path
required: true
description: User ID
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/UpdateUserTeamsRequest'
responses:
'200':
description: Teams updated successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'400':
description: Bad request (e.g. team not found)
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'404':
description: User not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
# ---- Teams ----
teams:
get:
operationId: listTeams
summary: List teams
description: Returns a paginated list of teams with optional search.
tags:
- Teams
parameters:
- name: page
in: query
description: Page number (1-based)
schema:
type: integer
minimum: 1
default: 1
- name: limit
in: query
description: Number of teams per page (max 100)
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: search
in: query
description: Search by team name
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/ListTeamsResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
post:
operationId: createTeam
summary: Create team
description: Creates a new team. The team ID is derived from the name.
tags:
- Teams
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/CreateTeamRequest'
responses:
'200':
description: Team created successfully
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/CreateTeamResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'409':
description: Team with this name already exists
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
teams-by-id:
get:
operationId: getTeam
summary: Get team
description: Returns details of a specific team including member count.
tags:
- Teams
parameters:
- name: id
in: path
required: true
description: Team ID
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/TeamObject'
'404':
description: Team not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
put:
operationId: updateTeam
summary: Update team
description: Updates a team. Note that renaming teams is not allowed.
tags:
- Teams
parameters:
- name: id
in: path
required: true
description: Team ID
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/UpdateTeamRequest'
responses:
'200':
description: Team updated successfully
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/CreateTeamResponse'
'400':
description: Bad request (e.g. renaming not allowed)
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'404':
description: Team not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
delete:
operationId: deleteTeam
summary: Delete team
description: Permanently removes a team.
tags:
- Teams
parameters:
- name: id
in: path
required: true
description: Team ID
schema:
type: string
responses:
'200':
description: Team deleted successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'404':
description: Team not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
# ---- Team Members ----
team-members:
get:
operationId: getTeamMembers
summary: List team members
description: Returns all members of a team with their user details and membership source.
tags:
- Teams
parameters:
- name: id
in: path
required: true
description: Team ID
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/TeamMembersResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Team not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
post:
operationId: addTeamMember
summary: Add team member
description: Adds a user to a team. Both the team and user must exist.
tags:
- Teams
parameters:
- name: id
in: path
required: true
description: Team ID
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/users.yaml#/AddTeamMemberRequest'
responses:
'200':
description: Member added successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'404':
description: Team or user not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'409':
description: User is already a member of this team
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'
team-member-by-id:
delete:
operationId: removeTeamMember
summary: Remove team member
description: Removes a user from a team.
tags:
- Teams
parameters:
- name: id
in: path
required: true
description: Team ID
schema:
type: string
- name: userId
in: path
required: true
description: User ID to remove
schema:
type: string
responses:
'200':
description: Member removed successfully
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/MessageResponse'
'404':
description: Membership not found
content:
application/json:
schema:
$ref: '../../schemas/management/common.yaml#/ErrorResponse'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'