> ## Documentation Index
> Fetch the complete documentation index at: https://docs.slng.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Update Client Model

> Update one client model owned by your organisation. Send the fields you want to change (at least one is required); omitted fields keep their stored values. A model owned by another organisation returns 404. The write-only `api_key`, `vertex_credentials`, and `aws_credentials` fields overwrite the stored secret when supplied and are never returned.



## OpenAPI

````yaml /api-reference/agents/shared-resources.oas.yaml put /v1/agents/client-models/{client_model_id}
openapi: 3.1.0
info:
  title: SLNG Agent Resources API
  version: 1.0.0
  description: >-
    Public control-plane API for agent resources: tools, MCP servers, Vault
    secrets and variables, and client models.
servers:
  - url: https://api.agents.slng.ai
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Tools
    description: Create, test, publish, version, and attach agent tools.
    x-page-icon: wrench
  - name: MCP servers
    description: Configure MCP servers and refresh their live capabilities.
    x-page-icon: plug
  - name: Vault
    description: >-
      Store organisation secrets and readable variables without exposing secret
      values.
    x-page-icon: key
  - name: Client models
    description: Manage bring-your-own LLM provider credentials.
    x-page-icon: brain
paths:
  /v1/agents/client-models/{client_model_id}:
    put:
      tags:
        - Client models
      summary: Update Client Model
      description: >-
        Update one client model owned by your organisation. Send the fields you
        want to change (at least one is required); omitted fields keep their
        stored values. A model owned by another organisation returns 404. The
        write-only `api_key`, `vertex_credentials`, and `aws_credentials` fields
        overwrite the stored secret when supplied and are never returned.
      operationId: updateClientModel
      parameters:
        - name: client_model_id
          in: path
          required: true
          description: >-
            The UUID of the client model to update. A model owned by another
            organisation returns 404.
          example: 6a3f5b2c-1d4e-4f8a-9b0c-2e3d4f5a6b7c
          schema:
            type: string
            format: uuid
            title: Client Model Id
      requestBody:
        required: true
        description: >-
          The fields to change on the client model. At least one must be
          supplied.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClientModelUpdate'
            examples:
              Rotate API key:
                summary: Rotate the stored upstream API key
                value:
                  api_key: sk-proj-new-example
              Rename model:
                summary: Point the alias at a different upstream model
                value:
                  model_name: gpt-4o
      responses:
        '200':
          description: The updated client model.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientModelOut'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '403':
          $ref: '#/components/responses/ForbiddenError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '409':
          $ref: '#/components/responses/ConflictError'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimitError'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  schemas:
    ClientModelUpdate:
      properties:
        url:
          anyOf:
            - type: string
              maxLength: 2000
              minLength: 1
            - type: 'null'
          title: Url
        api_key:
          anyOf:
            - type: string
              minLength: 1
            - type: 'null'
          description: >-
            A replacement upstream provider API key. Write-only: overwrites the
            stored key and is never returned. Required for openai-compat,
            openai-responses, and azure; rejected for vertex.
          title: Api Key
          writeOnly: true
        model_name:
          anyOf:
            - type: string
              maxLength: 255
              minLength: 1
            - type: 'null'
          description: >-
            A new alias for the model. Sent upstream as-is unless `model_id` is
            set.
          title: Model Name
        model_id:
          anyOf:
            - type: string
              maxLength: 255
            - type: 'null'
          description: >-
            A new upstream provider-facing model id. Empty or null sends
            `model_name` as-is.
          title: Model Id
        provider:
          anyOf:
            - type: string
              enum:
                - openai-compat
                - openai-responses
                - azure
                - vertex
            - type: 'null'
          description: >-
            The bring-your-own model provider to set. Changing it re-checks the
            per-provider field requirements against the merged record. Values:
            `openai-compat` and `openai-responses` (OpenAI-compatible
            endpoints), `azure` (Azure OpenAI), and `vertex` (Google Vertex AI).
          title: Provider
        model_lab:
          anyOf:
            - type: string
              maxLength: 100
            - type: 'null'
          title: Model Lab
        azure_deployment:
          anyOf:
            - type: string
              maxLength: 255
            - type: 'null'
          description: A new Azure OpenAI deployment name. Azure only.
          title: Azure Deployment
        api_version:
          anyOf:
            - type: string
              maxLength: 100
            - type: 'null'
          description: A new Azure OpenAI API version. Azure only.
          title: Api Version
        auth_header:
          anyOf:
            - type: string
              maxLength: 64
            - type: 'null'
          description: >-
            openai-compat and openai-responses only: change the custom
            credential header name that replaces the default Authorization
            Bearer scheme. Rejected for azure and vertex.
          title: Auth Header
        vertex_credentials:
          anyOf:
            - type: object
              additionalProperties: true
            - type: 'null'
          description: >-
            Vertex only: a replacement GCP service-account key JSON. Write-only;
            stored encrypted and never returned (responses expose
            `has_vertex_credentials`).
          title: Vertex Credentials
          writeOnly: true
        vertex_location:
          anyOf:
            - type: string
              maxLength: 100
            - type: 'null'
          title: Vertex Location
        vertex_project:
          anyOf:
            - type: string
              maxLength: 100
            - type: 'null'
          title: Vertex Project
        aws_credentials:
          anyOf:
            - type: object
              additionalProperties: true
            - type: 'null'
          description: >-
            Speech BYOK only: replacement AWS SigV4 credentials (access_key_id,
            secret_access_key, region). Write-only; stored encrypted and never
            returned (responses expose `has_aws_credentials`).
          title: Aws Credentials
          writeOnly: true
        languages:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Languages
        regions:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Regions
        enabled:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Enabled
        kwargs:
          anyOf:
            - type: object
              additionalProperties: true
            - type: 'null'
          title: Kwargs
        fallbacks:
          anyOf:
            - items:
                $ref: '#/components/schemas/LlmRouterConfigEntry'
              type: array
              maxItems: 2
            - type: 'null'
          title: Fallbacks
      type: object
      title: ClientModelUpdate
      description: >-
        Fields to change on an existing client model. All are optional and at
        least one must be supplied; omitted fields keep their stored values.
        Write-only credential fields overwrite the stored secret when provided.
      example:
        model_name: gpt-4o
        enabled: false
    ClientModelOut:
      properties:
        id:
          type: string
          format: uuid
          title: Id
        org_id:
          type: string
          format: uuid
          title: Org Id
        api_key_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          description: >-
            Speech BYOK only: the API key id this credential is scoped to, or
            null for the organisation default. Non-secret.
          title: Api Key Id
        service_type:
          type: string
          enum:
            - llm
            - stt
            - tts
          description: 'The kind of model: `llm`, `stt`, or `tts`.'
          title: Service Type
        provider:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The configured provider. May be a legacy free-form label on records
            created before the current provider set.
          title: Provider
        model_lab:
          anyOf:
            - type: string
            - type: 'null'
          title: Model Lab
        url:
          anyOf:
            - type: string
            - type: 'null'
          title: Url
        has_api_key:
          type: boolean
          description: >-
            Whether an upstream API key is stored. The key value is write-only
            and never returned.
          title: Has Api Key
        auth_header:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The custom credential header name, or null for the default
            Authorization Bearer scheme. The credential value itself is never
            returned.
          title: Auth Header
        model_name:
          type: string
          description: The configured alias for the model.
          title: Model Name
        model_id:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The upstream provider-facing model id, or null when `model_name` is
            sent as-is.
          title: Model Id
        fallbacks:
          anyOf:
            - items:
                $ref: '#/components/schemas/LlmRouterConfigEntry'
              type: array
            - type: 'null'
          title: Fallbacks
        azure_deployment:
          anyOf:
            - type: string
            - type: 'null'
          description: The configured Azure OpenAI deployment name (Azure only).
          title: Azure Deployment
        api_version:
          anyOf:
            - type: string
            - type: 'null'
          description: The configured Azure OpenAI API version (Azure only).
          title: Api Version
        has_vertex_credentials:
          type: boolean
          description: >-
            Whether Vertex service-account credentials are stored. The value is
            write-only and never returned.
          title: Has Vertex Credentials
        has_aws_credentials:
          type: boolean
          description: >-
            Whether AWS SigV4 credentials are stored. The value is write-only
            and never returned.
          title: Has Aws Credentials
        vertex_location:
          anyOf:
            - type: string
            - type: 'null'
          title: Vertex Location
        vertex_project:
          anyOf:
            - type: string
            - type: 'null'
          title: Vertex Project
        languages:
          items:
            type: string
          type: array
          title: Languages
        regions:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Regions
        enabled:
          type: boolean
          title: Enabled
        kwargs:
          anyOf:
            - type: object
              additionalProperties: true
            - type: 'null'
          title: Kwargs
        created_at:
          type: string
          format: date-time
          title: Created At
        updated_at:
          type: string
          format: date-time
          title: Updated At
      type: object
      required:
        - id
        - org_id
        - service_type
        - provider
        - model_lab
        - url
        - has_api_key
        - auth_header
        - model_name
        - model_id
        - azure_deployment
        - api_version
        - has_vertex_credentials
        - has_aws_credentials
        - vertex_location
        - vertex_project
        - languages
        - regions
        - enabled
        - kwargs
        - created_at
        - updated_at
      title: ClientModelOut
      description: >-
        A client model as returned by the API. Credential values are never
        included; `has_api_key`, `has_vertex_credentials`, and
        `has_aws_credentials` report whether each secret is stored, and
        `fallbacks` lists the configured fallback cascade.
      example:
        id: 6a3f5b2c-1d4e-4f8a-9b0c-2e3d4f5a6b7c
        org_id: 1b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e
        api_key_id: null
        service_type: llm
        provider: openai-compat
        model_lab: null
        url: https://api.openai.com/v1
        has_api_key: true
        auth_header: null
        model_name: gpt-4o-mini
        model_id: null
        fallbacks: []
        azure_deployment: null
        api_version: null
        has_vertex_credentials: false
        has_aws_credentials: false
        vertex_location: null
        vertex_project: null
        languages: []
        regions: null
        enabled: true
        kwargs: null
        created_at: '2026-01-15T09:30:00Z'
        updated_at: '2026-01-15T09:30:00Z'
    LlmRouterConfigEntry:
      properties:
        client_model_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          description: >-
            Bring-your-own model reference: the id of one of your client models.
            Mutually exclusive with `catalog_model_code` (set at most one).
          title: Client Model Id
        catalog_model_code:
          anyOf:
            - type: string
              maxLength: 255
              minLength: 1
            - type: 'null'
          description: >-
            SLNG-managed model reference: a catalog model code. Mutually
            exclusive with `client_model_id`.
          title: Catalog Model Code
      type: object
      title: LlmRouterConfigEntry
      description: >-
        One slot in a config's ordered fallback cascade (``entries``).


        Exactly one of ``client_model_id`` (BYOK) or ``catalog_model_code``

        (Slng-managed) — the same XOR as the row-level model reference. Org

        ownership / catalog entitlement are checked in the service layer (needs
        the

        DB session); position in the list is the tier the sync derives
        (1-based).
      example:
        client_model_id: 6a3f5b2c-1d4e-4f8a-9b0c-2e3d4f5a6b7c
        catalog_model_code: null
    ApiErrorResponse:
      type: object
      description: Standard error envelope returned for failed requests.
      required:
        - detail
        - error
      properties:
        detail:
          type: string
          description: Short human-readable summary of the error.
        error:
          $ref: '#/components/schemas/ApiErrorDetail'
      example:
        detail: A shared secret or variable named 'STRIPE_KEY' already exists
        error:
          code: RESOURCE_CONFLICT
          message: A shared secret or variable named 'STRIPE_KEY' already exists
          request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
    ApiErrorDetail:
      type: object
      description: Structured error detail carried inside an error response.
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Stable machine-readable error code.
          example: RESOURCE_CONFLICT
        message:
          type: string
          description: Human-readable explanation of the error.
          example: A shared secret or variable named STRIPE_KEY already exists
        request_id:
          type:
            - string
            - 'null'
          description: Identifier for this request, useful when contacting support.
          example: req_01H8XY7Z9QEXAMPLE
        retryable:
          type: boolean
          description: Whether retrying the same request may succeed.
          example: false
        fields:
          type: array
          description: >-
            Per-field validation problems, when the error relates to specific
            request fields.
          items:
            type: object
            additionalProperties: true
          example: []
      example:
        code: PUBLIC_SHARED_RESOURCES_DISABLED
        message: Public shared resources are disabled for this organisation
        request_id: req_01H8XY7Z9QEXAMPLE
        retryable: false
  responses:
    UnauthorizedError:
      description: The API key is missing or invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: Invalid API key
            error:
              code: AUTH_REQUIRED
              message: Invalid API key
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
              retryable: false
    ForbiddenError:
      description: >-
        The caller lacks permission, or the public shared-resource API is
        disabled for the organisation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          examples:
            permission_denied:
              summary: Owner or admin access required
              value:
                detail: Organisation owner or admin access required
                error:
                  code: PERMISSION_DENIED
                  message: Organisation owner or admin access required
                  request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
                  retryable: false
            api_disabled:
              summary: Public shared-resource API disabled for the organisation
              value:
                detail: >-
                  Public shared-resource API access is disabled for this
                  organisation
                error:
                  code: PUBLIC_SHARED_RESOURCES_DISABLED
                  message: >-
                    Public shared-resource API access is disabled for this
                    organisation
                  request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
                  retryable: false
    NotFoundError:
      description: The requested resource does not exist for this organisation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: The requested resource was not found.
            error:
              code: RESOURCE_NOT_FOUND
              message: The requested resource was not found.
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
    ConflictError:
      description: The request conflicts with the current state of the resource.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: The request conflicts with the current state of the resource.
            error:
              code: RESOURCE_CONFLICT
              message: The request conflicts with the current state of the resource.
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
    ValidationError:
      description: Request validation failed. See error.fields for the offending fields.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: >-
              Request validation failed. Fix the highlighted fields and try
              again.
            error:
              code: VALIDATION_FAILED
              message: >-
                Request validation failed. Fix the highlighted fields and try
                again.
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
              retryable: false
              fields:
                - path: name
                  message: >-
                    Name must be SCREAMING_SNAKE_CASE: start with a letter, then
                    letters, digits, or underscores (e.g. STRIPE_API_KEY)
    RateLimitError:
      description: >-
        The organisation exceeded its request rate limit. Retry after the window
        resets.
      headers:
        Retry-After:
          schema:
            type: integer
        X-RateLimit-Limit:
          schema:
            type: integer
        X-RateLimit-Remaining:
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: Rate limit exceeded. Maximum 60 requests per 60 seconds.
            error:
              code: INTERNAL_ERROR
              message: Rate limit exceeded. Maximum 60 requests per 60 seconds.
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
              retryable: false
    InternalServerError:
      description: The request failed unexpectedly. Secret values are never exposed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            detail: An unexpected error occurred.
            error:
              code: INTERNAL_ERROR
              message: An unexpected error occurred.
              request_id: 018f9b2c-7e4a-7c3d-9a1b-2c3d4e5f6a7b
              retryable: false
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: SLNG API key
      description: Your SLNG consumer API key.

````