> ## 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.

# Create virtual key

> Mints a new virtual key and returns the secret exactly once. The caller MUST persist the `secret` value, because LangWatch stores only a hash. `scopes` defaults to the caller's project; org- and team-scoped keys require a scoped API key holding `virtualKeys:manage` at each requested scope. An org- or team-scoped key also needs a place for its traces and spend to land, and must say where: pass `trace_project_id` (needs `virtualKeys:manage` on that project). Without it, and without exactly one project scope to take it from, creation refuses with `gateway_trace_project_ambiguous`, because the spend would be attributed to the organization's hidden governance project and counted by no budget on the project you had in mind. An organization whose only project is the governance one is exempt, since there is nothing else to name; one with no governance project either refuses with `trace_project_required`. Send `Idempotency-Key` to make a retry safe: a replay returns the original response including its `secret`, which is the only way to recover a secret whose response was lost in transit.



## OpenAPI

````yaml POST /api/gateway/v1/virtual-keys
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:
    post:
      tags:
        - Virtual Keys
      summary: Create virtual key
      description: >-
        Mints a new virtual key and returns the secret exactly once. The caller
        MUST persist the `secret` value, because LangWatch stores only a hash.
        `scopes` defaults to the caller's project; org- and team-scoped keys
        require a scoped API key holding `virtualKeys:manage` at each requested
        scope. An org- or team-scoped key also needs a place for its traces and
        spend to land, and must say where: pass `trace_project_id` (needs
        `virtualKeys:manage` on that project). Without it, and without exactly
        one project scope to take it from, creation refuses with
        `gateway_trace_project_ambiguous`, because the spend would be attributed
        to the organization's hidden governance project and counted by no budget
        on the project you had in mind. An organization whose only project is
        the governance one is exempt, since there is nothing else to name; one
        with no governance project either refuses with `trace_project_required`.
        Send `Idempotency-Key` to make a retry safe: a replay returns the
        original response including its `secret`, which is the only way to
        recover a secret whose response was lost in transit.
      operationId: postApiGatewayV1VirtualKeys
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          description: >-
            A caller-chosen key, 8 to 255 characters, that makes this create
            safe to retry. The first request to use a key runs normally and its
            response is stored for 24 hours. A later request with the same key
            and the same body is not executed again: it returns the stored
            response, marked with `X-Idempotent-Replay: true`. The same key with
            a different body is refused 409 `idempotency_error`, as is a retry
            sent while the original is still running. Only successful responses
            are stored, so a create that failed can simply be retried with the
            same key.
          schema:
            type: string
            minLength: 8
            maxLength: 255
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 128
                description:
                  type: string
                principal_user_id:
                  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'
                routing_policy_id:
                  type:
                    - string
                    - 'null'
                routing_mode:
                  type: string
                  enum:
                    - none
                    - fallback_all
                    - policy
                expires_at:
                  type: string
                  description: >-
                    When the key stops serving. Omit it and the key never
                    expires. A date that has already passed is refused with
                    `virtual_key_expiry_in_past`, rather than writing a key that
                    is dead on arrival.
                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
                purpose:
                  type: string
                  const: user
              required:
                - name
      responses:
        '201':
          description: Virtual key created
          headers:
            X-Idempotent-Replay:
              description: >-
                Present and `true` only when this body came from a stored
                response rather than a fresh execution. Absent on the first use
                of a key, and on every request that carries no key.
              schema:
                type: string
                enum:
                  - 'true'
          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
                  secret:
                    type: string
                required:
                  - virtual_key
                  - secret
        '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: Caller lacks virtualKeys:manage at a requested scope
          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
        '409':
          description: Conflict
          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.

````