> ## 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 Jailbreak Benchmark

> Run Enkrypt AI's fixed **jailbreak benchmark** against a target, as an ordinary Red Team run.

The recipe is **fixed server-side**: a 60-prompt jailbreak corpus (`jailbreak_bench`) attacked with a set mix of methods chosen from the target's modalities. The dataset, the attack parameters and the evaluation are not caller-configurable, so the body takes only `target`, `run_name` and `user_metadata` - sending `risk_categories`, `compliance_frameworks`, `attack_config`, `generation_config`, `context` or any other key returns `422`.

| Target modalities | Attacks run |
|---|---|
| text in, text out | 10 encoding transforms - `upside_down`, `atbash`, `base32`, `caesar`, `pig_latin`, `zalgo`, `code_switching`, `base64`, `zero_width`, `homoglyph`, each applied once per prompt (600 encoding attempts) - plus ARTA (`rt_agent_v2`) and GOAT (`goat`) |
| text + image in, text out | everything above, plus HADES-AT (`hades_at`) and CAMO (`camo`) |

Any other combination of `target.input_modalities` / `target.output_modalities` is rejected with `422`.

There is no `context` field, so a Code of Conduct policy cannot be passed in the body; name it in the `X-Enkrypt-Policy` header instead. You do **not** send a user id either - the gateway identifies the run owner from your API key.

As on `POST /rt/redteam`, the target is health-checked before the run is queued (`400` if it does not answer), and a submission your remaining Red Team credits cannot cover returns `402`. The price is flat per modality class - see [Credits and Usage](/resources/credits).

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



## OpenAPI

````yaml POST /rt/redteam/jailbreak
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.
  - name: Compliance
    description: >-
      Compliance APIs: connect a ChatGPT Enterprise workspace, then keep reading
      its compliance logs and scanning every message through one of your saved
      guardrails.


      Every endpoint here — reads as well as writes — requires the **governance
      officer** role on the project your API key belongs to. The organization
      owner is **not** exempt: an owner who has not been granted the role gets
      `403` like anyone else. An individual (non-organization) account cannot
      hold the role at all, so compliance is an organization-only feature today.


      A scan is addressed by name in the `X-Enkrypt-Scan` header, within the
      project its API key belongs to. Message text is never stored: Get
      Compliance Message fetches it live from the provider, and only while the
      provider still holds it.
paths:
  /rt/redteam/jailbreak:
    post:
      tags:
        - Redteam
      summary: Run Jailbreak Benchmark
      description: >-
        Run Enkrypt AI's fixed **jailbreak benchmark** against a target, as an
        ordinary Red Team run.


        The recipe is **fixed server-side**: a 60-prompt jailbreak corpus
        (`jailbreak_bench`) attacked with a set mix of methods chosen from the
        target's modalities. The dataset, the attack parameters and the
        evaluation are not caller-configurable, so the body takes only `target`,
        `run_name` and `user_metadata` - sending `risk_categories`,
        `compliance_frameworks`, `attack_config`, `generation_config`, `context`
        or any other key returns `422`.


        | Target modalities | Attacks run |

        |---|---|

        | text in, text out | 10 encoding transforms - `upside_down`, `atbash`,
        `base32`, `caesar`, `pig_latin`, `zalgo`, `code_switching`, `base64`,
        `zero_width`, `homoglyph`, each applied once per prompt (600 encoding
        attempts) - plus ARTA (`rt_agent_v2`) and GOAT (`goat`) |

        | text + image in, text out | everything above, plus HADES-AT
        (`hades_at`) and CAMO (`camo`) |


        Any other combination of `target.input_modalities` /
        `target.output_modalities` is rejected with `422`.


        There is no `context` field, so a Code of Conduct policy cannot be
        passed in the body; name it in the `X-Enkrypt-Policy` header instead.
        You do **not** send a user id either - the gateway identifies the run
        owner from your API key.


        As on `POST /rt/redteam`, the target is health-checked before the run is
        queued (`400` if it does not answer), and a submission your remaining
        Red Team credits cannot cover returns `402`. The price is flat per
        modality class - see [Credits and Usage](/resources/credits).


        Everything after submission is the ordinary Red Team v2 flow: a `202`
        carrying a `run_id` (prefixed `rt-`), then `GET /rt/runs/{run_id}`,
        `.../results`, `.../records` and `.../stream`, and `POST
        /rt/runs/{run_id}/resume`, as for any run.
      operationId: run_jailbreak_v1_redteam_jailbreak_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. The benchmark's prompts and
              scoring are fixed, so the policy does not change what is tested.
            example: customer-support-coc
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RTv2JailbreakRequest'
            example:
              target:
                endpoint: https://api.openai.com/v1
                provider: openai_compatible
                api_key: YOUR_TARGET_API_KEY
                model_name: gpt-4o-mini
                input_modalities:
                  - text
                output_modalities:
                  - text
        required: true
      responses:
        '202':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RTv2RunQueuedResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RTv2HTTPValidationError'
components:
  schemas:
    RTv2JailbreakRequest:
      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: RTv2JailbreakRequest
      description: >-
        `POST /v1/redteam/jailbreak` payload.


        Fixed recipe: the jailbreak corpus, the attacks and the evaluation are
        server-owned, so `target` is the only thing to configure. The target
        must be text in and text out, or text + image in and text out.
    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
    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.
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: apikey

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.