> ## Documentation Index
> Fetch the complete documentation index at: https://bifrost-dev.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# List projects

> Returns projects visible to the caller: those they created, those with no
recorded creator, and those they belong to. Each project's roster is
narrowed the same way, so `members` is a subset of the true roster and
`pagination.total` counts only what the caller may see.


<Note>
  This endpoint is available in [Bifrost Enterprise](https://www.getmaxim.ai/bifrost/enterprise) only.
</Note>


## OpenAPI

````yaml /openapi/openapi.json get /api/governance/projects
openapi: 3.1.0
info:
  title: Bifrost API
  description: >
    Bifrost HTTP Transport API for AI model inference and gateway management.


    This API provides a unified interface for interacting with multiple AI
    providers

    including OpenAI, Anthropic, Bedrock, Gemini, and more through a single API,

    along with comprehensive management APIs for configuring and monitoring the
    gateway.


    ## API Structure


    ### Unified Inference API (`/v1/*`)

    The primary API using Bifrost's unified format. Model parameters use the
    format

    `provider/model` (e.g., `openai/gpt-4`, `anthropic/claude-3-opus`).


    ### Async Inference API (`/v1/async/*`)

    Submit inference requests for asynchronous execution. Returns a job ID
    immediately

    and allows polling for results. Supports all inference types except batches,
    files,

    and containers.


    ### Provider Integration APIs

    Native provider-format APIs for drop-in compatibility:

    - `/openai/*` - OpenAI-compatible API

    - `/anthropic/*` - Anthropic-compatible API

    - `/genai/*` - Google GenAI (Gemini) compatible API

    - `/bedrock/*` - AWS Bedrock compatible API

    - `/cohere/*` - Cohere compatible API


    ### Framework Integration APIs

    Multi-provider proxy endpoints for AI frameworks:

    - `/litellm/*` - LiteLLM proxy with all provider formats

    - `/langchain/*` - LangChain compatible endpoints

    - `/pydanticai/*` - PydanticAI compatible endpoints


    ### Management APIs (`/api/*`)

    APIs for managing and monitoring the Bifrost gateway:

    - `/api/config` - Configuration management

    - `/api/providers` - Provider and API key management

    - `/api/plugins` - Plugin management

    - `/api/governance/*` - Virtual keys, teams, customers, budgets, rate
    limits, routing rules, and pricing overrides

    - `/api/logs` - Log search and analytics

    - `/api/mcp/*` - MCP (Model Context Protocol) client management

    - `/api/session/*` - Authentication and session management

    - `/api/cache/*` - Cache management

    - `/health` - Health check endpoint


    ## Fallbacks

    Requests can include fallback models that will be tried if the primary model
    fails.
  version: 1.0.0
  contact:
    name: Contact Us
    url: https://getmaxim.ai/bifrost
  license:
    name: Apache 2.0
    url: https://opensource.org/licenses/Apache-2.0
servers:
  - url: '{baseUrl}'
    description: Your Bifrost instance
    variables:
      baseUrl:
        default: http://localhost:8080
        description: Base URL of your Bifrost instance (e.g. https://bifrost.mycompany.com)
security:
  - BearerAuth: []
  - BasicAuth: []
  - ApiKeyAuth: []
tags:
  - name: Models
    description: Model listing and information
  - name: Chat Completions
    description: Chat-based text generation
  - name: Text Completions
    description: Text completion generation
  - name: Responses
    description: OpenAI Responses API compatible endpoints
  - name: OCR
    description: Optical character recognition for documents and images
  - name: Rerank
    description: Document reranking by relevance to a query
  - name: Embeddings
    description: Text embedding generation
  - name: Images
    description: Image generations, editing, and variations
  - name: Videos
    description: Video generation and management
  - name: Audio
    description: Speech synthesis and transcription
  - name: Count Tokens
    description: Token counting utilities
  - name: Batch
    description: Batch processing operations
  - name: Files
    description: File management operations
  - name: Containers
    description: Container management operations
  - name: Async Jobs
    description: Asynchronous job submission and retrieval endpoints
  - name: Realtime
    description: Realtime WebSocket and WebRTC endpoints
  - name: OpenAI Integration
    description: OpenAI-compatible API endpoints (/openai/*)
  - name: Azure Integration
    description: Azure OpenAI integration endpoints
  - name: Anthropic Integration
    description: Anthropic-compatible API endpoints (/anthropic/*)
  - name: GenAI Integration
    description: Google GenAI (Gemini) compatible API endpoints (/genai/*)
  - name: Bedrock Integration
    description: AWS Bedrock compatible API endpoints (/bedrock/*)
  - name: Cohere Integration
    description: Cohere compatible API endpoints (/cohere/*)
  - name: LiteLLM Integration
    description: LiteLLM proxy endpoints with multi-provider support (/litellm/*)
  - name: LangChain Integration
    description: LangChain compatible endpoints with multi-provider support (/langchain/*)
  - name: PydanticAI Integration
    description: >-
      PydanticAI compatible endpoints with multi-provider support
      (/pydanticai/*)
  - name: Health
    description: Health check endpoints
  - name: Configuration
    description: Configuration management endpoints
  - name: Session
    description: Session and authentication endpoints
  - name: Providers
    description: Provider management endpoints
  - name: Plugins
    description: Plugin management endpoints
  - name: MCP
    description: Model Context Protocol endpoints
  - name: Governance
    description: Virtual keys, teams, and customers management
  - name: Routing
    description: Routing rules and complexity analyzer configuration
  - name: Logging
    description: Log search and management endpoints
  - name: Cache
    description: Cache management endpoints
  - name: Vault
    description: Vault secret management endpoints
  - name: Skills
    description: Skills Repository management, marketplace, and download endpoints
  - name: Audit Logs
    description: >-
      CADF-compliant audit log search, export, and signature verification
      endpoints
  - name: Webhooks
    description: Webhook endpoint management and signed async-job delivery history
  - name: Notifications
    description: >-
      Role-targeted dashboard notifications, delivered over the dashboard
      WebSocket
paths:
  /api/governance/projects:
    get:
      tags:
        - Projects
      summary: List projects
      description: >
        Returns projects visible to the caller: those they created, those with
        no

        recorded creator, and those they belong to. Each project's roster is

        narrowed the same way, so `members` is a subset of the true roster and

        `pagination.total` counts only what the caller may see.
      operationId: listProjects
      parameters:
        - name: limit
          in: query
          description: Page size, clamped to 100. Defaults to 20.
          schema:
            type: integer
        - name: offset
          in: query
          schema:
            type: integer
        - name: page
          in: query
          description: One-based page number, consulted only when `offset` is absent.
          schema:
            type: integer
        - name: search
          in: query
          description: Case-insensitive match on name or description.
          schema:
            type: string
        - name: is_active
          in: query
          description: Return only enabled or only disabled projects.
          schema:
            type: boolean
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  projects:
                    type: array
                    items:
                      type: object
                      description: >-
                        A per-request access scope and accounting ledger that
                        callers opt into with a header.
                      properties:
                        id:
                          type: string
                          readOnly: true
                        name:
                          type: string
                          description: >-
                            Globally unique. Requests reference it with the
                            `x-bf-project-name` header.
                        description:
                          type: string
                          nullable: true
                        is_active:
                          type: boolean
                          default: true
                          description: >-
                            A disabled project refuses every request that names
                            it.
                        expires_at:
                          type: string
                          format: date-time
                          nullable: true
                          description: >-
                            An expired project refuses every request that names
                            it. The comparison is inclusive.
                        access_rule:
                          type: string
                          enum:
                            - intersect
                            - union
                          description: >-
                            How the project's own access composes with the
                            access the caller already holds. `intersect` permits
                            only what both allow, so a project with no provider
                            config permits nothing. `union` leaves the caller's
                            access untouched and adds to it, so a project with
                            no provider or MCP config only attributes and caps
                            spend.
                        membership_mode:
                          type: string
                          enum:
                            - explicit
                            - open
                          default: explicit
                          description: >-
                            `explicit` admits only the users on the roster.
                            `open` admits every authenticated caller and has no
                            membership rows, which is why it cannot divide a
                            budget between members.
                        accounting_mode:
                          type: string
                          enum:
                            - both
                            - project_only
                            - principal_only
                          default: both
                          description: >-
                            Which ledgers a request's spend lands on. `both`
                            charges the project and the caller. `project_only`
                            takes the request off everything the caller funds,
                            including the teams and business units above them.
                            `principal_only` leaves the project's caps on record
                            but checks and charges none of them. The
                            deployment's own global caps always apply.
                        split_policy:
                          type: string
                          enum:
                            - none
                            - equal
                          default: none
                          description: >-
                            `none` keeps the project's caps shared, and
                            individual members can still be capped by hand.
                            `equal` gives every member an equal slice of every
                            budget and rate limit the project holds, at every
                            tier, as a second cap within it.
                        calendar_aligned:
                          type: boolean
                          default: false
                          description: >-
                            Snaps every window the project holds, including each
                            member's derived slice, onto calendar boundaries
                            instead of running from creation.
                        budgets:
                          type: array
                          nullable: true
                          items:
                            type: object
                            description: >-
                              A spend cap on a project, on a provider inside it,
                              or on a model under that provider. On an update,
                              restating `id` pairs the declaration with its
                              stored row so accumulated spend and the window
                              anchor carry over; omit `id` to create a new cap.
                            required:
                              - max_limit
                              - reset_duration
                            properties:
                              id:
                                type: string
                                description: >-
                                  Omit to create. Restate to update in place. An
                                  id the project does not hold is refused.
                              max_limit:
                                type: number
                                minimum: 0
                                description: Cap in dollars.
                              reset_duration:
                                type: string
                                description: >-
                                  Reset window as a number and a unit, for
                                  example `30s`, `5m`, `1h`, `1d`, `1w`, `1M`,
                                  `1Q`, `1Y`. Only day-or-longer windows can be
                                  calendar-aligned.
                                example: 1M
                              reset_config:
                                type: object
                                description: >-
                                  Window settings the reset duration cannot
                                  express. Only valid when `reset_duration` is
                                  quarterly (`1Q`).
                                properties:
                                  quarter_start_month:
                                    type: integer
                                    minimum: 1
                                    maximum: 12
                                    description: >-
                                      First month of Q1 as 1-12. Omitted means
                                      January. Only the value modulo 3 changes
                                      the reset dates, so January, April, July
                                      and October all reset on calendar
                                      quarters.
                                additionalProperties: false
                              current_usage:
                                type: number
                                readOnly: true
                                description: Spend recorded in the current window.
                              last_reset:
                                type: string
                                format: date-time
                                readOnly: true
                              override_amount:
                                type: number
                                readOnly: true
                                description: >-
                                  Operator top-up added to `max_limit` while
                                  active. Projects have no endpoint that sets
                                  one; the field is reported for completeness.
                              override_mode:
                                type: string
                                readOnly: true
                              override_cycles_remaining:
                                type: integer
                                readOnly: true
                              override_cycles_total:
                                type: integer
                                readOnly: true
                              override_anchor_reset:
                                type: string
                                format: date-time
                                readOnly: true
                              config_hash:
                                type: string
                                readOnly: true
                              created_at:
                                type: string
                                format: date-time
                                readOnly: true
                              updated_at:
                                type: string
                                format: date-time
                                readOnly: true
                        rate_limit:
                          type: object
                          description: >-
                            A token and request rate limit on a project, on a
                            provider inside it, or on a model under that
                            provider. The two dimensions run independent
                            windows, and a cap is enforced only together with
                            its window.
                          properties:
                            id:
                              type: string
                              description: Omit to create. Restate to update in place.
                            token_max_limit:
                              type: integer
                              minimum: 0
                              description: >-
                                Maximum tokens per window. Requires
                                `token_reset_duration`. On a project with
                                `split_policy: equal`, a cap below the member
                                count is refused, since a slice is a whole
                                number of tokens.
                            token_reset_duration:
                              type: string
                              example: 1h
                            request_max_limit:
                              type: integer
                              minimum: 0
                              description: >-
                                Maximum requests per window. Requires
                                `request_reset_duration`. Subject to the same
                                lower bound under `split_policy: equal`.
                            request_reset_duration:
                              type: string
                              example: 1h
                            token_current_usage:
                              type: integer
                              readOnly: true
                            token_last_reset:
                              type: string
                              format: date-time
                              readOnly: true
                            request_current_usage:
                              type: integer
                              readOnly: true
                            request_last_reset:
                              type: string
                              format: date-time
                              readOnly: true
                            config_hash:
                              type: string
                              readOnly: true
                            created_at:
                              type: string
                              format: date-time
                              readOnly: true
                            updated_at:
                              type: string
                              format: date-time
                              readOnly: true
                        provider_configs:
                          type: array
                          items:
                            type: object
                            description: >-
                              What the project allows on one provider, and the
                              money that provider's use answers to. A project
                              names each provider at most once.
                            required:
                              - provider_name
                            properties:
                              id:
                                type: integer
                                description: >-
                                  Omit or send `0` to create. Restate to update
                                  in place. An id the project does not hold is
                                  refused.
                              provider_name:
                                type: string
                                example: openai
                              all_models_allowed:
                                type: boolean
                                default: false
                                description: Allows every model the provider offers.
                              allowed_models:
                                type: array
                                nullable: true
                                items:
                                  type: string
                                description: >-
                                  Allowlist. `["*"]` allows every model. A list
                                  may not mix `*` with named entries.
                              blacklisted_models:
                                type: array
                                nullable: true
                                items:
                                  type: string
                                description: >-
                                  Denylist, which wins over the allowlist.
                                  `["*"]` blocks everything.
                              key_ids:
                                type: array
                                nullable: true
                                items:
                                  type: string
                                description: >-
                                  Provider keys that may serve the request.
                                  `["*"]` allows all; an empty list allows none.
                                  Each id must exist and belong to this
                                  provider.
                              weight:
                                type: number
                                nullable: true
                                description: >-
                                  Load-balancing preference for this provider
                                  inside the project. Null leaves the caller's
                                  own preference standing. Negative values are
                                  refused.
                              budgets:
                                type: array
                                nullable: true
                                items:
                                  type: object
                                  description: >-
                                    A spend cap on a project, on a provider
                                    inside it, or on a model under that
                                    provider. On an update, restating `id` pairs
                                    the declaration with its stored row so
                                    accumulated spend and the window anchor
                                    carry over; omit `id` to create a new cap.
                                  required:
                                    - max_limit
                                    - reset_duration
                                  properties:
                                    id:
                                      type: string
                                      description: >-
                                        Omit to create. Restate to update in
                                        place. An id the project does not hold
                                        is refused.
                                    max_limit:
                                      type: number
                                      minimum: 0
                                      description: Cap in dollars.
                                    reset_duration:
                                      type: string
                                      description: >-
                                        Reset window as a number and a unit, for
                                        example `30s`, `5m`, `1h`, `1d`, `1w`,
                                        `1M`, `1Q`, `1Y`. Only day-or-longer
                                        windows can be calendar-aligned.
                                      example: 1M
                                    reset_config:
                                      type: object
                                      description: >-
                                        Window settings the reset duration
                                        cannot express. Only valid when
                                        `reset_duration` is quarterly (`1Q`).
                                      properties:
                                        quarter_start_month:
                                          type: integer
                                          minimum: 1
                                          maximum: 12
                                          description: >-
                                            First month of Q1 as 1-12. Omitted means
                                            January. Only the value modulo 3 changes
                                            the reset dates, so January, April, July
                                            and October all reset on calendar
                                            quarters.
                                      additionalProperties: false
                                    current_usage:
                                      type: number
                                      readOnly: true
                                      description: Spend recorded in the current window.
                                    last_reset:
                                      type: string
                                      format: date-time
                                      readOnly: true
                                    override_amount:
                                      type: number
                                      readOnly: true
                                      description: >-
                                        Operator top-up added to `max_limit`
                                        while active. Projects have no endpoint
                                        that sets one; the field is reported for
                                        completeness.
                                    override_mode:
                                      type: string
                                      readOnly: true
                                    override_cycles_remaining:
                                      type: integer
                                      readOnly: true
                                    override_cycles_total:
                                      type: integer
                                      readOnly: true
                                    override_anchor_reset:
                                      type: string
                                      format: date-time
                                      readOnly: true
                                    config_hash:
                                      type: string
                                      readOnly: true
                                    created_at:
                                      type: string
                                      format: date-time
                                      readOnly: true
                                    updated_at:
                                      type: string
                                      format: date-time
                                      readOnly: true
                              rate_limit:
                                type: object
                                description: >-
                                  A token and request rate limit on a project,
                                  on a provider inside it, or on a model under
                                  that provider. The two dimensions run
                                  independent windows, and a cap is enforced
                                  only together with its window.
                                properties:
                                  id:
                                    type: string
                                    description: >-
                                      Omit to create. Restate to update in
                                      place.
                                  token_max_limit:
                                    type: integer
                                    minimum: 0
                                    description: >-
                                      Maximum tokens per window. Requires
                                      `token_reset_duration`. On a project with
                                      `split_policy: equal`, a cap below the
                                      member count is refused, since a slice is
                                      a whole number of tokens.
                                  token_reset_duration:
                                    type: string
                                    example: 1h
                                  request_max_limit:
                                    type: integer
                                    minimum: 0
                                    description: >-
                                      Maximum requests per window. Requires
                                      `request_reset_duration`. Subject to the
                                      same lower bound under `split_policy:
                                      equal`.
                                  request_reset_duration:
                                    type: string
                                    example: 1h
                                  token_current_usage:
                                    type: integer
                                    readOnly: true
                                  token_last_reset:
                                    type: string
                                    format: date-time
                                    readOnly: true
                                  request_current_usage:
                                    type: integer
                                    readOnly: true
                                  request_last_reset:
                                    type: string
                                    format: date-time
                                    readOnly: true
                                  config_hash:
                                    type: string
                                    readOnly: true
                                  created_at:
                                    type: string
                                    format: date-time
                                    readOnly: true
                                  updated_at:
                                    type: string
                                    format: date-time
                                    readOnly: true
                              model_budgets:
                                type: array
                                items:
                                  type: object
                                  description: >-
                                    Caps for one model under a provider
                                    configuration. A provider may carry up to
                                    100 of these, and the `*` tier is not
                                    accepted here because the provider
                                    configuration's own caps cover it.
                                  required:
                                    - model_name
                                  properties:
                                    model_name:
                                      type: string
                                      description: Concrete model name. `*` is refused.
                                    budgets:
                                      type: array
                                      items:
                                        type: object
                                        description: >-
                                          A spend cap on a project, on a provider
                                          inside it, or on a model under that
                                          provider. On an update, restating `id`
                                          pairs the declaration with its stored
                                          row so accumulated spend and the window
                                          anchor carry over; omit `id` to create a
                                          new cap.
                                        required:
                                          - max_limit
                                          - reset_duration
                                        properties:
                                          id:
                                            type: string
                                            description: >-
                                              Omit to create. Restate to update in
                                              place. An id the project does not hold
                                              is refused.
                                          max_limit:
                                            type: number
                                            minimum: 0
                                            description: Cap in dollars.
                                          reset_duration:
                                            type: string
                                            description: >-
                                              Reset window as a number and a unit, for
                                              example `30s`, `5m`, `1h`, `1d`, `1w`,
                                              `1M`, `1Q`, `1Y`. Only day-or-longer
                                              windows can be calendar-aligned.
                                            example: 1M
                                          reset_config:
                                            type: object
                                            description: >-
                                              Window settings the reset duration
                                              cannot express. Only valid when
                                              `reset_duration` is quarterly (`1Q`).
                                            properties:
                                              quarter_start_month:
                                                type: integer
                                                minimum: 1
                                                maximum: 12
                                                description: >-
                                                  First month of Q1 as 1-12. Omitted means
                                                  January. Only the value modulo 3 changes
                                                  the reset dates, so January, April, July
                                                  and October all reset on calendar
                                                  quarters.
                                            additionalProperties: false
                                          current_usage:
                                            type: number
                                            readOnly: true
                                            description: Spend recorded in the current window.
                                          last_reset:
                                            type: string
                                            format: date-time
                                            readOnly: true
                                          override_amount:
                                            type: number
                                            readOnly: true
                                            description: >-
                                              Operator top-up added to `max_limit`
                                              while active. Projects have no endpoint
                                              that sets one; the field is reported for
                                              completeness.
                                          override_mode:
                                            type: string
                                            readOnly: true
                                          override_cycles_remaining:
                                            type: integer
                                            readOnly: true
                                          override_cycles_total:
                                            type: integer
                                            readOnly: true
                                          override_anchor_reset:
                                            type: string
                                            format: date-time
                                            readOnly: true
                                          config_hash:
                                            type: string
                                            readOnly: true
                                          created_at:
                                            type: string
                                            format: date-time
                                            readOnly: true
                                          updated_at:
                                            type: string
                                            format: date-time
                                            readOnly: true
                                    rate_limit:
                                      type: object
                                      description: >-
                                        A token and request rate limit on a
                                        project, on a provider inside it, or on
                                        a model under that provider. The two
                                        dimensions run independent windows, and
                                        a cap is enforced only together with its
                                        window.
                                      properties:
                                        id:
                                          type: string
                                          description: >-
                                            Omit to create. Restate to update in
                                            place.
                                        token_max_limit:
                                          type: integer
                                          minimum: 0
                                          description: >-
                                            Maximum tokens per window. Requires
                                            `token_reset_duration`. On a project
                                            with `split_policy: equal`, a cap below
                                            the member count is refused, since a
                                            slice is a whole number of tokens.
                                        token_reset_duration:
                                          type: string
                                          example: 1h
                                        request_max_limit:
                                          type: integer
                                          minimum: 0
                                          description: >-
                                            Maximum requests per window. Requires
                                            `request_reset_duration`. Subject to the
                                            same lower bound under `split_policy:
                                            equal`.
                                        request_reset_duration:
                                          type: string
                                          example: 1h
                                        token_current_usage:
                                          type: integer
                                          readOnly: true
                                        token_last_reset:
                                          type: string
                                          format: date-time
                                          readOnly: true
                                        request_current_usage:
                                          type: integer
                                          readOnly: true
                                        request_last_reset:
                                          type: string
                                          format: date-time
                                          readOnly: true
                                        config_hash:
                                          type: string
                                          readOnly: true
                                        created_at:
                                          type: string
                                          format: date-time
                                          readOnly: true
                                        updated_at:
                                          type: string
                                          format: date-time
                                          readOnly: true
                                  additionalProperties: false
                                description: >-
                                  Per-model caps under this provider. Stored as
                                  project-scoped model configurations and
                                  reassembled on read, so this field is absent
                                  from `GET
                                  /api/governance/users/{user_id}/projects`.
                        mcp_configs:
                          type: array
                          items:
                            type: object
                            description: >-
                              The tools of one MCP client the project may
                              execute. Naming a client with an empty tool list
                              still counts as the project having named it, so a
                              client the project closes off cannot be reopened
                              by a default-allowed rule.
                            properties:
                              id:
                                type: integer
                                description: >-
                                  Omit or send `0` to create. Restate to update
                                  in place.
                              mcp_client_id:
                                type: integer
                                description: >-
                                  The stored MCP client. May be omitted when
                                  `mcp_client_name` is given, which is resolved
                                  to this id on write.
                              mcp_client_name:
                                type: string
                                description: >-
                                  Write-only convenience. Resolved to
                                  `mcp_client_id`; a name that matches no client
                                  is refused. Never returned on a read.
                              mcp_client:
                                readOnly: true
                                allOf:
                                  - $ref: '#/components/schemas/MCPClient'
                                description: The resolved client, included on reads.
                              tools_to_execute:
                                type: array
                                nullable: true
                                items:
                                  type: string
                                description: >-
                                  `["*"]` allows every tool the client exposes,
                                  including ones added later. An empty list
                                  allows none. A list may not mix `*` with named
                                  entries.
                        virtual_mcps:
                          type: array
                          items:
                            type: object
                            description: >-
                              A virtual MCP assigned to the project. A scoped
                              request can reach each one at its `/mcp/<slug>`
                              endpoint. Assignments are a set, so a repeated id
                              is ignored rather than doubled, and the list is
                              replaced wholesale on update rather than diffed.
                            required:
                              - virtual_mcp_id
                            properties:
                              virtual_mcp_id:
                                type: integer
                                minimum: 1
                            additionalProperties: false
                        members:
                          type: array
                          readOnly: true
                          items:
                            type: object
                            description: >-
                              A user on a project's roster. Members are users,
                              never keys or teams: a key authenticates a
                              request, and the user behind it is who belongs to
                              a project.
                            required:
                              - user_id
                            properties:
                              id:
                                type: string
                                readOnly: true
                                description: >-
                                  The membership row id, which is the
                                  `{member_id}` of the member routes.
                              user_id:
                                type: string
                                description: >-
                                  Immutable after creation. Changing it is a
                                  remove and an add.
                              budget_shares:
                                type: array
                                items:
                                  type: object
                                  description: >-
                                    One member's cap on a budget the project
                                    holds. The share is a second cap, not a
                                    replacement: the budget it slices still caps
                                    the whole, and whichever binds first refuses
                                    the request.
                                  required:
                                    - source_budget_id
                                  properties:
                                    id:
                                      type: string
                                      readOnly: true
                                    project_id:
                                      type: string
                                      readOnly: true
                                    user_id:
                                      type: string
                                      readOnly: true
                                    source_budget_id:
                                      type: string
                                      description: >-
                                        The budget being sliced. Must be one the
                                        project holds, at any tier.
                                    budget_id:
                                      type: string
                                      readOnly: true
                                      description: >-
                                        The derived governance budget that
                                        enforces the slice.
                                    share_value:
                                      type: number
                                      description: >-
                                        The authored figure. A percent share
                                        must be greater than 0 and at most 100;
                                        an amount share must be greater than 0.
                                        Null on every slice derived by an equal
                                        split.
                                    share_type:
                                      type: string
                                      enum:
                                        - percent
                                        - amount
                                      description: >-
                                        Whether a member's authored share is a
                                        percentage of the source cap or an
                                        absolute figure. Budget shares must
                                        state this explicitly; a rate-limit
                                        share left blank settles to `amount`.
                                    budget:
                                      readOnly: true
                                      allOf:
                                        - type: object
                                          description: >-
                                            A spend cap on a project, on a provider
                                            inside it, or on a model under that
                                            provider. On an update, restating `id`
                                            pairs the declaration with its stored
                                            row so accumulated spend and the window
                                            anchor carry over; omit `id` to create a
                                            new cap.
                                          required:
                                            - max_limit
                                            - reset_duration
                                          properties:
                                            id:
                                              type: string
                                              description: >-
                                                Omit to create. Restate to update in
                                                place. An id the project does not hold
                                                is refused.
                                            max_limit:
                                              type: number
                                              minimum: 0
                                              description: Cap in dollars.
                                            reset_duration:
                                              type: string
                                              description: >-
                                                Reset window as a number and a unit, for
                                                example `30s`, `5m`, `1h`, `1d`, `1w`,
                                                `1M`, `1Q`, `1Y`. Only day-or-longer
                                                windows can be calendar-aligned.
                                              example: 1M
                                            reset_config:
                                              type: object
                                              description: >-
                                                Window settings the reset duration
                                                cannot express. Only valid when
                                                `reset_duration` is quarterly (`1Q`).
                                              properties:
                                                quarter_start_month:
                                                  type: integer
                                                  minimum: 1
                                                  maximum: 12
                                                  description: >-
                                                    First month of Q1 as 1-12. Omitted means
                                                    January. Only the value modulo 3 changes
                                                    the reset dates, so January, April, July
                                                    and October all reset on calendar
                                                    quarters.
                                              additionalProperties: false
                                            current_usage:
                                              type: number
                                              readOnly: true
                                              description: Spend recorded in the current window.
                                            last_reset:
                                              type: string
                                              format: date-time
                                              readOnly: true
                                            override_amount:
                                              type: number
                                              readOnly: true
                                              description: >-
                                                Operator top-up added to `max_limit`
                                                while active. Projects have no endpoint
                                                that sets one; the field is reported for
                                                completeness.
                                            override_mode:
                                              type: string
                                              readOnly: true
                                            override_cycles_remaining:
                                              type: integer
                                              readOnly: true
                                            override_cycles_total:
                                              type: integer
                                              readOnly: true
                                            override_anchor_reset:
                                              type: string
                                              format: date-time
                                              readOnly: true
                                            config_hash:
                                              type: string
                                              readOnly: true
                                            created_at:
                                              type: string
                                              format: date-time
                                              readOnly: true
                                            updated_at:
                                              type: string
                                              format: date-time
                                              readOnly: true
                                      description: >-
                                        The derived budget row, with its own
                                        usage.
                                    created_at:
                                      type: string
                                      format: date-time
                                      readOnly: true
                                    updated_at:
                                      type: string
                                      format: date-time
                                      readOnly: true
                              rate_limit_shares:
                                type: array
                                items:
                                  type: object
                                  description: >-
                                    One member's cap on a rate limit the project
                                    holds. The token and request dimensions are
                                    authored independently, so a member may hold
                                    a percentage of tokens and a flat count of
                                    requests.
                                  required:
                                    - source_rate_limit_id
                                  properties:
                                    id:
                                      type: string
                                      readOnly: true
                                    project_id:
                                      type: string
                                      readOnly: true
                                    user_id:
                                      type: string
                                      readOnly: true
                                    source_rate_limit_id:
                                      type: string
                                      description: >-
                                        The rate limit being sliced. Must be one
                                        the project holds, at any tier.
                                    rate_limit_id:
                                      type: string
                                      readOnly: true
                                      description: >-
                                        The derived governance rate limit that
                                        enforces the slice.
                                    token_share:
                                      type: integer
                                      description: >-
                                        Authored token share. Requires the
                                        source to cap tokens. A percent share
                                        that comes to no whole tokens is
                                        refused.
                                    token_share_type:
                                      allOf:
                                        - type: string
                                          enum:
                                            - percent
                                            - amount
                                          description: >-
                                            Whether a member's authored share is a
                                            percentage of the source cap or an
                                            absolute figure. Budget shares must
                                            state this explicitly; a rate-limit
                                            share left blank settles to `amount`.
                                      description: >-
                                        Settles to `amount` when a token share
                                        is given without one.
                                    request_share:
                                      type: integer
                                      description: >-
                                        Authored request share. Requires the
                                        source to cap requests. A percent share
                                        that comes to no whole requests is
                                        refused.
                                    request_share_type:
                                      allOf:
                                        - type: string
                                          enum:
                                            - percent
                                            - amount
                                          description: >-
                                            Whether a member's authored share is a
                                            percentage of the source cap or an
                                            absolute figure. Budget shares must
                                            state this explicitly; a rate-limit
                                            share left blank settles to `amount`.
                                      description: >-
                                        Settles to `amount` when a request share
                                        is given without one.
                                    rate_limit:
                                      readOnly: true
                                      allOf:
                                        - type: object
                                          description: >-
                                            A token and request rate limit on a
                                            project, on a provider inside it, or on
                                            a model under that provider. The two
                                            dimensions run independent windows, and
                                            a cap is enforced only together with its
                                            window.
                                          properties:
                                            id:
                                              type: string
                                              description: >-
                                                Omit to create. Restate to update in
                                                place.
                                            token_max_limit:
                                              type: integer
                                              minimum: 0
                                              description: >-
                                                Maximum tokens per window. Requires
                                                `token_reset_duration`. On a project
                                                with `split_policy: equal`, a cap below
                                                the member count is refused, since a
                                                slice is a whole number of tokens.
                                            token_reset_duration:
                                              type: string
                                              example: 1h
                                            request_max_limit:
                                              type: integer
                                              minimum: 0
                                              description: >-
                                                Maximum requests per window. Requires
                                                `request_reset_duration`. Subject to the
                                                same lower bound under `split_policy:
                                                equal`.
                                            request_reset_duration:
                                              type: string
                                              example: 1h
                                            token_current_usage:
                                              type: integer
                                              readOnly: true
                                            token_last_reset:
                                              type: string
                                              format: date-time
                                              readOnly: true
                                            request_current_usage:
                                              type: integer
                                              readOnly: true
                                            request_last_reset:
                                              type: string
                                              format: date-time
                                              readOnly: true
                                            config_hash:
                                              type: string
                                              readOnly: true
                                            created_at:
                                              type: string
                                              format: date-time
                                              readOnly: true
                                            updated_at:
                                              type: string
                                              format: date-time
                                              readOnly: true
                                      description: >-
                                        The derived rate limit row, with its own
                                        counters.
                                    created_at:
                                      type: string
                                      format: date-time
                                      readOnly: true
                                    updated_at:
                                      type: string
                                      format: date-time
                                      readOnly: true
                              user_name:
                                type: string
                                readOnly: true
                              user_email:
                                type: string
                                readOnly: true
                              created_at:
                                type: string
                                format: date-time
                                readOnly: true
                              updated_at:
                                type: string
                                format: date-time
                                readOnly: true
                          description: >-
                            Narrowed to what the caller's data access permits,
                            so two operators can read the same project and see
                            different rosters. Managed through the member
                            routes, never through the project body.
                        created_by_user_id:
                          type: string
                          nullable: true
                          readOnly: true
                          description: >-
                            Taken from the calling identity, never from the
                            body.
                        created_at:
                          type: string
                          format: date-time
                          readOnly: true
                        updated_at:
                          type: string
                          format: date-time
                          readOnly: true
                  pagination:
                    type: object
                    properties:
                      total:
                        type: integer
                        format: int64
                        description: >-
                          Matching projects visible to the caller, before
                          pagination.
                      limit:
                        type: integer
                      offset:
                        type: integer
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BifrostError'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BifrostError'
      security:
        - ManagementBearerAuth: []
components:
  schemas:
    MCPClient:
      type: object
      description: Connected MCP client with its tools
      properties:
        config:
          $ref: '#/components/schemas/MCPClientConfig'
        tools:
          type: array
          items:
            type: object
            description: Tool function definition
            properties:
              name:
                type: string
              description:
                type: string
              parameters:
                type: object
                additionalProperties: true
              strict:
                type: boolean
        state:
          type: string
          enum:
            - healthy
            - unstable
            - error
            - pending_verification
            - needs_reauth
            - disabled
            - degraded
          description: >
            Connection state of an MCP client:

            - healthy: Bifrost's own periodic connection check (ping/list_tools
            for
              sticky clients, list_tools for per-call clients) most recently
              succeeded.
            - unstable: The periodic connection check most recently failed with
            a
              transient-classified error. Purely informational — unlike
              needs_reauth, this never gates execution; tool calls are still
              attempted normally. Self-heals to healthy on the next successful
              check, no human action required.
            - error: A data-consistency fallback used only when a client is
              registered in the config store but missing from the runtime manager
              entirely — a deeper anomaly than anything in the normal
              connect/health-check lifecycle, which never assigns this value itself.
            - pending_verification: Declared (typically via config.json) but the
            one-time
              admin verification has not been completed yet. Complete it via
              POST /api/mcp/client/{id}/initiate-verification (auth_type oauth /
              per_user_oauth) or POST /api/mcp/client/{id}/verify-headers
              (auth_type per_user_headers).
            - needs_reauth: Setup completed at least once, but a credential an
            admin is
              responsible for has permanently died and needs a human to repair it.
              For shared OAuth clients the connection credential itself was
              rejected/expired with no silent recovery; the state is sticky (the health
              monitor will not clobber it) until an admin runs
              POST /api/mcp/client/{id}/reauthorize. For per-user clients this is a
              response-only projection — computed at list-time, never stored in the
              runtime manager — meaning the retained admin discovery credential
              needs repair; end-user credentials and tool calls keep working, only
              periodic tool-list refresh pauses. Overlays onto both healthy and
              unstable runtime readings, never onto disabled or
              pending_verification. Repair via reauthorize (per_user_oauth),
              verify-headers with fresh sample values (per_user_headers), or
              verify-exchange (token_exchange, which re-exchanges the signed-in
              admin's own identity token — no sample values to supply).
            - disabled: Client has been intentionally disabled; no connection or
            workers are active

            - degraded: A read-time cluster aggregate, never a single node's own
              local state — multiple instances of a distributed deployment each
              currently hold a different self-reported state for the same client.
              Only meaningful for states that can genuinely vary per instance
              (healthy, unstable, pending_verification); needs_reauth/disabled are
              config-sourced facts expected to already agree everywhere. Never
              appears in a single-instance deployment.
        last_failure:
          $ref: '#/components/schemas/MCPConnectionFailure'
        node_states:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/MCPInstanceState'
          description: >
            Per-instance breakdown behind `state` in a distributed deployment:

            instance ID -> that instance's own self-reported state and

            last_failure. Present when instances disagree (`state` is then

            `degraded`) and when they all agree on `unstable`, so each
            instance's

            own reason is visible. Never present in a single-instance
            deployment.
        vk_configs:
          type: array
          items:
            type: object
            description: >-
              Per-virtual-key tool access configuration as returned in list/get
              responses
            properties:
              virtual_key_id:
                type: string
                description: ID of the virtual key
              virtual_key_name:
                type: string
                description: Display name of the virtual key
              tools_to_execute:
                type: array
                items:
                  type: string
                description: |
                  Tools this virtual key is allowed to call on this MCP client.
                  ["*"] => all tools allowed
                  ["tool1", "tool2"] => only the specified tools
          description: Virtual key assignments for this MCP client
    BifrostError:
      type: object
      description: Error response from Bifrost
      properties:
        event_id:
          type: string
        type:
          type: string
        is_bifrost_error:
          type: boolean
        status_code:
          type: integer
        error:
          $ref: '#/components/schemas/ErrorField'
        extra_fields:
          $ref: '#/components/schemas/BifrostErrorExtraFields'
    MCPClientConfig:
      type: object
      description: Full MCP client configuration (used in responses)
      properties:
        client_id:
          type: string
          description: Unique identifier for the MCP client
        name:
          type: string
          description: Display name for the MCP client
        is_code_mode_client:
          type: boolean
          description: Whether this client is available in code mode
        connection_type:
          type: string
          enum:
            - http
            - stdio
            - sse
            - inprocess
          description: Connection type for MCP client
        connection_string:
          type: string
          description: HTTP or SSE URL (required for HTTP or SSE connections)
        stdio_config:
          type: object
          description: STDIO configuration for MCP client
          properties:
            command:
              type: string
              description: Executable command to run
            args:
              type: array
              items:
                type: string
              description: Command line arguments
            envs:
              type: array
              items:
                type: string
              description: Environment variables required
        tls_config:
          type: object
          description: TLS configuration for HTTP and SSE connections.
          properties:
            insecure_skip_verify:
              type: boolean
              description: Disable TLS certificate verification. Development/testing only.
            ca_cert_pem:
              type: string
              description: >
                PEM-encoded CA certificate. Supports env.VAR_NAME syntax for
                input.

                Responses return a redacted placeholder rather than the raw PEM
                value.
        auth_type:
          type: string
          enum:
            - none
            - headers
            - oauth
            - per_user_oauth
            - per_user_headers
            - token_exchange
          description: Authentication type for the MCP connection
        oauth_config_id:
          type: string
          description: |
            OAuth config ID for OAuth authentication.
            References the oauth_configs table.
            Only set when auth_type is "oauth".
        headers:
          type: object
          additionalProperties:
            type: string
          description: |
            Custom headers to include in requests.
            Only used when auth_type is "headers".
        tools_to_execute:
          type: array
          items:
            type: string
          description: |
            Include-only list for tools.
            ["*"] => all tools are included
            [] => no tools are included
            ["tool1", "tool2"] => include only the specified tools
        tools_to_auto_execute:
          type: array
          items:
            type: string
          description: |
            List of tools that can be auto-executed without user approval.
            Must be a subset of tools_to_execute.
            ["*"] => all executable tools can be auto-executed
            [] => no tools are auto-executed
            ["tool1", "tool2"] => only specified tools can be auto-executed
        tool_pricing:
          type: object
          additionalProperties:
            type: number
            format: double
          description: |
            Per-tool cost in USD for execution.
            Key is the tool name, value is the cost per execution.
            Example: {"read_file": 0.001, "write_file": 0.002}
        allow_on_all_virtual_keys:
          type: boolean
          default: false
          description: >
            When true, this MCP client's tools are accessible to all virtual
            keys without requiring

            explicit per-key assignment. All tools are allowed by default. If a
            virtual key has an

            explicit MCP config for this client, that config takes precedence
            and overrides this behaviour.
        per_user_header_keys:
          type: array
          items:
            type: string
          description: >
            For `per_user_headers` clients only. The list of header names each
            end-user

            must supply via the inline-401 flow. Header values themselves are
            stored

            per-user in a separate table (surfaced on `/api/mcp/sessions`).
        token_exchange:
          type: object
          required:
            - audience
          properties:
            audience:
              type: string
              minLength: 1
              description: >-
                Resource identifier this server is scoped to at the identity
                provider (e.g. "api://jira-mcp")
            use_idp_credentials:
              type: boolean
              description: >
                When true, performs the exchange as the SSO login application
                itself

                instead of client_id/client_secret below, which are then
                ignored.

                Some providers require this: Microsoft Entra ID's on-behalf-of
                grant

                only accepts an assertion audienced to the exchanging
                application,

                and the SSO login flow always requests a token self-audienced to
                the

                SSO application, so a separate exchange application can never

                receive a usable one.
            client_id:
              type: string
              minLength: 1
              description: >
                The identity-provider application authorized to perform
                exchanges for

                this audience — typically a dedicated registration carrying the

                token-exchange (or on-behalf-of) grant, separate from the SSO
                login

                application. Required unless use_idp_credentials is true.
                Supports

                env.VAR_NAME and vault.path references. Redacted in API
                responses.
            client_secret:
              type: string
              description: >
                Secret for the exchange application; omit for public clients.
                Ignored

                when use_idp_credentials is true. Supports env.VAR_NAME and

                vault.path references. Redacted in API responses.
            scopes:
              type: array
              items:
                type: string
              description: >
                Optional scopes to request on the exchanged token. Include

                "offline_access" (where the identity provider supports it) so
                the

                retained admin discovery credential gets a refresh token and
                stays

                self-renewing.
            authorization_server_url:
              type: string
              description: >
                Overrides the Authorization Server the exchange request is sent
                to.

                Only needed when the audience is registered on a different

                Authorization Server than the one used for SSO login (e.g.
                Okta's

                per-resource Custom Authorization Servers). Leave unset to use
                the

                deployment's SSO login issuer, which is correct for providers
                with a

                single tenant-wide token endpoint (Entra, Auth0).
          allOf:
            - if:
                not:
                  properties:
                    use_idp_credentials:
                      const: true
                  required:
                    - use_idp_credentials
              then:
                required:
                  - client_id
                description: >
                  client_id is required unless use_idp_credentials is true, in
                  which

                  case the exchange uses the SSO login application's own
                  credentials

                  instead.
          additionalProperties: false
          description: >
            For `token_exchange` clients only. `client_id` and `client_secret`
            are

            redacted in this response.
        disabled:
          type: boolean
          default: false
          description: >
            Whether the client is intentionally disabled.

            When true, the client has no active connection or workers and its
            tools are not available for inference.
    MCPConnectionFailure:
      type: object
      description: |
        The latest failure recorded by the instance serving the request for its
        own connection handling of this client: which step failed, the error it
        failed with, when that last happened, and when the current run of
        failures began. Present only after that instance has attempted a connect
        or check that failed. Absent while `healthy`, cleared the moment a check
        passes, and absent when a state changed without such an attempt, for
        example `needs_reauth` projected from a credential row that died before
        the next scheduled check ran. Describes only Bifrost's own connection
        checks and connect attempts, never the outcome of real tool calls made
        through the client.
      required:
        - stage
        - message
        - at
        - since
      properties:
        stage:
          type: string
          enum:
            - connect
            - ping
            - list_tools
            - tool_discovery
            - transport_lost
            - credential
          description: >
            The step that failed:

            - connect: establishing the shared connection (dial, initialize,
              connect gate, or the initial list_tools a new connection must pass)
            - ping: the periodic check's ping over an existing sticky connection

            - list_tools: the periodic check's list_tools over an existing
            sticky
              connection
            - tool_discovery: the periodic check's ephemeral
            connect-discover-close
              cycle for per-call auth types
            - transport_lost: a live SSE connection dropped outside any check

            - credential: a credential the connection depends on was rejected
              upstream or rotated by an admin
        message:
          type: string
          description: >-
            The error the step failed with, whitespace-collapsed and capped at
            512 characters.
        at:
          type: string
          format: date-time
          description: |
            The most recent failed attempt. While a client is unstable the check
            retries every 10 seconds, so this keeps moving for as long as the
            outage lasts.
        since:
          type: string
          format: date-time
          description: The first failed attempt of the current unhealthy run.
    MCPInstanceState:
      type: object
      description: One instance's own view of an MCP client in a distributed deployment.
      required:
        - state
      properties:
        state:
          type: string
          enum:
            - healthy
            - unstable
            - error
            - pending_verification
            - needs_reauth
            - disabled
          description: >
            That instance's own self-reported connection state. Never
            `degraded`,

            which only ever exists as the aggregate above this map.
        last_failure:
          $ref: '#/components/schemas/MCPConnectionFailure'
    ErrorField:
      type: object
      properties:
        type:
          type: string
        code:
          type: string
        message:
          type: string
        param:
          type: string
        event_id:
          type: string
    BifrostErrorExtraFields:
      type: object
      properties:
        provider:
          $ref: '#/components/schemas/ModelProvider'
        model_requested:
          type: string
        request_type:
          type: string
    ModelProvider:
      type: string
      description: AI model provider identifier
      enum:
        - anthropic
        - azure
        - bedrock
        - bedrock_mantle
        - cerebras
        - cohere
        - deepseek
        - gemini
        - groq
        - mistral
        - ollama
        - opencode-go
        - opencode-zen
        - openai
        - parasail
        - perplexity
        - sgl
        - vertex
        - openrouter
        - elevenlabs
        - huggingface
        - nebius
        - xai
        - replicate
        - vllm
        - runway
        - runware
        - fireworks
        - sarvam
        - wafer
        - databricks
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >
        Bearer token authentication. Use your provider API key or Bifrost
        authentication token.

        Virtual keys (prefixed with `sk-bf-`) can also be passed here.
    BasicAuth:
      type: http
      scheme: basic
      description: |
        Basic authentication using username and password.
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: |
        API key authentication via the `x-api-key` header.
        Virtual keys (prefixed with `sk-bf-`) can also be passed here.
    ManagementBearerAuth:
      type: http
      scheme: bearer
      description: >
        Management API authentication for `/api/*` endpoints. Use the
        `Authorization` header with `Bearer <API key>`.

        Virtual keys, dashboard/user/session tokens, and `x-api-key` headers are
        not supported on management APIs.

````