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

# List Scans

> List scan jobs (source and hosted) ordered by `(created_at DESC, job_id DESC)` with **opaque cursor pagination**. Supports filtering by visibility, status, scan type, repository name, `source_url`, and `source_version`. Use `latest_only=true` to collapse repeated scans of the same `(source_url, source_version)` to the newest row per combo.

## Pagination

```
GET /mcp-hub/scans?limit=20                       # first page
GET /mcp-hub/scans?limit=20&cursor=<next_cursor>  # subsequent pages
```

The response includes `next_cursor` (an opaque base64url string). Pass it back verbatim as the `cursor` query parameter to fetch the next page. When `next_cursor` is `null` you have reached the end of the result set. The cursor is treated as **opaque**; do not decode or construct it manually.

By default `total` is **not** returned. Pass `?include_total=true` to opt in — it costs a separate COUNT(\*) round-trip per request and is intended only for UIs that need a "Showing X of N" counter.

**Enterprise data-license feature:** requires MCP Hub API access enabled for your organization, otherwise returns `403`. Contact support@enkryptai.com.



## OpenAPI

````yaml GET /mcp-hub/scans
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: Datasets
  - name: Redteam
  - 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
paths:
  /mcp-hub/scans:
    get:
      tags:
        - MCP Hub
      summary: List Scans
      description: >-
        List scan jobs (source and hosted) ordered by `(created_at DESC, job_id
        DESC)` with **opaque cursor pagination**. Supports filtering by
        visibility, status, scan type, repository name, `source_url`, and
        `source_version`. Use `latest_only=true` to collapse repeated scans of
        the same `(source_url, source_version)` to the newest row per combo.


        ## Pagination


        ```

        GET /mcp-hub/scans?limit=20                       # first page

        GET /mcp-hub/scans?limit=20&cursor=<next_cursor>  # subsequent pages

        ```


        The response includes `next_cursor` (an opaque base64url string). Pass
        it back verbatim as the `cursor` query parameter to fetch the next page.
        When `next_cursor` is `null` you have reached the end of the result set.
        The cursor is treated as **opaque**; do not decode or construct it
        manually.


        By default `total` is **not** returned. Pass `?include_total=true` to
        opt in — it costs a separate COUNT(\*) round-trip per request and is
        intended only for UIs that need a "Showing X of N" counter.


        **Enterprise data-license feature:** requires MCP Hub API access enabled
        for your organization, otherwise returns `403`. Contact
        support@enkryptai.com.
      operationId: mcp_hub_list_scans
      parameters:
        - in: query
          name: limit
          required: false
          description: Page size (max 200).
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
            example: 50
        - in: query
          name: cursor
          required: false
          description: >-
            Opaque pagination cursor returned by the previous response as
            `next_cursor`. Omit on the first page. Treat as opaque — do not
            decode or construct manually.
          schema:
            type: string
            maxLength: 4096
            example: >-
              eyJjcmVhdGVkX2F0IjoiMjAyNi0wNi0yNVQxMTozMjoxMS4xMjM0NTYrMDA6MDAiLCJqb2JfaWQiOiJhYmMtMTIzIn0
        - in: query
          name: include_total
          required: false
          description: >-
            When `true`, the response includes a `total` count of rows matching
            the filters. Costs an extra COUNT(\*) round-trip per page request;
            omit by default for cursor pagination's constant-time-per-page
            property.
          schema:
            type: boolean
            default: false
        - in: query
          name: is_official
          required: false
          description: >-
            Filter to only official scans (`true`) or only non-official
            (`false`). Omit for both.
          schema:
            type: boolean
        - in: query
          name: is_private
          required: false
          description: >-
            Filter to only private scans (`true`) or only public (`false`). Omit
            for both.
          schema:
            type: boolean
        - in: query
          name: job_status
          required: false
          description: Filter by job status
          schema:
            type: string
            enum:
              - initializing
              - downloading
              - discovering_tools
              - scanning_tools
              - completed
              - failed
              - connecting
              - discovering
              - analyzing
        - in: query
          name: repo_name
          required: false
          description: Case-insensitive substring match on repo / server name
          schema:
            type: string
            maxLength: 500
        - in: query
          name: scan_type
          required: false
          description: '`source` or `hosted`'
          schema:
            type: string
            enum:
              - source
              - hosted
        - in: query
          name: job_id
          required: false
          description: Exact job UUID match
          schema:
            type: string
            format: uuid
        - in: query
          name: source_url
          required: false
          description: Exact match on `source_url`.
          schema:
            type: string
            maxLength: 2000
        - in: query
          name: source_version
          required: false
          description: Exact match on `source_version` (npm version or git commit).
          schema:
            type: string
            maxLength: 200
        - in: query
          name: latest_only
          required: false
          description: >-
            When `true`, applies all other filters first, then dedupes results
            by `(source_url, source_version)`, keeping the newest row per group
            by `created_at`. Pagination applies to the deduped list and `total`
            reflects the deduped count. Intended for `scan_type=source`. Returns
            `400` if the filters would require dedupe over more than 5000
            matching rows.
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: Paginated list of scans
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MCPHubScanListResponse'
        '400':
          description: >-
            `latest_only=true` would require dedupe over more than 5000 matching
            rows. Narrow the filters and retry.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    example: >-
                      latest_only requires fetching more than 5000 rows; please
                      narrow filters (e.g. source_url, scan_type, org_id).
        '401':
          $ref: '#/components/responses/MCPHubUnauthorized'
        '403':
          $ref: '#/components/responses/MCPHubForbiddenNoAccess'
        '422':
          $ref: '#/components/responses/MCPHubValidationError'
components:
  schemas:
    MCPHubScanListResponse:
      title: MCPHubScanListResponse
      type: object
      required:
        - items
        - limit
      description: >-
        Cursor-paginated list of scans. Page by passing the previous response's
        `next_cursor` back as the `cursor` query parameter. When `next_cursor`
        is `null` you have reached the end of the result set.
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/MCPHubScanListItem'
        next_cursor:
          type: string
          nullable: true
          description: >-
            Opaque cursor for the next page, or `null` on the last page. Pass
            back verbatim as `?cursor=...` — treat as opaque.
          example: >-
            eyJjcmVhdGVkX2F0IjoiMjAyNi0wNi0yNVQxMTozMjoxMS4xMjM0NTYrMDA6MDAiLCJqb2JfaWQiOiJhYmMtMTIzIn0
        limit:
          type: integer
          description: The page size used for this response.
        total:
          type: integer
          nullable: true
          description: >-
            Total rows matching the filters. Only populated when the request set
            `?include_total=true`; omitted by default because counting arbitrary
            filtered subsets defeats the point of cursor pagination.
    MCPHubScanListItem:
      title: MCPHubScanListItem
      type: object
      required:
        - job_id
        - job_status
        - user_email
        - created_at
      description: Slim representation of a scan row for the list endpoint.
      properties:
        job_id:
          type: string
        scan_type:
          type: string
          nullable: true
          enum:
            - source
            - hosted
            - null
        job_status:
          type: string
        repo_name:
          type: string
          nullable: true
        user_email:
          type: string
        is_official:
          type: boolean
          nullable: true
        is_private:
          type: boolean
          nullable: true
        org_id:
          type: string
          nullable: true
        user_id:
          type: string
          nullable: true
        project_name:
          type: string
          nullable: true
        registry_name:
          type: string
          nullable: true
        source_url:
          type: string
          nullable: true
          description: Source URL of the scanned package or repository (source scans only).
        source_version:
          type: string
          nullable: true
          description: >-
            Source version or git commit of the scanned source (source scans
            only).
        scan_version:
          type: string
          nullable: true
          description: >-
            Scanner version that produced this row. Multiple rows can share
            `(source_url, source_version)` but differ on `scan_version`; use
            `latest_only=true` to collapse to the newest per group.
        created_at:
          type: string
        completed_at:
          type: string
          nullable: true
        total_vulnerabilities:
          type: integer
          nullable: true
        overall_severity:
          type: string
          nullable: true
    MCPHubAuthErrorResponse:
      title: MCPHubAuthErrorResponse
      type: object
      description: Error envelope returned by the MCP Hub auth/permission failures.
      properties:
        detail:
          type: string
    MCPHubForbiddenResponse:
      title: MCPHubForbiddenResponse
      type: object
      description: >-
        Error envelope returned when the caller's organization lacks MCP Hub API
        access (enterprise data-license feature).
      properties:
        code:
          type: integer
          example: 403
        error:
          type: string
          example: Forbidden
        message:
          type: string
          example: >-
            MCP Hub APIs are an enterprise feature not enabled for your
            organization. Contact us at support@enkryptai.com for access.
        request_id:
          type: string
        time:
          type: number
    MCPHubValidationError:
      title: MCPHubValidationError
      type: object
      description: FastAPI-style validation error response.
      properties:
        detail:
          type: array
          items:
            type: object
            required:
              - loc
              - msg
              - type
            properties:
              loc:
                type: array
                items:
                  oneOf:
                    - type: string
                    - type: integer
              msg:
                type: string
              type:
                type: string
  responses:
    MCPHubUnauthorized:
      description: Unauthorized — missing or invalid Authorization header
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/MCPHubAuthErrorResponse'
    MCPHubForbiddenNoAccess:
      description: >-
        Forbidden — your organization does not have access to the MCP Hub APIs.
        These retrieval/list endpoints are an enterprise data-license feature;
        contact support@enkryptai.com to enable access.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/MCPHubForbiddenResponse'
    MCPHubValidationError:
      description: Validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/MCPHubValidationError'
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: apikey

````