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

# Test Compliance Connection

> Probes a provider compliance key and a workspace **before any scan exists**: whether the key works, whether the workspace was found, which event types that workspace can actually serve, and — when you send `proposed_cursor` — how much history a backfill from that time would pull.

Read-only on both sides. **Nothing is stored, including the key**, so Add Compliance Scan has to carry it again.

A rejected key is **not** an HTTP error: the call returns `200` with `key_valid: false`. Check the fields, not the status code.

Listing a 30-day window is the slowest call in this API; allow up to a minute for it.

Requires the **governance officer** role on the project your API key belongs to. The organization owner is not exempt — an owner without the role gets `403` — and an individual (non-organization) account cannot hold the role at all.



## OpenAPI

````yaml POST /compliance/test-connection
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:
  /compliance/test-connection:
    post:
      tags:
        - Compliance
      summary: Test Compliance Connection
      description: >-
        Probes a provider compliance key and a workspace **before any scan
        exists**: whether the key works, whether the workspace was found, which
        event types that workspace can actually serve, and — when you send
        `proposed_cursor` — how much history a backfill from that time would
        pull.


        Read-only on both sides. **Nothing is stored, including the key**, so
        Add Compliance Scan has to carry it again.


        A rejected key is **not** an HTTP error: the call returns `200` with
        `key_valid: false`. Check the fields, not the status code.


        Listing a 30-day window is the slowest call in this API; allow up to a
        minute for it.


        Requires the **governance officer** role on the project your API key
        belongs to. The organization owner is not exempt — an owner without the
        role gets `403` — and an individual (non-organization) account cannot
        hold the role at all.
      operationId: compliance_test_connection
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ComplianceTestConnectionRequest'
            examples:
              probe-with-backfill-estimate:
                summary: Probe a workspace and estimate the backfill
                value:
                  compliance_api_key: YOUR_PROVIDER_COMPLIANCE_KEY
                  workspace_id: 00000000-0000-0000-0000-000000000000
                  event_types:
                    - CONVERSATION_MESSAGE
                    - CODEX_LOG
                  proposed_cursor: '2026-09-01T00:00:00Z'
              key-and-workspace-only:
                summary: Just check the key and the workspace
                value:
                  compliance_api_key: YOUR_PROVIDER_COMPLIANCE_KEY
                  workspace_id: 00000000-0000-0000-0000-000000000000
      responses:
        '200':
          description: >-
            The probe ran. `key_valid` and `workspace_found` say whether the
            credentials worked — a rejected key is reported here, not as a 4xx.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ComplianceTestConnectionResponse'
              examples:
                working:
                  summary: Key works, one event type unavailable
                  value:
                    key_valid: true
                    workspace_found: true
                    event_types:
                      - event_type: CONVERSATION_MESSAGE
                        supported: true
                      - event_type: CODEX_LOG
                        supported: false
                        status: 400
                        error: not available for this workspace
                    backfill:
                      since: '2026-09-01T00:00:00Z'
                      files: 42
                      bytes: 187654321
                      by_event_type:
                        CONVERSATION_MESSAGE:
                          files: 42
                          bytes: 187654321
                      truncated: false
                rejected-key:
                  summary: The provider rejected the key (still HTTP 200)
                  value:
                    key_valid: false
                    workspace_found: false
                    error: The provider rejected the compliance key
        '400':
          $ref: '#/components/responses/ComplianceBadRequest'
        '401':
          $ref: '#/components/responses/ComplianceUnauthorized'
        '403':
          $ref: '#/components/responses/ComplianceForbidden'
        '500':
          $ref: '#/components/responses/ComplianceServerError'
        '503':
          $ref: '#/components/responses/ComplianceServiceUnavailable'
components:
  schemas:
    ComplianceTestConnectionRequest:
      title: ComplianceTestConnectionRequest
      type: object
      required:
        - compliance_api_key
        - workspace_id
      description: >-
        Body of Test Compliance Connection. Nothing here is stored, including
        the key.
      properties:
        compliance_api_key:
          type: string
          format: password
          writeOnly: true
          description: The provider's compliance API key to probe.
        workspace_id:
          type: string
          format: uuid
          description: The **ChatGPT workspace UUID**, not an OpenAI organization id.
        event_types:
          type: array
          items:
            type: string
            enum:
              - CONVERSATION_MESSAGE
              - CODEX_LOG
              - APP_LOG
              - CUSTOM_AGENTS_LOG
              - CHATGPT_PLUGIN_SPREADSHEET
          description: >-
            Which services to probe. Omit to let the service choose what to
            check.
        proposed_cursor:
          type: string
          format: date-time
          description: >-
            A start time you are considering. Supplying it makes the response
            carry a `backfill` estimate for the history since then.
        max_pages:
          type: integer
          minimum: 1
          maximum: 50
          default: 10
          description: >-
            How many pages of the provider's file listing to walk while
            estimating. Higher is slower but less likely to come back
            `truncated`.
    ComplianceTestConnectionResponse:
      title: ComplianceTestConnectionResponse
      type: object
      description: >-
        Result of the probe. A rejected key is reported here with `key_valid:
        false` and HTTP `200`, not as a 4xx.
      properties:
        key_valid:
          type: boolean
          description: Whether the provider accepted the key.
        workspace_found:
          type: boolean
          description: >-
            Whether that workspace was found. A false here with a valid key
            usually means an organization id was sent instead of a workspace id.
        event_types:
          type: array
          items:
            $ref: '#/components/schemas/ComplianceEventTypeProbe'
          description: One entry per probed service.
        backfill:
          allOf:
            - $ref: '#/components/schemas/ComplianceBackfillEstimate'
          nullable: true
          description: Present only when `proposed_cursor` was sent.
        error:
          type: string
          nullable: true
          description: Why the probe failed, when it did.
    ComplianceEventTypeProbe:
      title: ComplianceEventTypeProbe
      type: object
      description: >-
        Whether one event type is available for this workspace. The provider
        answers "not this one" with a `400` on its listing endpoint, which is
        reported here as `supported: false`.
      properties:
        event_type:
          type: string
        supported:
          type: boolean
        status:
          type: integer
          nullable: true
          description: The provider's status code, when it gave one.
        error:
          type: string
          nullable: true
    ComplianceBackfillEstimate:
      title: ComplianceBackfillEstimate
      type: object
      description: >-
        How much history a scan starting at `proposed_cursor` would pull. Volume
        varies by orders of magnitude between workspaces — quote this before
        committing to a start time.
      properties:
        since:
          type: string
          format: date-time
          description: The proposed start time this estimate is for.
        files:
          type: integer
          description: Export files found since then.
        bytes:
          type: integer
          description: Total size of those files.
        by_event_type:
          type: object
          additionalProperties:
            type: object
            additionalProperties:
              type: integer
          description: The same counts broken down per event type.
        truncated:
          type: boolean
          description: >-
            True when the listing hit `max_pages` before it ran out of files, so
            the real total is larger.
    ComplianceErrorResponse:
      title: ComplianceErrorResponse
      type: object
      description: Error envelope returned by the compliance APIs.
      properties:
        error:
          type: string
          example: Scan not found
    ComplianceGatewayErrorResponse:
      title: ComplianceGatewayErrorResponse
      type: object
      description: >-
        Error envelope returned by the gateway for a request it refuses before
        it reaches the compliance service — an unknown body field, a value
        outside an enum, a malformed scan name, or a failed permission check.
      properties:
        code:
          type: integer
          example: 403
        error:
          type: string
          example: Forbidden
        message:
          type: string
          example: Access Denied
        request_id:
          type: string
        time:
          type: number
  responses:
    ComplianceBadRequest:
      description: >-
        Bad Request — a malformed or non-JSON body, an unknown or unexpected
        field, a value outside an enum, a missing or malformed `X-Enkrypt-Scan`,
        a missing `event_id`, out-of-range paging, an empty update, or an
        attempt to change `provider` / `workspace_id` / `scan_id`.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ComplianceErrorResponse'
              - $ref: '#/components/schemas/ComplianceGatewayErrorResponse'
    ComplianceUnauthorized:
      description: Unauthorized — missing or invalid `apikey` header.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ComplianceGatewayErrorResponse'
    ComplianceForbidden:
      description: >-
        Forbidden — the caller does not hold the **governance officer** role on
        this project, or the account is an individual (non-organization)
        account, which cannot hold that role. The organization owner is not
        exempt: an owner without the role is refused here too.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ComplianceErrorResponse'
              - $ref: '#/components/schemas/ComplianceGatewayErrorResponse'
    ComplianceServerError:
      description: Internal Server Error.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ComplianceErrorResponse'
              - $ref: '#/components/schemas/ComplianceGatewayErrorResponse'
    ComplianceServiceUnavailable:
      description: >-
        Service Unavailable — the scanning service could not be reached or timed
        out. Calls that only read or write the record are unaffected; only the
        ones that need the service live fail this way.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ComplianceErrorResponse'
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: apikey

````