openapi: 3.1.0
info:
  title: Plurence Data API
  version: 1.0.0
  description: ''
  x-generated-at: '2026-04-20T02:18:57.797Z'
servers:
  - url: https://data.plurence.com
tags:
  - name: Account
    description: >-
      An Account is the unit of access, isolation, and billing. Accounts form a tree — a root account (parent_id
      omitted) represents a person or organization and is the billing anchor. Child accounts represent any isolation
      boundary the owner needs: environment (production/staging), region (us-east/eu-west), team, or any custom split.

      Any account at any depth can own Apps. Quota flows downward — a child account's quota is a slice of its parent's
      ceiling. Role assignments granted at a parent are inherited by all descendants.
  - name: Audit
    description: >-
      One audit event per gateway request, written after the response is sent to the client. Covers all request outcomes
      including auth failures, policy denials, quota blocks, and upstream errors — unlike usage events which are emitted
      only on 2xx responses.

      For realtime (WebSocket) sessions one audit event is written per client interaction (session.created,
      session.updated, conversation.item.created, response.done) rather than per HTTP request.

      Three retention tiers are controlled by account.policy.audit_retention:
        zero_retention  — nothing written
        metadata        — all fields except client_request / upstream_request / upstream_response
        full            — complete record including raw request and response bodies for replay
  - name: Credential
    description: |-
      A credential record maps one authentication method to a principal. Covers all authentication types:
        oidc     — OpenID Connect (Google, GitHub, Apple, internal, any OIDC provider)
        saml     — Enterprise SSO (Okta, Azure AD, custom)
        password — email + scrypt/argon2id
        apikey   — server-generated key
        hmac     — HMAC signing key
  - name: Inquiry
    description: >-
      A customer-submitted inquiry. Covers access requests, abuse reports, and general contact. The `type` field
      distinguishes the intent; all other fields are shared.
  - name: Invitation
    description: >-
      An invite code issued to grant access to the platform. Used to gate sign-up during beta and early access periods.
      The `code` field is the redeemable token sent to the recipient; `status` tracks its lifecycle.
  - name: Principal
    description: >-
      A human user or machine service account that can authenticate and be granted roles. Credentials (API keys, HMAC
      secrets, passwords) live on Credential records. Federated login identities (Google, GitHub, etc.) live on
      FederatedIdentity records.
  - name: Project
    description: >-
      A Project is a named workspace within an Account. Resources such as API keys, models, and usage budgets are scoped
      to a project.
  - name: Signin
    description: >-
      A signin event record. Created on each successful authentication or token refresh. Serves as an immutable audit
      trail — one record per credential exchange, regardless of grant type. Query by principal_id or grant_type to
      reconstruct a principal's login history.
  - name: Signup
    description: >-
      A signup event record. Created when a new user completes registration. Serves as the audit anchor for the
      principal/federated_identity/account/project creation chain.
  - name: Usage
    description: >-
      One append-only usage event for billing, quota reconciliation, and analytics. Omit fields the gateway or provider
      cannot populate; prefer null only when "known absent" vs unknown.
paths:
  /v1/accounts:
    get:
      operationId: list_account
      summary: List accounts
      tags:
        - Account
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          description: Number of records to skip before returning.
          schema:
            type: integer
            default: 0
        - name: order_asc
          in: query
          description: Field name to sort by ascending.
          schema:
            type: string
        - name: order_desc
          in: query
          description: Field name to sort by descending.
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Account'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    post:
      operationId: create_account
      summary: Create account
      tags:
        - Account
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/Account'
                - type: array
                  items:
                    $ref: '#/components/schemas/Account'
                  minItems: 1
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Account'
                  - type: array
                    items:
                      $ref: '#/components/schemas/Account'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error409'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/accounts/{id}:
    get:
      operationId: get_account
      summary: Get account by id
      tags:
        - Account
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    patch:
      operationId: update_account
      summary: Update account
      tags:
        - Account
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Account'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    delete:
      operationId: delete_account
      summary: Delete account
      tags:
        - Account
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '204':
          description: Deleted
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/audit:
    get:
      operationId: list_audit
      summary: List audit
      tags:
        - Audit
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          description: Number of records to skip before returning.
          schema:
            type: integer
            default: 0
        - name: order_asc
          in: query
          description: Field name to sort by ascending.
          schema:
            type: string
        - name: order_desc
          in: query
          description: Field name to sort by descending.
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Audit'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/audit/{id}:
    get:
      operationId: get_audit
      summary: Get audit by id
      tags:
        - Audit
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Audit'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/credentials:
    get:
      operationId: list_credential
      summary: List credentials
      tags:
        - Credential
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          description: Number of records to skip before returning.
          schema:
            type: integer
            default: 0
        - name: order_asc
          in: query
          description: Field name to sort by ascending.
          schema:
            type: string
        - name: order_desc
          in: query
          description: Field name to sort by descending.
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Credential'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    post:
      operationId: create_credential
      summary: Create credential
      tags:
        - Credential
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Credential'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Credential'
                  - type: array
                    items:
                      $ref: '#/components/schemas/Credential'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error409'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/credentials/{id}:
    get:
      operationId: get_credential
      summary: Get credential by id
      tags:
        - Credential
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Credential'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    patch:
      operationId: update_credential
      summary: Update credential
      tags:
        - Credential
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Credential'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Credential'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    delete:
      operationId: delete_credential
      summary: Delete credential
      tags:
        - Credential
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '204':
          description: Deleted
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/inquiries:
    post:
      operationId: create_inquiry
      summary: Create inquiry
      tags:
        - Inquiry
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/Inquiry'
                - type: array
                  items:
                    $ref: '#/components/schemas/Inquiry'
                  minItems: 1
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Inquiry'
                  - type: array
                    items:
                      $ref: '#/components/schemas/Inquiry'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error409'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/models:
    get:
      operationId: list_model
      summary: List models
      tags:
        - Model
      security: []
      parameters:
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          description: Number of records to skip before returning.
          schema:
            type: integer
            default: 0
        - name: order_asc
          in: query
          description: Field name to sort by ascending.
          schema:
            type: string
        - name: order_desc
          in: query
          description: Field name to sort by descending.
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Model'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/models/{id}:
    get:
      operationId: get_model
      summary: Get model by id
      tags:
        - Model
      security: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Model'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/principals:
    get:
      operationId: list_principal
      summary: List principals
      tags:
        - Principal
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          description: Number of records to skip before returning.
          schema:
            type: integer
            default: 0
        - name: order_asc
          in: query
          description: Field name to sort by ascending.
          schema:
            type: string
        - name: order_desc
          in: query
          description: Field name to sort by descending.
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Principal'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/principals/{id}:
    get:
      operationId: get_principal
      summary: Get principal by id
      tags:
        - Principal
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Principal'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    patch:
      operationId: update_principal
      summary: Update principal
      tags:
        - Principal
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Principal'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Principal'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/projects:
    get:
      operationId: list_project
      summary: List projects
      tags:
        - Project
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          description: Number of records to skip before returning.
          schema:
            type: integer
            default: 0
        - name: order_asc
          in: query
          description: Field name to sort by ascending.
          schema:
            type: string
        - name: order_desc
          in: query
          description: Field name to sort by descending.
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Project'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    post:
      operationId: create_project
      summary: Create project
      tags:
        - Project
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/Project'
                - type: array
                  items:
                    $ref: '#/components/schemas/Project'
                  minItems: 1
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Project'
                  - type: array
                    items:
                      $ref: '#/components/schemas/Project'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error409'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/projects/{id}:
    get:
      operationId: get_project
      summary: Get project by id
      tags:
        - Project
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    patch:
      operationId: update_project
      summary: Update project
      tags:
        - Project
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Project'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    delete:
      operationId: delete_project
      summary: Delete project
      tags:
        - Project
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '204':
          description: Deleted
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/providers:
    get:
      operationId: list_provider
      summary: List providers
      tags:
        - Provider
      security: []
      parameters:
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          description: Number of records to skip before returning.
          schema:
            type: integer
            default: 0
        - name: order_asc
          in: query
          description: Field name to sort by ascending.
          schema:
            type: string
        - name: order_desc
          in: query
          description: Field name to sort by descending.
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Provider'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/providers/{id}:
    get:
      operationId: get_provider
      summary: Get provider by id
      tags:
        - Provider
      security: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Provider'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/signins:
    post:
      operationId: create_signin
      summary: Create signin
      tags:
        - Signin
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Signin'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error409'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/signups:
    post:
      operationId: create_signup
      summary: Create signup
      tags:
        - Signup
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Signup'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignupResponse'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error409'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/usage:
    get:
      operationId: list_usage
      summary: List usage
      tags:
        - Usage
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          description: Number of records to skip before returning.
          schema:
            type: integer
            default: 0
        - name: order_asc
          in: query
          description: Field name to sort by ascending.
          schema:
            type: string
        - name: order_desc
          in: query
          description: Field name to sort by descending.
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Usage'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/usage/{id}:
    get:
      operationId: get_usage
      summary: Get usage by id
      tags:
        - Usage
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Usage'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /v1/projects/{id}/api-keys:
    get:
      operationId: list_credential_by_project
      summary: List credentials for project
      tags:
        - Project
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: offset
          in: query
          description: Number of records to skip before returning.
          schema:
            type: integer
            default: 0
        - name: order_asc
          in: query
          description: Field name to sort by ascending.
          schema:
            type: string
        - name: order_desc
          in: query
          description: Field name to sort by descending.
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Credential'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
    post:
      operationId: create_credential_for_project
      summary: Create credential for project
      tags:
        - Project
      security:
        - ApiKey: []
        - Hmac: []
        - Passthrough: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Credential'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Credential'
                  - type: array
                    items:
                      $ref: '#/components/schemas/Credential'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error409'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
components:
  schemas:
    Error:
      type: object
      required:
        - error_id
        - status_code
        - message_code
        - message
      properties:
        error_id:
          type: string
          pattern: ^[A-Z]{3}[0-9]{6}$
          examples:
            - DAT030002
          description: 'Stable error code in the form SERVICE+CLASS+SEQ (e.g. DAT030002). CLASS: 00=system, 02=auth, 03=data.'
        status_code:
          type: integer
          enum:
            - 400
            - 401
            - 403
            - 404
            - 405
            - 409
            - 500
          description: HTTP status code.
        message_code:
          type: string
          enum:
            - INTERNAL
            - UNAUTHORIZED
            - FORBIDDEN
            - VALIDATION_FAILED
            - NOT_FOUND
            - METHOD_NOT_ALLOWED
            - ENTITY_REQUIRED
            - BAD_REQUEST
            - ROUTE_NOT_FOUND
            - CONFLICT
          description: Machine-readable error code.
        message:
          type: string
          description: Human-readable description of the error.
        request_id:
          type: string
          format: uuid
          description: Request identifier for correlating errors with server logs.
        context:
          type: string
          description: Flow step where the error occurred.
        data_context:
          type: string
          description: Entity or resource name the error relates to.
        details:
          type: array
          description: Per-field validation messages. Present on VALIDATION_FAILED errors.
          items:
            type: object
            required:
              - message
            properties:
              field:
                type:
                  - string
                  - 'null'
                description: Dot-notation field path (e.g. "attributes.key_hash"), null for root-level errors.
              message:
                type: string
                description: Validation failure description.
    Error400:
      description: Record … did not pass validation
      examples:
        - error_id: DAT030001
          status_code: 400
          message_code: VALIDATION_FAILED
          message: Record … did not pass validation
          request_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
      allOf:
        - $ref: '#/components/schemas/Error'
        - properties:
            status_code:
              const: 400
            message_code:
              enum:
                - VALIDATION_FAILED
                - ENTITY_REQUIRED
                - BAD_REQUEST
    Error401:
      description: Authentication required
      examples:
        - error_id: DAT020001
          status_code: 401
          message_code: UNAUTHORIZED
          message: Authentication required
          request_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
      allOf:
        - $ref: '#/components/schemas/Error'
        - properties:
            status_code:
              const: 401
            message_code:
              enum:
                - UNAUTHORIZED
    Error403:
      description: Access to … denied
      examples:
        - error_id: DAT020002
          status_code: 403
          message_code: FORBIDDEN
          message: Access to … denied
          request_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
      allOf:
        - $ref: '#/components/schemas/Error'
        - properties:
            status_code:
              const: 403
            message_code:
              enum:
                - FORBIDDEN
    Error404:
      description: … not found
      examples:
        - error_id: DAT030002
          status_code: 404
          message_code: NOT_FOUND
          message: … not found
          request_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
      allOf:
        - $ref: '#/components/schemas/Error'
        - properties:
            status_code:
              const: 404
            message_code:
              enum:
                - NOT_FOUND
                - ROUTE_NOT_FOUND
    Error405:
      description: Method … not allowed
      examples:
        - error_id: DAT030003
          status_code: 405
          message_code: METHOD_NOT_ALLOWED
          message: Method … not allowed
          request_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
      allOf:
        - $ref: '#/components/schemas/Error'
        - properties:
            status_code:
              const: 405
            message_code:
              enum:
                - METHOD_NOT_ALLOWED
    Error409:
      description: … with id … already exists
      examples:
        - error_id: DAT030007
          status_code: 409
          message_code: CONFLICT
          message: … with id … already exists
          request_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
      allOf:
        - $ref: '#/components/schemas/Error'
        - properties:
            status_code:
              const: 409
            message_code:
              enum:
                - CONFLICT
    Error500:
      description: Internal server error
      examples:
        - error_id: DAT000001
          status_code: 500
          message_code: INTERNAL
          message: Internal server error
          request_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
      allOf:
        - $ref: '#/components/schemas/Error'
        - properties:
            status_code:
              const: 500
            message_code:
              enum:
                - INTERNAL
    TokenResponse:
      type: object
      required:
        - access_token
        - token_type
        - expires_in
      properties:
        access_token:
          type: string
          description: Signed JWT
        token_type:
          type: string
          enum:
            - bearer
        expires_in:
          type: integer
          description: Token lifetime in seconds
        user:
          $ref: '#/components/schemas/Principal'
          description: Authenticated user
        account:
          $ref: '#/components/schemas/Account'
          description: User's personal root account
    SignupResponse:
      type: object
      required:
        - access_token
        - token_type
        - expires_in
        - user
        - account
        - project
      properties:
        access_token:
          type: string
          description: Signed JWT for the newly created user
        token_type:
          type: string
          enum:
            - bearer
        expires_in:
          type: integer
          description: Token lifetime in seconds
        user:
          $ref: '#/components/schemas/Principal'
          description: Newly created user
        account:
          $ref: '#/components/schemas/Account'
          description: User's personal root account
        project:
          $ref: '#/components/schemas/Project'
          description: Default project created for the account
    PrefixedId:
      type: string
      pattern: ^[a-z][a-z0-9_]*_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
      description: 'Entity ID in the form prefix_uuidv4. Example: user_550e8400-e29b-41d4-a716-446655440000.'
    Quota:
      type: object
      additionalProperties: false
      description: >
        Resource limits for this account. Child accounts cannot exceed their parent's ceiling. Omitted fields inherit
        from the parent account or fall back to platform defaults.
      properties:
        requests_per_minute:
          type: integer
          minimum: 1
          description: Maximum requests per minute across all apps in this account.
        requests_per_day:
          type: integer
          minimum: 1
          description: Maximum requests per day across all apps in this account.
        tokens_per_minute:
          type: integer
          minimum: 1
          description: Maximum tokens per minute across all apps in this account.
        tokens_per_day:
          type: integer
          minimum: 1
          description: Maximum tokens per day across all apps in this account.
        max_apps:
          type: integer
          minimum: 1
          description: Maximum number of Apps this account can create.
        max_child_accounts:
          type: integer
          minimum: 1
          description: Maximum number of direct child accounts.
        max_members:
          type: integer
          minimum: 1
          description: Maximum number of members (users + service accounts).
    ProviderId:
      type: string
      enum:
        - openai
        - vertexai
        - bedrock
        - ollama
        - fireworks
      description: Canonical provider identifier. Add here when onboarding a new provider.
    ApiType:
      type: string
      enum:
        - chat_completions
        - responses
        - embeddings
        - image
        - audio_speech
        - transcribe
        - realtime
        - batch
        - generate_content
        - stream_generate_content
        - raw_predict
        - stream_raw_predict
        - invoke
        - invoke_stream
        - converse
        - messages
    ProcessingType:
      type: string
      enum:
        - request
        - stream
        - realtime
        - batch
        - async
      description: >
        How the request was processed. request   — standard synchronous HTTP request. stream    — streaming HTTP
        response (SSE or chunked). realtime  — bidirectional WebSocket session. batch     — offline batch job. async    
        — fire-and-poll async inference.
    Contact:
      type: object
      additionalProperties: false
      required:
        - name
        - email
      properties:
        name:
          type: string
          minLength: 1
          description: Full name of the person submitting the inquiry.
        email:
          type: string
          format: email
          description: Work or contact email address.
        company:
          type: string
          minLength: 1
          description: Company or organization name.
    SnapshotStatus:
      type: string
      enum:
        - stable
        - preview
        - latest
        - experimental
        - deprecated
    ModelStatus:
      type: string
      enum:
        - active
        - preview
        - deprecated
        - disabled
    ServiceTier:
      type: string
      enum:
        - default
        - standard
        - priority
        - flex
        - reserved
        - scale
        - auto
        - on_demand
        - fixed_quota
        - provisioned_throughput
    ReasoningEffort:
      type: string
      enum:
        - none
        - low
        - medium
        - high
        - xhigh
    ToolType:
      type: string
      enum:
        - web_search
        - file_search
        - image_generation
        - code_interpreter
        - hosted_shell
        - apply_patch
        - skills
        - computer_use
        - mcp
        - tool_search
    Modality:
      type: string
      enum:
        - text
        - image
        - video
        - audio
        - pdf
        - document
        - multimodal
    ModelFeature:
      type: string
      enum:
        - streaming_sse
        - streaming_ws
        - tools
        - vision
        - reasoning
        - coding
        - structured_output
        - json_mode
        - system_prompt
        - long_context
        - caching
        - audio
        - audio_input
        - audio_output
        - voice_synthesis
        - voice_cloning
        - emotion_control
        - transcription
        - diarization
        - speaker_identification
        - speaker_tracking
        - image_input
        - image_output
        - text_to_image
        - style_transfer
        - high_resolution
        - ultra_high_resolution
        - embedding
        - semantic_search
        - classification
        - clustering
        - similarity
        - cross_language
        - multilingual
        - instruction_following
        - code_execution
        - computer_use
        - file_search
        - search_grounding
        - url_context
        - open_source
        - guardrails
        - abuse_detection
        - count_tokens
        - prompt_management
        - prompt_optimization
        - knowledge_base
        - agents
        - flows
        - model_evaluation
        - intelligent_prompt_routing
        - distillation
        - fine_tune
        - batch
        - async
        - service_tier
    ProviderStatus:
      type: string
      enum:
        - active
        - preview
        - deprecated
        - disabled
    Account:
      title: Account
      description: >
        An Account is the unit of access, isolation, and billing. Accounts form a tree — a root account (parent_id
        omitted) represents a person or organization and is the billing anchor. Child accounts represent any isolation
        boundary the owner needs: environment (production/staging), region (us-east/eu-west), team, or any custom split.

        Any account at any depth can own Apps. Quota flows downward — a child account's quota is a slice of its parent's
        ceiling. Role assignments granted at a parent are inherited by all descendants.
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - slug
        - type
        - status
        - owner_id
      properties:
        id:
          $ref: '#/components/schemas/PrefixedId'
          description: Unique account identifier.
        parent_id:
          $ref: '#/components/schemas/PrefixedId'
          description: >
            Parent account ID. Omit for root accounts (billing anchors). A root account with type "personal" is
            auto-created on user signup.
        name:
          type: string
          minLength: 1
          maxLength: 100
          description: Human-readable account name (e.g. "Acme Corp", "Production").
        slug:
          type: string
          pattern: ^[a-z0-9][a-z0-9-]{1,48}[a-z0-9]$
          description: >
            URL-safe identifier, unique within the parent account (or globally for root accounts). Used in API paths and
            UI URLs.
        type:
          type: string
          enum:
            - personal
            - organization
          description: >
            Meaningful on root accounts only. personal      — auto-created for individual users on signup. organization 
            — created by a user representing a company or team.
        status:
          type: string
          enum:
            - active
            - suspended
            - disabled
          description: >
            active     — fully operational. suspended  — access blocked, data retained (e.g. payment failure).
            disabled   — permanently deactivated.
        owner_id:
          $ref: '#/components/schemas/PrefixedId'
          description: User ID of the account creator. Always a human user, never a service account.
        quota:
          $ref: '#/components/schemas/Quota'
        meta:
          type: object
          additionalProperties: false
          description: Optional metadata for display and billing purposes.
          properties:
            billing_email:
              type: string
              format: email
              description: |
                Billing contact email. Relevant on root accounts only. Defaults to the owner's primary email if omitted.
            website:
              type: string
              format: uri
            description:
              type: string
              maxLength: 500
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
    Audit:
      title: Audit
      description: >
        One audit event per gateway request, written after the response is sent to the client. Covers all request
        outcomes including auth failures, policy denials, quota blocks, and upstream errors — unlike usage events which
        are emitted only on 2xx responses.

        For realtime (WebSocket) sessions one audit event is written per client interaction (session.created,
        session.updated, conversation.item.created, response.done) rather than per HTTP request.

        Three retention tiers are controlled by account.policy.audit_retention:
          zero_retention  — nothing written
          metadata        — all fields except client_request / upstream_request / upstream_response
          full            — complete record including raw request and response bodies for replay
      type: object
      additionalProperties: false
      required:
        - event_id
        - request_id
        - account_id
        - auth_method
        - provider
        - api_type
        - processing_type
        - request_url
        - retention
      properties:
        id:
          type: string
          description: Server-generated record id.
        event_id:
          $ref: '#/components/schemas/PrefixedId'
          description: Unique id for this audit event.
        usage_id:
          oneOf:
            - $ref: '#/components/schemas/PrefixedId'
            - type: 'null'
          description: >
            References the usage event for the same request (usage.event_id). Null when no usage event was emitted (e.g.
            non-2xx response, non-response.done turn).
        session_id:
          type:
            - string
            - 'null'
          description: |
            Realtime session id (e.g. sess_*). Set for processing_type=realtime; null otherwise.
        turn_index:
          type: integer
          minimum: 0
          description: >
            Sequential interaction counter within a realtime session. Increments on every audit-emitting event
            (session.created, session.updated, conversation.item.created, response.done). Null for non-realtime
            requests.
        turn_type:
          type: string
          enum:
            - session.created
            - session.updated
            - conversation.item.created
            - response.done
          description: |
            What triggered this audit record. Set for realtime sessions only.
        timestamp:
          type: integer
          description: When the audit event was finalized (after egress completes).
        request_id:
          type: string
          description: Gateway-assigned request id. Correlates with usage and metrics.
        retention:
          type: string
          enum:
            - full
            - metadata
          description: >
            Retention tier that was active when this record was written. zero_retention records are never written, so
            this field is always present.
        account_id:
          type: string
          description: Resolved account id from auth.
        auth_method:
          type: string
          enum:
            - apikey
            - jwt
            - oauth2_client
            - mtls
            - hmac
          description: Authentication method used.
        scopes:
          type: array
          items:
            type: string
          description: Auth scopes granted to this request.
        provider:
          $ref: '#/components/schemas/ProviderId'
          description: Resolved upstream provider id. Null when request was denied before routing.
        model:
          type: string
          description: >
            Resolved model id (same fallback chain as usage: response body → URL → request body). Null when request was
            denied before upstream.
        api_type:
          $ref: '#/components/schemas/ApiType'
          description: Resolved api_type. Null when request was denied before routing.
        processing_type:
          $ref: '#/components/schemas/ProcessingType'
        region:
          type: string
          description: Provider routing region when known.
        request_url:
          type: string
          description: URL as received by the gateway from the client.
        upstream_url:
          type: string
          description: |
            URL the gateway forwarded the request to. Null when request was denied before upstream.
        status_code:
          type:
            - integer
            - 'null'
          minimum: 100
          maximum: 599
          description: >
            HTTP status code of the upstream response, or gateway-generated status for denied/errored requests (e.g.
            401, 403, 429, 502). Null for realtime session interaction turns (status applies to the WS upgrade only).
        error:
          type:
            - string
            - 'null'
          description: |
            Human-readable error message when upstream returned a non-2xx response. Null on success.
        latency_ms:
          type:
            - number
            - 'null'
          minimum: 0
          description: >
            End-to-end gateway latency in milliseconds, measured from first byte received to last byte sent to the
            client. Null for individual realtime interaction turns (latency is per-turn in usage).
        first_token_ms:
          type:
            - number
            - 'null'
          minimum: 0
          description: Time to first token for streaming responses.
        client_request:
          type: object
          additionalProperties: false
          description: >
            Exact request received from the client. Present only when retention=full. Auth headers are stripped; all
            other headers are preserved. For realtime sessions, body_raw is an array of raw JSON frame strings sent by
            the client for this interaction.
          properties:
            method:
              type: string
            url:
              type: string
              description: Full path including query string as received from client.
            headers:
              type: object
              additionalProperties:
                type: string
              description: >
                Sanitized client request headers. x-api-key and authorization are stripped. Array-valued headers joined
                with ", ".
            body_raw:
              type:
                - string
                - array
                - 'null'
              items:
                type: string
              description: >
                Request body. UTF-8 text for JSON/text payloads; base64 for binary. Null for WebSocket upgrades with no
                client messages. For realtime sessions, an array of raw JSON frame strings sent by the client.
            body_encoding:
              type:
                - string
                - 'null'
              enum:
                - utf8
                - base64
                - null
        upstream_request:
          type: object
          additionalProperties: false
          description: >
            Request forwarded to the provider after policy transforms. Present only when retention=full and the request
            reached upstream. Differs from client_request when policy has injected or modified fields (e.g.
            stream_options, system prompt).
          properties:
            method:
              type: string
            url:
              type: string
              description: Full upstream URL including path and query string.
            headers:
              type: object
              additionalProperties:
                type: string
              description: >
                Sanitized upstream request headers. Provider API key is stripped and replaced with
                "provider:<provider_id>" as a placeholder.
            body_raw:
              type:
                - string
                - array
                - 'null'
              items:
                type: string
              description: >
                Request body after transforms. UTF-8 text or base64. For realtime sessions, an array of raw JSON frame
                strings forwarded to upstream.
            body_encoding:
              type:
                - string
                - 'null'
              enum:
                - utf8
                - base64
                - null
        upstream_response:
          type: object
          additionalProperties: false
          description: >
            Full response received from the provider. Present only when retention=full and the request reached upstream.
            For streaming responses, body_raw is the complete accumulated byte sequence (all SSE frames or EventStream
            frames concatenated in order). For non-streaming JSON responses the gateway accumulates chunks and body_raw
            may be an array of raw chunk strings.
          properties:
            status_code:
              type:
                - integer
                - 'null'
              minimum: 100
              maximum: 599
            headers:
              type: object
              additionalProperties:
                type: string
              description: >
                Upstream response headers. Filtered with the same filter list as usage (content-type, content-length,
                transfer-encoding, rate-limit headers, etc.).
            body_raw:
              type:
                - string
                - array
                - 'null'
              items:
                type: string
              description: >
                Complete response body. UTF-8 text for JSON and SSE; base64 for binary (audio, image, EventStream). May
                be a string or an array of chunk strings when the response was buffered chunk-by-chunk. For realtime
                sessions, an array of server→client JSON event strings (text frames) followed by base64-encoded audio
                frames when audio was exchanged.
            body_encoding:
              type:
                - string
                - 'null'
              enum:
                - utf8
                - base64
                - null
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
    Credential:
      title: Credential
      description: |
        A credential record maps one authentication method to a principal. Covers all authentication types:
          oidc     — OpenID Connect (Google, GitHub, Apple, internal, any OIDC provider)
          saml     — Enterprise SSO (Okta, Azure AD, custom)
          password — email + scrypt/argon2id
          apikey   — server-generated key
          hmac     — HMAC signing key
      type: object
      additionalProperties: false
      required:
        - id
        - principal_id
        - account_id
        - type
        - status
      properties:
        id:
          $ref: '#/components/schemas/PrefixedId'
        principal_id:
          $ref: '#/components/schemas/PrefixedId'
          description: Principal this credential authenticates.
        account_id:
          $ref: '#/components/schemas/PrefixedId'
          description: Account this credential belongs to.
        project_id:
          $ref: '#/components/schemas/PrefixedId'
          description: Project this credential is scoped to. Optional for apikey.
        scopes:
          type: array
          items:
            type: string
          description: Granted scopes embedded in the issued token. Present only for session credentials.
        type:
          type: string
          enum:
            - oidc
            - saml
            - password
            - apikey
            - hmac
            - session
        provider:
          type: string
          description: |
            Provider name for oidc and saml types. Examples: google, github, apple, internal, okta, azure.
        external_id:
          type: string
          minLength: 1
          description: |
            Provider-assigned stable identifier. oidc — sub claim. saml — NameID.
        email:
          type: string
          format: email
          description: Email address as reported by the provider (oidc/saml).
        verified:
          type: boolean
          description: Whether the provider has verified ownership of this email (oidc/saml).
        status:
          type: string
          enum:
            - active
            - disabled
            - deprecated
        name:
          type: string
          description: Human-readable label for this credential.
        expires_at:
          type: integer
          description: Expiry as Unix ms. Omit for non-expiring credentials.
        issued_by:
          type: string
        description:
          type: string
        attributes:
          type: object
          description: >
            Key material for password, apikey, and hmac types. Not present on oidc and saml credentials — verification
            is external.
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
      allOf:
        - if:
            properties:
              type:
                enum:
                  - oidc
                  - saml
            required:
              - type
          then:
            required:
              - provider
              - external_id
        - if:
            properties:
              type:
                const: password
            required:
              - type
          then:
            required:
              - attributes
            properties:
              attributes:
                additionalProperties: false
                required:
                  - email
                  - secret_hash
                properties:
                  email:
                    type: string
                    format: email
                    description: Email address. Used as the lookup key.
                  secret_hash:
                    type: string
                    pattern: ^(scrypt|argon2id):.+$
                    description: Hashed password. Preferred — argon2id.
        - if:
            properties:
              type:
                const: apikey
            required:
              - type
          then:
            required:
              - attributes
            properties:
              attributes:
                additionalProperties: false
                required:
                  - key_hash
                properties:
                  key_hash:
                    type: string
                    pattern: ^(sha256|hmac-sha256|argon2id):.+$
                    description: Hashed API key.
        - if:
            properties:
              type:
                const: hmac
            required:
              - type
          then:
            required:
              - attributes
            properties:
              attributes:
                additionalProperties: false
                required:
                  - key_id
                  - secret
                properties:
                  key_id:
                    type: string
                    description: Key identifier sent alongside the signature. Used as the lookup key.
                  secret:
                    type: string
                    minLength: 44
                    description: Raw HMAC signing key (base64url encoded).
                  algorithm:
                    type: string
                    enum:
                      - hmac-sha256
                      - hmac-sha512
                    default: hmac-sha256
        - if:
            properties:
              type:
                const: session
            required:
              - type
          then:
            required:
              - project_id
              - scopes
              - expires_at
    Inquiry:
      title: Inquiry
      description: >
        A customer-submitted inquiry. Covers access requests, abuse reports, and general contact. The `type` field
        distinguishes the intent; all other fields are shared.
      type: object
      additionalProperties: false
      required:
        - id
        - type
        - status
        - contact
        - message
      properties:
        id:
          type: string
          description: Unique inquiry identifier (UUID recommended).
        type:
          type: string
          enum:
            - access_request
            - abuse_report
            - general
          description: >
            access_request — customer requesting API access or a trial. abuse_report   — reporting misuse, policy
            violation, or harmful content. general        — any other question or feedback.
        status:
          type: string
          enum:
            - pending
            - in_review
            - resolved
            - closed
          description: Lifecycle state. Set by the handling team; callers submit as pending.
        contact:
          $ref: '#/components/schemas/Contact'
        subject:
          type: string
          minLength: 1
          maxLength: 200
          description: Optional short title. Auto-generated from type if omitted.
        message:
          type: string
          minLength: 1
          description: >
            Main body of the inquiry. For access_request: describe your use case and expected usage. For abuse_report:
            describe what you observed and why it violates policy.
        ref:
          type: string
          description: >
            Optional reference to the resource involved. For abuse_report: URL, model ID, or request ID being reported.
            For access_request: referral code or invitation link.
        resolved_at:
          type: integer
          description: When the inquiry was resolved or closed.
        notes:
          type: string
          description: Internal notes added by the handling team. Not visible to the submitter.
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
    Invitation:
      title: Invitation
      description: >
        An invite code issued to grant access to the platform. Used to gate sign-up during beta and early access
        periods. The `code` field is the redeemable token sent to the recipient; `status` tracks its lifecycle.
      type: object
      additionalProperties: false
      required:
        - id
        - voucher
        - type
        - status
        - email
      properties:
        id:
          $ref: '#/components/schemas/PrefixedId'
          description: 'Unique invitation identifier (prefix: inv).'
        voucher:
          type: string
          minLength: 6
          maxLength: 64
          description: >
            The redeemable invite voucher code. Should be randomly generated and treated as a secret until delivered to
            the recipient.
        type:
          type: string
          enum:
            - registration
          description: |
            registration - grants the recipient the ability to create a new account.
        status:
          type: string
          enum:
            - new
            - pending
            - used
          description: >
            new     - generated but not yet sent to the recipient. pending - sent to the recipient, awaiting redemption.
            used    - redeemed; the code is no longer valid.
        email:
          type: string
          format: email
          description: The email address the invitation was issued to.
        inquiry_id:
          $ref: '#/components/schemas/PrefixedId'
          description: The inquiry that triggered this invitation, if any.
        note:
          type: string
          description: Internal note about why this invitation was issued.
        used_at:
          type: integer
          description: Unix timestamp (ms) when the invitation was redeemed.
        expires_at:
          type: integer
          description: >
            Optional Unix timestamp (ms) after which the invitation is no longer valid. If omitted, the invitation does
            not expire.
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
    Model:
      title: Model
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - description
        - provider
        - status
        - api_types
        - modalities
      properties:
        id:
          type: string
          pattern: ^[a-z][a-z0-9_-]*:.+
          description: Canonical model ID in the form provider:model (e.g. openai:gpt-4o).
        name:
          type: string
          minLength: 1
          description: Provider-local model ID as used in API requests.
        description:
          type: string
          minLength: 1
          description: Short model summary.
        provider:
          $ref: '#/components/schemas/ProviderId'
          description: Provider ID that owns this model.
        family:
          type: string
          minLength: 1
          description: Broad model family name (e.g. gpt-4o, gemini, claude-4).
        lineage:
          type: string
          minLength: 1
          description: Stable model line within a family, used to track successive snapshots.
        snapshots:
          type: object
          description: Map of snapshot alias → lifecycle status.
          propertyNames:
            type: string
            minLength: 1
          additionalProperties:
            $ref: '#/components/schemas/SnapshotStatus'
        status:
          $ref: '#/components/schemas/ModelStatus'
        deprecation:
          type: object
          additionalProperties: false
          properties:
            deprecated_at:
              type: string
              pattern: ^[0-9]{4}-[0-9]{2}(-[0-9]{2})?$
              description: Date (YYYY-MM or YYYY-MM-DD) when the model was marked deprecated.
            eol_at:
              type: string
              pattern: ^[0-9]{4}-[0-9]{2}(-[0-9]{2})?$
              description: Date when the model is no longer expected to be available.
            replacement:
              type: string
              pattern: ^[a-z][a-z0-9_-]*:.+
              description: Canonical replacement model ID (provider:model).
            note:
              type: string
              description: Short migration note.
        api_types:
          type: array
          uniqueItems: true
          minItems: 1
          items:
            $ref: '#/components/schemas/ApiType'
        attributes:
          type: object
          additionalProperties: false
          description: Numeric and structural model attributes.
          properties:
            context_window:
              type: integer
              minimum: 1
              description: Maximum number of tokens in the combined input+output context.
            max_output_tokens:
              type: integer
              minimum: 1
              description: Maximum tokens the model can generate in a single response.
            max_tokens:
              type: integer
              minimum: 1
              description: Maximum input tokens (used for embedding and non-generative models).
            output_dimensions:
              type: integer
              minimum: 1
              description: Embedding vector dimension (embedding models only).
            max_resolution:
              type: string
              minLength: 1
              description: Maximum output resolution (image models, e.g. "1024x1024").
            max_items_per_prompt:
              type: integer
              minimum: 1
              description: Maximum number of images/items generated per request.
            service_tiers:
              type: array
              uniqueItems: true
              minItems: 1
              items:
                $ref: '#/components/schemas/ServiceTier'
            reasoning_effort:
              type: array
              uniqueItems: true
              minItems: 1
              items:
                $ref: '#/components/schemas/ReasoningEffort'
            tools:
              type: array
              minItems: 1
              items:
                type: object
                additionalProperties: false
                required:
                  - api_type
                  - values
                properties:
                  api_type:
                    $ref: '#/components/schemas/ApiType'
                  values:
                    type: array
                    uniqueItems: true
                    minItems: 1
                    items:
                      $ref: '#/components/schemas/ToolType'
        modalities:
          type: array
          uniqueItems: true
          minItems: 1
          description: Input/output modality declarations for this model.
          items:
            type: object
            additionalProperties: false
            required:
              - type
              - input
            properties:
              type:
                $ref: '#/components/schemas/Modality'
              input:
                type: boolean
              output:
                type: boolean
              api_types:
                type: array
                uniqueItems: true
                minItems: 1
                items:
                  $ref: '#/components/schemas/ApiType'
              specs:
                type: object
                additionalProperties: false
                properties:
                  max_items_per_prompt:
                    type: integer
                    minimum: 1
                  max_pages_per_file:
                    type: integer
                    minimum: 1
                  max_inline_file_size_mb:
                    type: number
                    minimum: 0
                  max_direct_upload_file_size_mb:
                    type: number
                    minimum: 0
                  max_gcs_file_size_mb:
                    type: number
                    minimum: 0
                  max_file_size_mb:
                    type: number
                    minimum: 0
                  max_video_length_with_audio_minutes:
                    type: number
                    minimum: 0
                  max_video_length_without_audio_minutes:
                    type: number
                    minimum: 0
                  max_audio_length_hours:
                    type: number
                    minimum: 0
                  max_audio_length_tokens:
                    type: integer
                    minimum: 1
                  default_resolution_tokens:
                    type: integer
                    minimum: 1
                  default_resolution_tokens_per_frame:
                    type: integer
                    minimum: 1
                  ocr_default:
                    type: boolean
                  speech_understanding:
                    type: array
                    uniqueItems: true
                    minItems: 1
                    items:
                      type: string
                      minLength: 1
                  mime_types:
                    type: array
                    uniqueItems: true
                    minItems: 1
                    items:
                      type: string
                      pattern: ^[a-zA-Z0-9][a-zA-Z0-9!#$&\-^_]*/[a-zA-Z0-9][a-zA-Z0-9!#$&\-^_.+]*$
        capabilities:
          type: array
          minItems: 1
          items:
            type: object
            additionalProperties: false
            required:
              - api_type
              - values
            properties:
              api_type:
                $ref: '#/components/schemas/ApiType'
              values:
                type: array
                uniqueItems: true
                minItems: 1
                items:
                  $ref: '#/components/schemas/ModelFeature'
        provider_inference_ids:
          type: object
          description: Map of routing prefix (e.g. us, eu) to provider-specific inference ID.
          minProperties: 1
          propertyNames:
            type: string
            minLength: 1
          additionalProperties:
            type: string
            minLength: 1
        availability:
          type: object
          additionalProperties: false
          properties:
            in_region:
              type: array
              uniqueItems: true
              minItems: 1
              items:
                type: string
                minLength: 1
            geo:
              type: object
              minProperties: 1
              additionalProperties:
                type: array
                uniqueItems: true
                minItems: 1
                items:
                  type: string
                  minLength: 1
            global:
              type: array
              uniqueItems: true
              minItems: 1
              items:
                type: string
                minLength: 1
        endpoint_families:
          type: array
          minItems: 1
          items:
            type: object
            additionalProperties: false
            required:
              - id
              - api_types
            properties:
              id:
                type: string
                minLength: 1
              api_types:
                type: array
                uniqueItems: true
                minItems: 1
                items:
                  $ref: '#/components/schemas/ApiType'
              features:
                type: array
                uniqueItems: true
                minItems: 1
                items:
                  $ref: '#/components/schemas/ModelFeature'
        geo_routing:
          type: object
          description: Map of geo-prefix → region → list of serving regions.
          minProperties: 1
          additionalProperties:
            type: object
            minProperties: 1
            additionalProperties:
              type: array
              uniqueItems: true
              minItems: 1
              items:
                type: string
                minLength: 1
        launch_stage:
          type: string
          minLength: 1
          description: Provider-defined launch stage (e.g. ga, preview, experimental).
        endpoints:
          type: object
          description: >
            Provider-specific endpoint map. Keys are api_type names; values describe path templates or endpoint
            configuration. Schema is provider-defined and intentionally open.
          additionalProperties: true
        rate_limits:
          type: array
          minItems: 1
          items:
            type: object
            additionalProperties: false
            properties:
              tier:
                type: string
                minLength: 1
              region:
                type: string
                minLength: 1
                description: Region this limit applies to (provider-specific).
              rpm:
                type: integer
                minimum: 1
                description: Requests per minute.
              tpm:
                type: integer
                minimum: 1
                description: Tokens per minute.
              tpd:
                type: integer
                minimum: 1
                description: Tokens per day.
              requests_per_day:
                type: integer
                minimum: 1
                description: Requests per day (used for free/dev tiers).
              batch_tpm:
                type: integer
                minimum: 1
                description: Tokens per minute for batch API.
              qpm:
                type: integer
                minimum: 1
                description: Queries per minute (provider-specific alias for rpm).
              context_window:
                type: integer
                minimum: 1
                description: Per-region context window override.
              is_long_context:
                type: boolean
                description: Whether this limit entry applies to the long-context variant.
        params:
          type: object
          additionalProperties: false
          description: Supported inference parameter ranges.
          properties:
            temperature:
              type: object
              additionalProperties: false
              properties:
                min:
                  type: number
                  minimum: 0
                max:
                  type: number
                  maximum: 2
                default:
                  type: number
                  minimum: 0
                  maximum: 2
            top_p:
              type: object
              additionalProperties: false
              properties:
                min:
                  type: number
                  minimum: 0
                max:
                  type: number
                  maximum: 1
                default:
                  type: number
                  minimum: 0
                  maximum: 1
            top_k:
              type: object
              additionalProperties: false
              properties:
                fixed:
                  type: integer
                  minimum: 0
            candidate_count:
              type: object
              additionalProperties: false
              properties:
                min:
                  type: integer
                  minimum: 1
                max:
                  type: integer
                  minimum: 1
                default:
                  type: integer
                  minimum: 1
        meta:
          type: object
          additionalProperties: false
          properties:
            api_reference:
              type: string
              format: uri
            service_card_url:
              type: string
              format: uri
            terms_url:
              type: string
              format: uri
            eula_url:
              type: string
              format: uri
            last_updated:
              type: string
              pattern: ^[0-9]{4}-[0-9]{2}(-[0-9]{2})?$
            knowledge_cutoff:
              type: string
              pattern: ^[0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?$
              description: Training data cutoff date (YYYY, YYYY-MM, or YYYY-MM-DD).
            release_date:
              type: string
              pattern: ^[0-9]{4}-[0-9]{2}(-[0-9]{2})?$
            owner:
              type: string
              minLength: 1
              description: Organization that trained and owns the model weights.
            model_card_url:
              type: string
              format: uri
            license:
              type: string
              minLength: 1
            retirement_date:
              type: string
              pattern: ^[0-9]{4}-[0-9]{2}(-[0-9]{2})?$
            params_total:
              type: string
              minLength: 1
              description: Total parameter count (e.g. "7B", "70B", "unknown").
            params_active:
              type: string
              minLength: 1
              description: Active parameters for MoE models.
            architecture:
              type: string
              minLength: 1
              description: Model architecture type (e.g. dense, moe, unknown).
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
    Principal:
      title: Principal
      description: >
        A human user or machine service account that can authenticate and be granted roles. Credentials (API keys, HMAC
        secrets, passwords) live on Credential records. Federated login identities (Google, GitHub, etc.) live on
        FederatedIdentity records.
      type: object
      additionalProperties: false
      required:
        - id
        - type
        - name
        - status
      properties:
        id:
          $ref: '#/components/schemas/PrefixedId'
        type:
          type: string
          enum:
            - user
            - service
          description: Discriminator — user for humans, service for machine callers.
        name:
          type: string
          minLength: 1
          maxLength: 200
          description: Display name.
        status:
          type: string
          enum:
            - active
            - suspended
            - disabled
        account_id:
          $ref: '#/components/schemas/PrefixedId'
          description: >
            Owning account. Required for service_account principals. Omitted for user principals — account membership
            via account.owner_id.
        scopes:
          type: array
          uniqueItems: true
          items:
            type: string
          description: >
            Scopes declared directly on this principal. Overlaid with other derived scopes (account membership, auth
            method) to form the effective scope set. Primary use: service_account and system principals whose
            permissions are not derived from account membership.
        avatar_url:
          type: string
          format: uri
          description: Profile image URL (user principals only).
        description:
          type: string
          maxLength: 500
        run_as_allowed_types:
          type: array
          uniqueItems: true
          items:
            type: string
            enum:
              - user
              - service
          description: |
            Principal types this service principal is permitted to carry via x-client-credentials.
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
      allOf:
        - if:
            properties:
              type:
                const: service
          then:
            required:
              - account_id
        - if:
            properties:
              type:
                not:
                  const: service
            required:
              - type
          then:
            properties:
              run_as_allowed_types:
                not: {}
              description:
                not: {}
            description: |
              run_as_allowed_types and description are service-only fields.
    Project:
      title: Project
      description: >
        A Project is a named workspace within an Account. Resources such as API keys, models, and usage budgets are
        scoped to a project.
      type: object
      additionalProperties: false
      required:
        - id
        - account_id
        - name
        - slug
        - status
      properties:
        id:
          $ref: '#/components/schemas/PrefixedId'
          description: Unique project identifier.
        account_id:
          $ref: '#/components/schemas/PrefixedId'
          description: The account that owns this project.
        name:
          type: string
          minLength: 1
          maxLength: 100
          description: Human-readable project name.
        slug:
          type: string
          pattern: ^[a-z0-9][a-z0-9-]{1,48}[a-z0-9]$
          description: URL-safe identifier, unique within the account.
        status:
          type: string
          enum:
            - active
            - archived
          description: |
            active   — fully operational. archived — read-only, no new resources can be added.
        description:
          type: string
          maxLength: 500
          description: Optional free-text description of the project's purpose.
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
    Provider:
      title: Provider
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - description
        - base_url
        - default_region
        - status
        - auth
        - regions
        - endpoints
        - models
      properties:
        id:
          $ref: '#/components/schemas/ProviderId'
          description: Canonical provider identifier used by the gateway.
        name:
          type: string
          minLength: 1
          description: Human-readable provider name.
        description:
          type: string
          minLength: 1
          description: Short provider summary.
        base_url:
          type: string
          minLength: 1
          description: >
            Base URL or URL template used to construct upstream endpoints. May contain {region} or {project_id}
            placeholders resolved at runtime.
        global_base_url:
          type: string
          minLength: 1
          description: >
            Global (non-regional) base URL for providers that have a separate region-agnostic endpoint (e.g. Vertex AI
            global endpoint).
        default_region:
          type: string
          minLength: 1
          description: >
            Region used when no override is supplied via environment variable. Must be a key present in the `regions`
            map.
        status:
          $ref: '#/components/schemas/ProviderStatus'
        meta:
          type: object
          additionalProperties: false
          properties:
            website_url:
              type: string
              format: uri
            api_reference:
              type: string
              format: uri
            spec_url:
              type: string
              format: uri
            status_url:
              type: string
              format: uri
            support_url:
              type: string
              format: uri
        auth:
          type: object
          additionalProperties: false
          required:
            - method
          properties:
            method:
              type: string
              enum:
                - none
                - aws_sigv4
                - bearer
                - apikey
                - oauth
                - mtls
            key_env:
              type: string
              minLength: 1
              description: Name of the environment variable that holds the API key or token.
            key_header:
              type: string
              minLength: 1
              description: HTTP header used to transmit the credential (e.g. Authorization, X-Api-Key).
            scopes:
              type: array
              uniqueItems: true
              minItems: 1
              items:
                type: string
                minLength: 1
              description: >
                Required scopes or IAM actions. For oauth: OAuth 2.0 scope strings. For aws_sigv4: IAM action strings
                (e.g. bedrock:InvokeModel).
          if:
            properties:
              method:
                enum:
                  - bearer
                  - apikey
          then:
            required:
              - key_env
        endpoints:
          type: array
          minItems: 1
          items:
            type: object
            additionalProperties: false
            required:
              - api_type
              - protocol
              - path
            properties:
              api_type:
                $ref: '#/components/schemas/ApiType'
              protocol:
                type: string
                enum:
                  - http
                  - https
                  - ws
                  - wss
              path:
                type: string
                minLength: 1
                description: >
                  URL path relative to base_url. May contain path template variables such as {model_id}, {region},
                  {project_id}.
              api_ver:
                type: string
                minLength: 1
                description: API version string (e.g. v1, 2024-02-15-preview).
              api_reference:
                type: string
                format: uri
                description: Link to the upstream API reference for this endpoint.
              extra_headers:
                type: object
                additionalProperties:
                  type: string
                description: Static headers always sent with requests to this endpoint.
        models:
          type: object
          additionalProperties: false
          required:
            - model_names
          properties:
            model_names:
              type: array
              uniqueItems: true
              minItems: 1
              description: Provider-local model names supported by this gateway deployment.
              items:
                type: string
                minLength: 1
        regions:
          type: object
          minProperties: 1
          additionalProperties:
            type: string
            minLength: 1
          description: >
            Map of region identifier to hostname or region string. At least one entry required; use `default_region` to
            identify the fallback.
        env_vars:
          type: object
          additionalProperties: false
          description: Environment variable names for runtime configuration.
          properties:
            region:
              type: array
              items:
                type: string
              description: Ordered list of env var names to check for region override.
        upstream:
          type: object
          additionalProperties: false
          description: Runtime upstream connection settings.
          properties:
            timeout_ms:
              type: integer
              minimum: 0
              description: Request timeout in milliseconds.
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
    Signin:
      title: Signin
      description: >
        A signin event record. Created on each successful authentication or token refresh. Serves as an immutable audit
        trail — one record per credential exchange, regardless of grant type. Query by principal_id or grant_type to
        reconstruct a principal's login history.
      type: object
      additionalProperties: false
      required:
        - principal_id
        - grant_type
      properties:
        id:
          $ref: '#/components/schemas/PrefixedId'
          description: Auto-generated signin event identifier.
        principal_id:
          $ref: '#/components/schemas/PrefixedId'
          description: The principal who authenticated.
        grant_type:
          type: string
          description: Authentication protocol or provider name used for this signin event.
        provider:
          type: string
          description: Provider name for oidc and saml types (e.g. google, github, okta).
        id_token:
          type: string
          description: Raw OIDC id_token presented at signin. Retained for audit.
        email:
          type: string
          format: email
          description: Email address as submitted (password grant).
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
    Signup:
      title: Signup
      description: >
        A signup event record. Created when a new user completes registration. Serves as the audit anchor for the
        principal/federated_identity/account/project creation chain.
      type: object
      additionalProperties: false
      required:
        - principal_id
        - grant_type
      properties:
        id:
          $ref: '#/components/schemas/PrefixedId'
          description: Auto-generated signup event identifier.
        principal_id:
          $ref: '#/components/schemas/PrefixedId'
          description: The principal created by this signup.
        grant_type:
          type: string
          description: Authentication protocol or provider name used to sign up.
        provider:
          type: string
          description: Provider name for oidc and saml types (e.g. google, github, okta).
        id_token:
          type: string
          description: Raw OIDC id_token presented at signup. Retained for audit.
        email:
          type: string
          format: email
          description: Email address as submitted at signup (password grant).
        name:
          type: string
          description: Display name as submitted at signup.
        slug:
          type: string
          description: Account slug as submitted at signup.
        invite_code:
          type: string
          description: Invite code presented at signup. Validated and redeemed before account creation.
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
    Usage:
      title: Usage
      description: >
        One append-only usage event for billing, quota reconciliation, and analytics. Omit fields the gateway or
        provider cannot populate; prefer null only when "known absent" vs unknown.
      type: object
      additionalProperties: false
      required:
        - event_id
        - request_id
        - account_id
        - auth_method
        - provider
        - model
        - api_type
        - processing_type
        - request_url
        - upstream_url
        - input_modality
        - output_modality
        - latency_ms
      properties:
        id:
          type: string
          description: Server-generated record id.
        event_id:
          $ref: '#/components/schemas/PrefixedId'
          description: Unique id for this usage event (idempotency target for sinks).
        timestamp:
          type: integer
          description: When usage was finalized (typically after upstream response completed).
        request_id:
          type: string
          description: Correlates with audit and metrics for the same gateway request.
        session_id:
          type:
            - string
            - 'null'
          description: >
            Groups multiple usage events within a single realtime/WS session. Set for processing_type=realtime; null for
            stateless requests.
        turn_index:
          type: integer
          minimum: 0
          description: >
            Sequential interaction index within a realtime session (matches paired audit record). Null for non-realtime
            requests.
        trace_id:
          type: string
          description: Optional distributed trace id when tracing is enabled.
        account_id:
          type: string
          description: Account charged or attributed for this usage.
        auth_method:
          type: string
          enum:
            - apikey
            - jwt
            - oauth2_client
            - mtls
            - hmac
          description: Auth method from the auth step, when available.
        principal_id:
          type: string
          description: >
            Opaque or hashed principal identifier when finer attribution than account is needed. Must not contain PII in
            clear text.
        project_id:
          type:
            - string
            - 'null'
          description: Project this request was attributed to, when a project session was used.
        quota_id:
          type: string
          description: Quota bucket debited for this request, when multiple buckets exist per account.
        provider:
          $ref: '#/components/schemas/ProviderId'
          description: Upstream provider id.
        model:
          type: string
          description: |
            Canonical model id (provider:model) when resolved; omit if unknown or N/A for this call.
        response_model:
          type: string
          description: >
            Model id as reported by the upstream response body. May differ from `model` when aliases are resolved
            server-side (e.g. gpt-4o → gpt-4o-2024-08-06).
        response_id:
          type:
            - string
            - 'null'
          description: >
            Provider-assigned response id from the upstream response body (e.g. chatcmpl-*, msg_*). Useful for
            correlating gateway events with provider-side logs.
        api_type:
          $ref: '#/components/schemas/ApiType'
        processing_type:
          $ref: '#/components/schemas/ProcessingType'
        region:
          type: string
          description: Provider routing or deployment region when known.
        request_url:
          type: string
          description: URL as received by the gateway from the client.
        upstream_url:
          type: string
          description: URL the gateway forwarded the request to.
        input_modality:
          $ref: '#/components/schemas/Modality'
          description: Dominant modality of the request (text, image, audio, video, pdf, multimodal).
        output_modality:
          $ref: '#/components/schemas/Modality'
          description: Dominant modality of the response (text, image, audio, video, multimodal).
        service_tier:
          oneOf:
            - $ref: '#/components/schemas/ServiceTier'
            - type: 'null'
        finish_reason:
          type:
            - string
            - 'null'
          description: >
            Stop reason as reported by the provider (e.g. stop, end_turn, length, STOP, MAX_TOKENS). Normalized to
            lowercase when possible; kept as-is otherwise.
        reasoning_effort:
          $ref: '#/components/schemas/ReasoningEffort'
        tokens:
          type:
            - object
            - 'null'
          additionalProperties: false
          description: Normalized token counts when the provider reports them. Null for non-token APIs (e.g. TTS, image).
          properties:
            input:
              type: integer
              minimum: 0
            output:
              type: integer
              minimum: 0
            total:
              type: integer
              minimum: 0
            cached_read:
              type:
                - integer
                - 'null'
              minimum: 0
              description: Prompt tokens served from cache (provider cache read).
            cache_write:
              type:
                - integer
                - 'null'
              minimum: 0
              description: Prompt tokens written to cache; typically billed at a higher rate.
            reasoning:
              type:
                - integer
                - 'null'
              minimum: 0
              description: Tokens attributed to reasoning / thinking when exposed by the API.
        tool_calls:
          type: integer
          minimum: 0
          description: Number of tool invocations attributed to this request when counted.
        embeddings:
          type: object
          additionalProperties: false
          description: Usage for embedding-style APIs when token breakdown differs.
          properties:
            input_tokens:
              type: integer
              minimum: 0
            dimensions:
              type: integer
              minimum: 1
            vectors:
              type: integer
              minimum: 1
              description: Number of embedding vectors produced in this call.
        images:
          type: object
          additionalProperties: false
          description: Image generation or vision-heavy usage when not token-primary.
          properties:
            count:
              type: integer
              minimum: 0
            megapixels:
              type: number
              minimum: 0
            steps:
              type: integer
              minimum: 0
              description: Diffusion steps when the model prices by step count.
        audio:
          type:
            - object
            - 'null'
          additionalProperties: false
          properties:
            input_seconds:
              type: number
              minimum: 0
              description: Duration of audio input (speech-to-text).
            output_seconds:
              type: number
              minimum: 0
              description: Duration of audio output (text-to-speech).
            input_tokens:
              type: integer
              minimum: 0
            output_tokens:
              type: integer
              minimum: 0
            input_chars:
              type: integer
              minimum: 0
              description: Character count of text input (TTS). OpenAI bills TTS per character.
        bytes:
          type: object
          additionalProperties: false
          description: Wire-size hints when token counts are missing or for non-text APIs.
          properties:
            request:
              type: integer
              minimum: 0
            response:
              type: integer
              minimum: 0
        latency_ms:
          type: number
          minimum: 0
          description: End-to-end gateway latency for this interaction.
        first_token_ms:
          type:
            - number
            - 'null'
          minimum: 0
          description: Time to first token for streaming responses when measured. Null for realtime sessions.
        context:
          type: object
          description: >
            System-level pass-through facets (env, deployment, gateway version). Populated by the gateway, not the
            client. Not for PII.
          additionalProperties:
            type: string
        tags:
          type: object
          description: Client-supplied string key/value facets for attribution (project, team, experiment).
          additionalProperties:
            type: string
        response_headers:
          type:
            - object
            - 'null'
          additionalProperties:
            type: string
          description: >
            HTTP headers returned by the upstream provider response. Array-valued headers are joined with ", ". Filtered
            to exclude transport, security, rate-limit, and CDN noise headers.
        created_at:
          type: string
          format: date-time
          description: When this record was created.
        updated_at:
          type: string
          format: date-time
          description: When this record was last updated.
        created_by:
          type: string
          description: auth_id of the caller who created this record.
        updated_by:
          type: string
          description: auth_id of the caller who last updated this record.
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: x-api-key
    Hmac:
      type: http
      scheme: bearer
      description: 'HMAC-signed request: x-hmac-auth: HMAC key_id=...,ts=...,sig=...'
    Passthrough:
      type: apiKey
      in: header
      name: x-auth-scopes
      description: 'Internal s2s: comma-separated scope list. Strip at the external gateway.'
