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

> ## Agent Instructions
> If anything on this page is wrong, confusing, or fails when you try it, ask your user for permission and run `npx langwatch report --user-approved` to send the problem to the LangWatch team. No login is needed and secrets are redacted locally. `npx langwatch report --help` has the details.

# Update virtual key

> Partial update: send only the fields you want to change. `scopes` replaces the entire visibility set and requires `virtualKeys:manage` at every NEW scope, and does NOT move where the key's traces and costs land: send `trace_project_id` for that, validated the way create validates it; explicit null re-resolves it under the create-time rules rather than clearing it. `config` is deep-merged. `budget` upserts the key's own cap; explicit null archives it.



## OpenAPI

````yaml PATCH /api/gateway/v1/virtual-keys/{id}
openapi: 3.1.0
info:
  title: LangWatch API
  version: 1.0.0
  description: LangWatch openapi spec
servers:
  - url: https://app.langwatch.ai
security:
  - project_api_key: []
paths:
  /api/gateway/v1/virtual-keys/{id}:
    patch:
      tags:
        - Virtual Keys
      summary: Update virtual key
      description: >-
        Partial update: send only the fields you want to change. `scopes`
        replaces the entire visibility set and requires `virtualKeys:manage` at
        every NEW scope, and does NOT move where the key's traces and costs
        land: send `trace_project_id` for that, validated the way create
        validates it; explicit null re-resolves it under the create-time rules
        rather than clearing it. `config` is deep-merged. `budget` upserts the
        key's own cap; explicit null archives it.
      operationId: patchApiGatewayV1VirtualKeysById
      parameters:
        - schema:
            type: string
          in: path
          name: id
          required: true
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 128
                description:
                  type:
                    - string
                    - 'null'
                scopes:
                  type: array
                  items:
                    type: object
                    properties:
                      scope_type:
                        type: string
                        enum:
                          - organization
                          - team
                          - project
                      scope_id:
                        type: string
                        minLength: 1
                    required:
                      - scope_type
                      - scope_id
                  minItems: 1
                trace_project_id:
                  type:
                    - string
                    - 'null'
                  description: >-
                    Where the key's traces and costs land. Omit it and the
                    destination stays exactly where it is, scope edits included.
                    A value moves it, validated the way create validates it.
                    Explicit null does not clear it: it asks for the destination
                    to be worked out again from what the key is now, under the
                    same rules create uses. It lands on the key's single project
                    scope when exactly one names a live project, and otherwise
                    on the organization's oldest live governance project when
                    there are no other live projects to choose from. An
                    organization with live projects that could have been named
                    refuses with `gateway_trace_project_ambiguous`, and one with
                    no governance project to fall back on refuses with
                    `trace_project_required`.
                routing_policy_id:
                  type:
                    - string
                    - 'null'
                routing_mode:
                  type: string
                  enum:
                    - none
                    - fallback_all
                    - policy
                expires_at:
                  type:
                    - string
                    - 'null'
                  description: >-
                    When the key stops serving. Omit it and the stored date
                    stays where it is; null clears it, so the key never expires;
                    a date moves it. A key whose date has already passed accepts
                    this edit like any other, which is how an expired key is put
                    back in service without minting a new secret. A date in the
                    past is refused with `virtual_key_expiry_in_past`.
                budget:
                  type:
                    - object
                    - 'null'
                  properties:
                    limit_usd:
                      anyOf:
                        - type: number
                          exclusiveMinimum: 0
                        - type: string
                          pattern: ^\d+(\.\d+)?$
                    window:
                      type: string
                      enum:
                        - day
                        - week
                        - month
                    on_breach:
                      type: string
                      enum:
                        - block
                        - warn
                    name:
                      type: string
                      minLength: 1
                      maxLength: 128
                  required:
                    - limit_usd
                    - window
                config:
                  type: object
                  properties:
                    modelsAllowed:
                      type:
                        - array
                        - 'null'
                      items:
                        type: string
                      default: null
                    providersAllowed:
                      type:
                        - array
                        - 'null'
                      items:
                        type: string
                      default: null
                    cache:
                      type: object
                      properties:
                        mode:
                          type: string
                          enum:
                            - respect
                            - force
                            - disable
                          default: respect
                        ttlS:
                          type: integer
                          minimum: 0
                          default: 3600
                      default:
                        mode: respect
                        ttlS: 3600
                    fallback:
                      type: object
                      properties:
                        maxAttempts:
                          type: integer
                          exclusiveMinimum: 0
                          default: 3
                      default:
                        maxAttempts: 3
                    guardrailAttachments:
                      type: array
                      items:
                        type: object
                        properties:
                          direction:
                            type: string
                            enum:
                              - pre
                              - post
                              - stream_chunk
                          guardrailIds:
                            type: array
                            items:
                              type: string
                            default: []
                        required:
                          - direction
                      default: []
                    rateLimits:
                      type: object
                      properties:
                        rpm:
                          type:
                            - integer
                            - 'null'
                          default: null
                        tpm:
                          type:
                            - integer
                            - 'null'
                          default: null
                        rpd:
                          type:
                            - integer
                            - 'null'
                          default: null
                      default:
                        rpm: null
                        tpm: null
                        rpd: null
                    realtime:
                      type: object
                      properties:
                        maxOpenSessions:
                          type:
                            - integer
                            - 'null'
                          exclusiveMinimum: 0
                          default: null
                      default:
                        maxOpenSessions: null
                    metadata:
                      type: object
                      properties:
                        label:
                          type: string
                        tags:
                          type: array
                          items:
                            type: string
                          default: []
                      default:
                        tags: []
                external_id:
                  type:
                    - string
                    - 'null'
                  minLength: 1
                  maxLength: 128
                metadata:
                  type: object
                  propertyNames:
                    type: string
                    minLength: 1
                    maxLength: 64
                  additionalProperties:
                    type: string
                    maxLength: 500
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  virtual_key:
                    type: object
                    properties:
                      id:
                        type: string
                      organization_id:
                        type: string
                      name:
                        type: string
                      description:
                        type:
                          - string
                          - 'null'
                      status:
                        type: string
                        enum:
                          - active
                          - disabled
                          - revoked
                      purpose:
                        type: string
                        enum:
                          - user
                          - langy
                      display_prefix:
                        type: string
                      principal_user_id:
                        type:
                          - string
                          - 'null'
                      trace_project_id:
                        type:
                          - string
                          - 'null'
                        description: >-
                          The project this key's traces and costs land in, which
                          is the project its spend is attributed to. Not a
                          scope: it grants no access to the key. Decided when
                          the key is written and stored on it, so editing what
                          the key is scoped to never moves it; send
                          `trace_project_id` on an update to move it. Null only
                          on a key created before this was stored, in an
                          organization that had no governance project to fall
                          back to; those keys export no spans until they are
                          given a destination.
                      trace_project_archived:
                        type: boolean
                        description: >-
                          True when the project in `trace_project_id` has been
                          deleted. The key goes on sending its traces there, so
                          the data stays whole and reappears if the project is
                          restored, and traffic is never refused for it. Nothing
                          else on the key says the destination is gone.
                      external_id:
                        type:
                          - string
                          - 'null'
                      metadata:
                        type: object
                        additionalProperties:
                          type: string
                      scopes:
                        type: array
                        items:
                          type: object
                          properties:
                            scope_type:
                              type: string
                              enum:
                                - organization
                                - team
                                - project
                            scope_id:
                              type: string
                          required:
                            - scope_type
                            - scope_id
                      routing_policy_id:
                        type:
                          - string
                          - 'null'
                      routing_mode:
                        type: string
                        enum:
                          - none
                          - fallback_all
                          - policy
                      config: {}
                      revision:
                        type: string
                      created_at:
                        type: string
                        format: date-time
                      updated_at:
                        type: string
                        format: date-time
                      last_used_at:
                        type:
                          - string
                          - 'null'
                        format: date-time
                      revoked_at:
                        type:
                          - string
                          - 'null'
                        format: date-time
                      expires_at:
                        type:
                          - string
                          - 'null'
                        format: date-time
                        description: >-
                          When the key stops serving, or null for a key that
                          never expires. Requests presented after this moment
                          are refused with `virtual_key_expired`. `status` stays
                          `active` past the date on purpose: the three status
                          values are what clients switch on, and the key stays
                          editable so the date can be extended.
                    required:
                      - id
                      - organization_id
                      - name
                      - description
                      - status
                      - purpose
                      - display_prefix
                      - principal_user_id
                      - trace_project_id
                      - trace_project_archived
                      - external_id
                      - metadata
                      - scopes
                      - routing_policy_id
                      - routing_mode
                      - revision
                      - created_at
                      - updated_at
                      - last_used_at
                      - revoked_at
                      - expires_at
                required:
                  - virtual_key
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                      code:
                        type: string
                      message:
                        type: string
                      meta:
                        type: object
                        additionalProperties: {}
                      trace_id:
                        type: string
                      span_id:
                        type: string
                    required:
                      - type
                      - code
                      - message
                required:
                  - error
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                      code:
                        type: string
                      message:
                        type: string
                      meta:
                        type: object
                        additionalProperties: {}
                      trace_id:
                        type: string
                      span_id:
                        type: string
                    required:
                      - type
                      - code
                      - message
                required:
                  - error
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                      code:
                        type: string
                      message:
                        type: string
                      meta:
                        type: object
                        additionalProperties: {}
                      trace_id:
                        type: string
                      span_id:
                        type: string
                    required:
                      - type
                      - code
                      - message
                required:
                  - error
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                      code:
                        type: string
                      message:
                        type: string
                      meta:
                        type: object
                        additionalProperties: {}
                      trace_id:
                        type: string
                      span_id:
                        type: string
                    required:
                      - type
                      - code
                      - message
                required:
                  - error
      security:
        - project_api_key: []
components:
  securitySchemes:
    project_api_key:
      type: apiKey
      in: header
      name: X-Auth-Token
      description: >-
        Project API key for sending traces and accessing project-scoped
        resources. Format: sk-lw-... (no underscore). Obtain one by creating a
        project via the Admin API or the LangWatch UI.

````