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

# Revoke an MCP Connection

> Destroy one person's stored upstream tokens for a delegated-OAuth MCP server.

The stored refresh and access tokens are **destroyed**, not flagged: the table
refuses a revoked row that still holds ciphertext. That person's next tool call
on this server is refused until they connect again.

This does **not** revoke KnoxCall's authorization at the upstream. If you need it
gone there too, remove the app in the upstream's own account settings — only the
account holder, or that provider's admin, can do that.

Requires the `delete` capability on `ai_gateway`. See the [control-plane overview](/api-reference/ai-gateway/control-plane-overview#authentication) for authentication, the `{data, meta}` envelope and error types.


## OpenAPI

````yaml DELETE /ai-gateway/mcp-servers/{id}/grants/{grantId}
openapi: 3.1.0
info:
  title: KnoxCall Client Management API
  version: '1.0'
  description: >
    The KnoxCall Client Management API provides programmatic access to manage
    your API gateway

    resources including routes, secrets, clients, environments, webhooks, and
    API keys.


    ## Authentication


    All requests must include an OAuth 2.1 access token **or** a legacy API key.
    The

    recommended path for new integrations is the first-party SDKs, which mint,
    cache, and

    refresh OAuth tokens for you (start with `knoxcall login` on a developer
    machine, or

    `KNOXCALL_CLIENT_ID` / `KNOXCALL_CLIENT_SECRET` in CI). You can authenticate
    using any of:


    - **Authorization header (OAuth 2.1 bearer token — recommended)**:
    `Authorization: Bearer <access_token>`

    - **Authorization header (legacy API key)**: `Authorization: Bearer
    tk_xxx_yyy`

    - **x-api-key header (legacy API key)**: `x-api-key: tk_xxx_yyy`


    OAuth 2.1 access tokens (`kc_` prefix) are minted at the root-host token
    endpoint

    `https://api.knoxcall.com/oauth/token` (not under `/v1`) using the
    `client_credentials`

    or `authorization_code` grant. See the `OAuth2` security scheme and the
    `/oauth/*`

    endpoints. Some resources that are managed exclusively through OAuth reject
    API-key auth

    with a `403 use_oauth` error.


    Long-lived API keys remain fully supported. They come in three types:

    - **Standard keys** (`tk_` prefix) are used on the production API
    (`api.knoxcall.com`).

    - **Test keys** (`tk_` prefix, type=test) are used on the sandbox API
    (`sandbox.knoxcall.com`).

    - **Enterprise Access Keys** (`AKE` prefix) follow the format
    `AKE[16chars]:[40chars]`.


    Using a test key on the production API (or vice versa) will return a `403
    wrong_key_type` error.


    ## Request IDs


    Every response — success or error — includes an `X-Request-Id` response
    header (a UUID).

    Its value is identical to the `request_id` field in the response body
    (`meta.request_id`

    on success, `error.request_id` on error). Quote it when contacting support.


    ## API Versioning


    The API is versioned on two axes:


    - **Major version — the `/v1` path prefix.** Breaking changes ship under a
    new major
      (`/v2`). `/v1` never receives a breaking change.
    - **Minor version — the `KnoxCall-Version` header (dated, `YYYY-MM-DD`).**
    Send
      `KnoxCall-Version: 2026-08-05` to pin the behaviour of a specific dated release. Omit
      the header to get the newest minor version. Every response echoes the resolved version
      back in a `KnoxCall-Version` response header.

    Within a major version, **additive changes are not breaking** and may appear
    without a new

    dated version: new endpoints, new optional request fields, new response
    fields, new

    `error.type` values, and new enum members. Clients must tolerate unknown
    response fields

    and unknown `error.type` values (see the `ErrorResponse` schema).


    An **unknown or malformed** `KnoxCall-Version` value returns `400` with

    `error.type: invalid_api_version`.


    ## Rate Limiting


    API keys can have optional rate limits configured. When a limit is
    configured, the

    following headers are emitted on **every** response (not only `429`s):

    - `X-RateLimit-Limit` -- maximum requests allowed per window

    - `X-RateLimit-Remaining` -- remaining requests in the current window

    - `X-RateLimit-Reset` -- epoch seconds at which the window resets


    When the limit is exceeded the API returns `429` (`rate_limit_exceeded` /
    `rate_limited`)

    and additionally sets `Retry-After` (seconds until the window resets).


    ## Idempotency


    All mutating requests (`POST`/`PUT`/`PATCH`/`DELETE`) accept an idempotency
    key so a

    retried request is executed at most once. Supply it as `X-Idempotency-Key`

    (the standard `Idempotency-Key` spelling is also accepted), max 255
    characters.


    - Replaying a completed request with the same key returns the original
    stored response,
      annotated with an `X-Idempotent-Replay: true` response header.
    - A key that is still being processed returns `409 request_in_progress`.

    - Re-using a key with a **different** request body returns `422
    idempotency_key_reuse`.

    - A malformed key returns `400 invalid_idempotency_key`.


    ## Pagination


    List endpoints support pagination with the following query parameters:

    - `page` -- page number (default: 1)

    - `per_page` -- items per page (default: 20, max: 100)

    - `sort` -- field to sort by (varies per endpoint)

    - `order` -- sort direction: `asc` or `desc`


    Paginated responses include a `meta` object with `total`, `page`,
    `per_page`, and `total_pages`.


    ### Offset ceiling


    The server derives its SQL offset as `(page - 1) * per_page` and will not

    exceed 100,000 rows, so `page` is clamped to `floor(100000 / per_page) + 1`

    (1,001 at the maximum `per_page` of 100). Two consequences:


    - `meta.page` echoes the **effective** page, which may be lower than the one
      you asked for. It always matches the rows returned.
    - `meta.total_pages` is capped at that same page, so it is
      `min(ceil(total / per_page), floor(100000 / per_page) + 1)`. A pager that
      walks until `page >= total_pages` therefore terminates.

    `meta.total` still reports the true row count. If `total` exceeds

    `total_pages * per_page` you are being truncated by the ceiling -- narrow

    the result set with a filter (date range, status, resource id) instead of

    paging deeper.


    ## Error Handling


    All errors follow one canonical shape everywhere on `/v1`:

    `{"error": {"type", "message", "request_id"}}`. The `type` field is a
    machine-readable

    category (see the `ErrorResponse` schema for the full enum). Request-body
    validation

    failures are always `400 validation_error`; the one `422` case is
    `idempotency_key_reuse`.
  contact:
    name: KnoxCall Support
    url: https://knoxcall.com
    email: support@knoxcall.com
  license:
    name: Proprietary
    url: https://knoxcall.com/terms
servers:
  - url: https://api.knoxcall.com/v1
    description: Production
  - url: https://sandbox.knoxcall.com/v1
    description: Sandbox (test keys only)
security:
  - OAuth2: []
  - BearerAuth: []
  - ApiKeyAuth: []
tags:
  - name: Routes
    description: Manage proxy routes that forward API requests to upstream targets.
  - name: Secrets
    description: Manage encrypted secrets injected into route headers and bodies.
  - name: Clients
    description: Manage authorized clients (users or servers) with IP-based access control.
  - name: Environments
    description: >-
      Manage deployment environments (e.g. production, staging) for route
      configuration overrides.
  - name: API Keys
    description: Create and revoke API keys for programmatic access.
  - name: Webhooks
    description: Manage webhook subscriptions for real-time event notifications.
  - name: Account
    description: Retrieve account information and usage metrics.
  - name: Audit Logs
    description: Query the immutable audit trail of all API actions.
  - name: Signup
    description: >-
      Headless account creation — the only unauthenticated endpoint, designed so
      scripts and AI agents can onboard without a browser.
  - name: OAuth Clients
    description: Manage OAuth 2.1 clients used to mint access tokens for the API.
  - name: Agents
    description: Manage BYO server agents (self-hosted data-plane / tunnel agents).
  - name: Crypto Keys
    description: >-
      Transit encryption keys — encrypt, decrypt, rewrap, sign, verify, and
      issue JWTs without key material ever leaving KnoxCall.
  - name: Encryption
    description: >-
      Portable structure-preserving encryption — encrypt any JSON into storable
      `kc:` ciphertext strings and decrypt them later.
  - name: Client Tokens
    description: >-
      Single-use client-side capability tokens (`kct_` prefix) that let a
      browser exchange one bound ciphertext or vault token for its plaintext.
  - name: PKI
    description: >-
      Private certificate authority — roots, issuing roles, leaf certificates,
      revocation, and CRLs.
  - name: Dynamic DB Credentials
    description: >-
      Just-in-time database credentials — register connections and roles, then
      mint short-lived leased users on demand.
  - name: Vaults
    description: >-
      Data tokenization vaults — swap sensitive values for format-preserving
      tokens and detokenize them under audit.
  - name: Ephemeral Proxy
    description: >-
      One-shot proxy that resolves vault-token template expressions on the wire
      — no pre-configured route required.
  - name: Wrap Credentials
    description: >-
      Escrow a third-party provider key into KnoxCall custody so it leaves your
      codebase, host-pinned; the ephemeral proxy injects it under
      X-Knox-Upstream-Auth-Secret.
  - name: Opportunities
    description: >-
      Suggestions to turn detected outbound API usage (agent-observed or
      gateway-traffic) into a durable route; accept promotes to a route + secret
      binding.
  - name: Workflows
    description: >-
      Create, manage, and run workflows. Executions are asynchronous; poll
      executions or subscribe a webhook to workflow.execution.completed|failed.
  - name: AI Gateway
    description: >-
      Manage AI egress gateways, their agents, and capability (phantom) tokens,
      plus cost/token spend rollups and FinOps exports.
paths:
  /ai-gateway/mcp-servers/{id}/grants/{grantId}:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The MCP server UUID.
      - name: grantId
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The connection UUID.
    delete:
      tags:
        - AI Gateway
      summary: Revoke one person's delegated-OAuth connection
      description: |
        The stored refresh and access tokens are destroyed. Revoking here does
        not revoke KnoxCall's authorization at the upstream — do that in the
        upstream's own account settings if you need it gone there too.
      operationId: revokeAiGatewayMcpGrant
      responses:
        '200':
          description: The revoked connection id.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      status:
                        type: string
                        enum:
                          - revoked
                  meta:
                    $ref: '#/components/schemas/RequestMeta'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    RequestMeta:
      type: object
      description: Metadata included with every API response.
      properties:
        request_id:
          type: string
          format: uuid
          description: >-
            Unique identifier for this API request, useful for support and
            debugging.
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - request_id
    ErrorResponse:
      type: object
      description: Standard error response envelope.
      properties:
        error:
          type: object
          properties:
            type:
              type: string
              description: >-
                Machine-readable error type. The set is OPEN — endpoints define
                specific types beyond the common ones below, so clients should
                branch on the types they know and fall back to the HTTP status
                class for anything unrecognized. Common values:
                authentication_required, invalid_api_key, wrong_key_type,
                subscription_inactive, rate_limit_exceeded, validation_error,
                forbidden, not_found, conflict, in_use, plan_limit,
                plan_feature, internal_error, invalid_request,
                invalid_definition, not_cancellable, invalid_idempotency_key,
                idempotency_key_reuse, request_in_progress,
                system_client_protected, use_oauth.
              example: validation_error
            message:
              type: string
              description: Human-readable error message.
              example: name and target_base_url are required.
            request_id:
              type: string
              format: uuid
              description: Unique identifier for this request.
              example: 550e8400-e29b-41d4-a716-446655440000
          required:
            - type
            - message
            - request_id
      required:
        - error
  responses:
    Unauthorized:
      description: Authentication is required or the provided API key is invalid.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        KnoxCall-Version:
          $ref: '#/components/headers/KnoxCall-Version'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            missing_key:
              summary: No API key provided
              value:
                error:
                  type: authentication_required
                  message: >-
                    API key is required. Use Authorization: Bearer <api_key> or
                    x-api-key header.
                  request_id: 550e8400-e29b-41d4-a716-446655440000
            invalid_key:
              summary: Invalid API key
              value:
                error:
                  type: invalid_api_key
                  message: Invalid API key.
                  request_id: 550e8400-e29b-41d4-a716-446655440000
    Forbidden:
      description: >
        The key is authenticated but not authorized for this action (missing
        scope), a plan

        limit was reached, or the resource must be managed via OAuth
        (`use_oauth`) / is a

        protected system client (`system_client_protected`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        KnoxCall-Version:
          $ref: '#/components/headers/KnoxCall-Version'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            forbidden:
              summary: Missing scope
              value:
                error:
                  type: forbidden
                  message: This key is not authorized to list AI gateways.
                  request_id: 550e8400-e29b-41d4-a716-446655440000
            use_oauth:
              summary: Resource is OAuth-only
              value:
                error:
                  type: use_oauth
                  message: >-
                    This resource must be managed with an OAuth 2.1 access
                    token.
                  request_id: 550e8400-e29b-41d4-a716-446655440000
            system_client_protected:
              summary: Protected system client
              value:
                error:
                  type: system_client_protected
                  message: >-
                    This client is managed by the platform and cannot be
                    modified.
                  request_id: 550e8400-e29b-41d4-a716-446655440000
    NotFound:
      description: The requested resource was not found.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        KnoxCall-Version:
          $ref: '#/components/headers/KnoxCall-Version'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: not_found
              message: Route not found.
              request_id: 550e8400-e29b-41d4-a716-446655440000
    InternalError:
      description: An unexpected server error occurred.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        KnoxCall-Version:
          $ref: '#/components/headers/KnoxCall-Version'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: internal_error
              message: An unexpected error occurred.
              request_id: 550e8400-e29b-41d4-a716-446655440000
  headers:
    X-Request-Id:
      description: >
        Unique identifier for this request (UUID). Present on **every** response
        and equal

        to the `request_id` field in the response body. Quote it when contacting
        support.
      schema:
        type: string
        format: uuid
      example: 550e8400-e29b-41d4-a716-446655440000
    KnoxCall-Version:
      description: >
        The dated API version (`YYYY-MM-DD`) that served this response. Equals
        the value

        of the `KnoxCall-Version` request header when supplied, otherwise the
        newest version.
      schema:
        type: string
        pattern: ^\d{4}-\d{2}-\d{2}$
      example: '2026-08-05T00:00:00.000Z'
  securitySchemes:
    OAuth2:
      type: oauth2
      description: >
        OAuth 2.1 authentication — recommended for new integrations. Access
        tokens

        (`kc_` prefix) are minted at the root-host token endpoint

        `https://api.knoxcall.com/oauth/token` and passed as `Authorization:
        Bearer <access_token>`.

        Public clients must use PKCE with the `authorization_code` grant;
        confidential

        clients may use `client_credentials`. The first-party SDKs and the

        `knoxcall login` CLI handle token minting, caching, refresh, and DPoP
        for you.
      flows:
        clientCredentials:
          tokenUrl: https://api.knoxcall.com/oauth/token
          refreshUrl: https://api.knoxcall.com/oauth/token
          scopes:
            routes:read: Read routes.
            routes:write: Create, update, and delete routes.
            secrets:read: >-
              Read secret metadata. Does NOT include retrieving a live OAuth2
              access token.
            secrets:oauth_token: >-
              Retrieve a live upstream OAuth2 access token (GET
              /v1/secrets/{id}/oauth2/token). Distinct from secrets:read because
              the call refreshes the credential at the provider.
            secrets:write: Create, update, and delete secrets.
            vaults:detokenize: >-
              Turn a vault token back into its original value. Required by GET
              /v1/vaults/{vault}/tokens/{token}, by a token template reference
              in a /v1/proxy body, and by creating a `detokenize` route action.
              Distinct from vaults:read, which lists vaults and token metadata
              and never returns a value.
            transit:decrypt: >-
              Open a portable `kc:` ciphertext with a tenant transit key.
              Required by creating a `decrypt` route action, which stores a
              standing instruction to open every matching field on every later
              request through that route. It is the same capability name the
              policy engine uses for POST /v1/decrypt. No routes scope satisfies
              it — managing a route is not permission to open the data flowing
              through it.
            proxy:invoke: >-
              Call the one-shot ephemeral proxy (any method on /v1/proxy).
              Required for EVERY verb — the proxy is one capability behind one
              handler, and a bodyless GET spends an escrowed credential exactly
              as a POST does. Neither proxy:read nor proxy:write satisfies it.
            clients:read: Read clients.
            clients:write: Manage clients.
            webhooks:write: Manage webhooks.
            workflows:write: Manage and execute workflows.
            '*:*': Full access (all scopes).
        authorizationCode:
          authorizationUrl: https://api.knoxcall.com/oauth/authorize
          tokenUrl: https://api.knoxcall.com/oauth/token
          refreshUrl: https://api.knoxcall.com/oauth/token
          scopes:
            routes:read: Read routes.
            routes:write: Create, update, and delete routes.
            secrets:read: >-
              Read secret metadata. Does NOT include retrieving a live OAuth2
              access token.
            secrets:oauth_token: >-
              Retrieve a live upstream OAuth2 access token (GET
              /v1/secrets/{id}/oauth2/token). Distinct from secrets:read because
              the call refreshes the credential at the provider.
            secrets:write: Create, update, and delete secrets.
            vaults:detokenize: >-
              Turn a vault token back into its original value. Required by GET
              /v1/vaults/{vault}/tokens/{token}, by a token template reference
              in a /v1/proxy body, and by creating a `detokenize` route action.
              Distinct from vaults:read, which lists vaults and token metadata
              and never returns a value.
            transit:decrypt: >-
              Open a portable `kc:` ciphertext with a tenant transit key.
              Required by creating a `decrypt` route action, which stores a
              standing instruction to open every matching field on every later
              request through that route. It is the same capability name the
              policy engine uses for POST /v1/decrypt. No routes scope satisfies
              it — managing a route is not permission to open the data flowing
              through it.
            proxy:invoke: >-
              Call the one-shot ephemeral proxy (any method on /v1/proxy).
              Required for EVERY verb — the proxy is one capability behind one
              handler, and a bodyless GET spends an escrowed credential exactly
              as a POST does. Neither proxy:read nor proxy:write satisfies it.
            clients:read: Read clients.
            clients:write: Manage clients.
            webhooks:write: Manage webhooks.
            workflows:write: Manage and execute workflows.
            '*:*': Full access (all scopes).
    BearerAuth:
      type: http
      scheme: bearer
      description: >
        Legacy long-lived API key authentication via the Authorization header.

        Pass your API key as: `Authorization: Bearer tk_xxx_yyy`.


        Standard keys (`tk_` prefix) are accepted on `api.knoxcall.com`.

        Test keys (type=test) are accepted on `sandbox.knoxcall.com`.

        Enterprise Access Keys (`AKE` prefix) are accepted on both.


        Fully supported, but prefer the `OAuth2` scheme (or the SDKs, which
        handle

        OAuth for you) for new integrations.
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >
        Legacy API key authentication via the `x-api-key` header.

        This is an alternative to Bearer token authentication for clients that
        cannot

        set the `Authorization` header. Prefer the `OAuth2` scheme for new
        integrations.

````