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

# Run Leaderboard

> Start a red team run whose results are published to the **LLM safety leaderboard**.

> **Internal API.** Calling it requires an `@enkryptai.com` or `@anaconda.com` account; every other key receives `403`. To have a model added to the public leaderboard, contact dkumar@anaconda.com.

The recipe is **frozen**: the prompt corpus, the attack methods and the judge are fixed by the service, which is what makes scores comparable between models. There is therefore nothing to scope — no `risk_categories`, no `compliance_frameworks`, no `attack_config` and no `generation_config` — and sending any of them returns `422`.

There is no `context` field either, so a Code of Conduct policy cannot be passed in the body; name it in the `X-Enkrypt-Policy` header instead.

Everything after submission is the ordinary Red Team v2 flow: a `202` carrying a `run_id` (prefixed `lb-`), then `GET /rt/runs/{run_id}`, `.../results` and `.../records` as usual.



## OpenAPI

````yaml POST /rt/leaderboard
openapi: 3.0.0
info:
  title: Enkrypt AI APIs
  version: 2.0.0
servers:
  - url: https://api.enkryptai.com
security:
  - apiKeyAuth: []
tags:
  - name: Guardrails
  - name: Code of Conduct
  - name: Endpoints
  - name: Redteam
    description: >-
      Red Team API: submit red-team / threat-modeling / playground / eval runs,
      then poll run status, records, results and compliance. Also two-phase
      threat modeling (categories + data), dataset retrieval, model health,
      findings and risk mitigation. The previous task-based Red Team API is
      under **Archived**.
  - name: Deployments
  - name: AI Proxy
  - name: Leaderboard
  - name: Archived
  - name: MCP Hub
    description: >-
      MCP Hub vulnerability scanning APIs. Submitting scans (the POST endpoints)
      is open to all authenticated callers. The scan **retrieval** APIs — Get
      Scan Job Status, Get Complete Scan Results, List Scans, and Get MCP Hub
      Scan Statistics (the GET endpoints) — are an **enterprise data-license
      feature**: they require your organization to have MCP Hub API access
      enabled by Enkrypt, otherwise they return `403`. Contact us at
      support@enkryptai.com to enable access.
  - name: MCP Registry Servers
  - name: MCP Gateways
  - name: MCP Playground
  - name: Skill Scanner
    description: >-
      Skill Scanner APIs: submit an agent skill (a directory inside a git
      repository) for security scanning, then read the verdict, the risk level
      and the full report. Scanning is asynchronous — a scan takes roughly 30–90
      seconds, so `POST /skill-hub/scan` returns a `scan_id` you poll.


      You see your organization's scans and nobody else's. The identity comes
      from your API key, never from your request — sending `user_email` is a
      `400`.


      For an organization or project API key, scans are filed under the
      **organization**, so every member sees every scan the organization has
      run, whichever project or member submitted it. For an individual account
      it is simply your own scans. Either way List Skill Scans needs no
      parameter to say who you are.
paths:
  /rt/leaderboard:
    post:
      tags:
        - Redteam
      summary: Run Leaderboard
      description: >-
        Start a red team run whose results are published to the **LLM safety
        leaderboard**.


        > **Internal API.** Calling it requires an `@enkryptai.com` or
        `@anaconda.com` account; every other key receives `403`. To have a model
        added to the public leaderboard, contact dkumar@anaconda.com.


        The recipe is **frozen**: the prompt corpus, the attack methods and the
        judge are fixed by the service, which is what makes scores comparable
        between models. There is therefore nothing to scope — no
        `risk_categories`, no `compliance_frameworks`, no `attack_config` and no
        `generation_config` — and sending any of them returns `422`.


        There is no `context` field either, so a Code of Conduct policy cannot
        be passed in the body; name it in the `X-Enkrypt-Policy` header instead.


        Everything after submission is the ordinary Red Team v2 flow: a `202`
        carrying a `run_id` (prefixed `lb-`), then `GET /rt/runs/{run_id}`,
        `.../results` and `.../records` as usual.
      operationId: run_leaderboard_v1_leaderboard_post
      parameters:
        - name: X-Enkrypt-Policy
          in: header
          required: false
          schema:
            title: Code of Conduct Policy Name
            type: string
            description: >-
              Optional. The name of a saved Code of Conduct policy to label the
              run with. There is deliberately no body field for this — the
              request model rejects unknown keys.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RTv2LeaderboardRequest'
        required: true
      responses:
        '202':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RTv2RunQueuedResponse'
        '403':
          $ref: '#/components/responses/RTv2LeaderboardForbidden'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RTv2HTTPValidationError'
components:
  schemas:
    RTv2LeaderboardRequest:
      properties:
        target:
          $ref: '#/components/schemas/RTv2ModelConfig'
        run_name:
          type: string
          maxLength: 200
          minLength: 1
          nullable: true
          title: Run Name
        user_metadata:
          additionalProperties: true
          type: object
          nullable: true
          title: User Metadata
      additionalProperties: false
      type: object
      required:
        - target
      title: RTv2LeaderboardRequest
      description: >-
        `POST /v1/leaderboard` payload.


        Frozen recipe: corpus, attacks, and judge are not caller-configurable —
        that is what keeps scores comparable between models.
    RTv2RunQueuedResponse:
      additionalProperties: true
      type: object
      title: RunQueuedResponse
      description: >-
        The accepted run. `run_id` is the value to carry into the run endpoints
        (`GET /rt/runs/{run_id}`, `/records`, `/results`, `/stream`).


        **Do not follow the `*_url` fields verbatim.** They are relative and are
        not guaranteed to carry the `/rt/` prefix this API is published under,
        so requesting one as given can return `400`. Build the URL from `run_id`
        and the paths documented here instead - `/rt/runs/{run_id}/records` is
        the resource you want. The same applies to `records_url` on the results
        payload.


        `websocket_url` is the **Server-Sent Events** progress stream
        (`/rt/runs/{run_id}/stream`) despite its name. The live log socket is
        `logs_url` - a relative path to join onto
        `wss://api.enkryptai.com/wss/redteam/v1/logs/tasks/`. See the `Stream
        Run Logs (WebSocket)` endpoint.
    RTv2HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/RTv2ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    RTv2ModelConfig:
      properties:
        endpoint:
          type: string
          title: Endpoint
        api_key:
          type: string
          title: Api Key
        model_name:
          title: Model Name
          type: string
        provider:
          type: string
          nullable: true
          title: Provider
        system_prompt:
          type: string
          nullable: true
          title: System Prompt
        system_type:
          $ref: '#/components/schemas/RTv2SystemType'
          default: foundation_model
        input_modalities:
          items:
            $ref: '#/components/schemas/RTv2Modality'
          type: array
          title: Input Modalities
        output_modalities:
          items:
            $ref: '#/components/schemas/RTv2Modality'
          type: array
          title: Output Modalities
        tools:
          items:
            $ref: '#/components/schemas/RTv2ToolSpec'
          type: array
          title: Tools
        connect_via_relay:
          type: boolean
          default: false
          title: Connect Via Relay
          description: >-
            Reach this target through a **relay bridge** running inside your own
            network instead of dialling `endpoint` from Enkrypt's cloud. Use it
            when the system under test has no inbound network exposure - the
            bridge holds one outbound WebSocket to Enkrypt, and every request
            travels down that socket to your intranet LLM. See `GET
            /redteam/relay/v1/relay/bridge`.


            This flag is the only switch; there is no `provider: "relay"`, and
            this flag stays at the **root** of `target` - it is not nested under
            `metadata`. When it is `true`, `metadata.relay` is required and a
            `422` naming it is returned otherwise, and three of the other fields
            change meaning:


            - `endpoint` is still required by the schema but becomes a **label
            only** - nothing in the cloud ever dials it, and it is exempt from
            the usual SSRF pre-check because a private address is the whole
            point.

            - `api_key` is still required but may be the empty string. The
            bridge, not Enkrypt, authenticates to your LLM - put those
            credentials in `metadata.relay.target_headers`, never here.

            - `provider` has no runtime effect. The relay wire is OpenAI-shaped
            end to end, so an OpenAI-compatible client is always used;
            `provider` survives only as a label on dashboards and audit logs.
            Translation to a non-OpenAI local LLM belongs in the bridge's hooks
            module.


            A relay target cannot be health-probed. `POST /rt/model-health`
            dials `endpoint` directly, so it always reports unhealthy for a
            relay target however healthy the bridge is - use `GET
            /redteam/relay/v1/relay/bridges/{bridge_id}/status` instead.
          example: true
        metadata:
          properties:
            relay:
              $ref: '#/components/schemas/RTv2RelayConfig'
              nullable: true
              title: Relay
          additionalProperties: false
          type: object
          nullable: true
          title: Metadata
          description: >-
            The canonical home for relay routing on an inline target:
            `target.metadata.relay` names which bridge to route through and what
            it should call. Required when `connect_via_relay` is `true`, and
            meaningless without it.


            **This object is not free-form.** `relay` is the only key it
            accepts; any other - `metadata.tenant_id`, `metadata.aws_region`,
            provider-specific metadata in general - is a `422`. The Red Team
            target cannot express provider metadata, and accepting it silently
            would let a run attack a differently-configured target and report
            success on it. Use the Archived Red Team API for a target that needs
            provider metadata.


            `metadata.relay` is the spelling used everywhere else in the chain -
            a saved model stores `model_config.metadata.relay`, and it is what
            the gateway fills in when it resolves a saved model for the
            `/rt/model/*` endpoints.
        relay:
          $ref: '#/components/schemas/RTv2RelayConfig'
          nullable: true
          title: Relay
          description: >-
            The older accepted spelling of `metadata.relay`, kept working for
            clients that already send it. Prefer `target.metadata.relay` in new
            integrations.


            Sending both is fine when they carry the same block. If
            `target.relay` and `target.metadata.relay` **disagree**, the request
            is rejected with a `422` naming the conflict rather than one of them
            being picked silently.
      additionalProperties: false
      type: object
      required:
        - endpoint
        - api_key
        - model_name
      title: ModelConfig
    LeaderboardGatewayErrorResponse:
      title: LeaderboardGatewayErrorResponse
      type: object
      description: >-
        Error envelope returned by the gateway for leaderboard requests it
        refuses before they reach the service.
      properties:
        code:
          type: integer
          example: 403
        error:
          type: string
          example: Forbidden
        message:
          type: string
          example: >-
            The private leaderboard is restricted to anaconda.com and
            enkryptai.com accounts. To have a model added to the public
            leaderboard, please contact dkumar@anaconda.com.
        request_id:
          type: string
        time:
          type: number
    RTv2ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    RTv2SystemType:
      type: string
      enum:
        - foundation_model
        - chatbot
        - agent
      title: SystemType
    RTv2Modality:
      type: string
      enum:
        - text
        - image
        - audio
        - video
      title: Modality
      description: |-
        Input/output modality.

        Aligned with the V2 ``Modality`` enum in ``redteamV2/ux_and_api.md``.
        ``VIDEO`` is reserved; not supported in V2 MVP.
    RTv2ToolSpec:
      properties:
        name:
          title: Name
          type: string
        description:
          type: string
          nullable: true
          title: Description
        parameters:
          additionalProperties: true
          type: object
          nullable: true
          title: Parameters
      additionalProperties: false
      type: object
      required:
        - name
      title: ToolSpec
    RTv2RelayConfig:
      properties:
        bridge_id:
          type: string
          title: Bridge Id
          description: >-
            Which of your connected bridges to route this run through. Must
            equal the id that bridge registered with (`RELAY_BRIDGE_ID` on the
            SDK bridge). Bridge ids are scoped to your own account, so they only
            have to be unique within it. Check the bridge is up first with `GET
            /redteam/relay/v1/relay/bridges/{bridge_id}/status`.
          example: customer-bridge-1
        target_endpoint:
          type: string
          title: Target Endpoint
          description: >-
            The full URL **inside your own network** that the bridge will POST
            to. This is the address that is actually called; the target's own
            `endpoint` is only a label. It is resolved on your side of the
            connection, so a private hostname or RFC1918 address is expected
            here.
          example: https://customer-internal-llm.local/v1/chat/completions
        model_name:
          type: string
          title: Model Name
          description: >-
            The model identifier **your own LLM** expects, which need not be the
            name the run is labelled with. This value wins over the target's
            top-level `model_name` when the request is sent to your endpoint.
          example: their-internal-model
        target_headers:
          additionalProperties:
            type: string
          type: object
          title: Target Headers
          description: >-
            Headers forwarded verbatim to your LLM by the bridge. This is where
            credentials for your own endpoint belong - the target's `api_key` is
            not used on a relay run and may be left empty. Omit the object
            entirely rather than sending `{}`.
          example:
            Authorization: Bearer customer-side-internal-key
      additionalProperties: false
      type: object
      required:
        - bridge_id
        - target_endpoint
        - model_name
      title: RelayConfig
      description: >-
        Routing for a target reached through a **relay bridge**. Set on
        `target.metadata.relay` (or on `target.relay`, the older accepted
        spelling), and only meaningful alongside `target.connect_via_relay:
        true` - which stays at the root of the target, not under `metadata`.


        Unknown keys are rejected with a `422`. In particular there is no relay
        endpoint, relay token, timeout or offline-grace setting to configure
        here: the relay address is fixed infrastructure and the timeouts are
        server-side.
  responses:
    RTv2LeaderboardForbidden:
      description: >-
        Forbidden — this endpoint is internal to Enkrypt AI and Anaconda, and
        the calling key is neither an `@enkryptai.com` nor an `@anaconda.com`
        account. To have a model added to the public leaderboard, contact
        dkumar@anaconda.com.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/LeaderboardGatewayErrorResponse'
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: apikey

````