# List issues

`GET /app/issues`

Issues, one per kind of problem and asset, with the asset, assignee, status, severity, reachability and SLA. Filter by status, severity, category, asset, project, reachability or text, and sort. Paged in the body (issues, total, page, limit): 100 by default, at most 500.

Scope: `issues:read`.

## Parameters

- `status` (query, string)
- `severity` (query, string)
- `category` (query, string)
- `assetId` (query, integer)
- `projectId` (query, integer)
- `reachability` (query, string)
- `q` (query, string)
- `sort` (query, string)
- `page` (query, number)
- `limit` (query, number)

## Example

```bash
curl -X GET "https://api.fortwatch.ai/app/issues" \
  -H "Authorization: Bearer $FORTWATCH_API_KEY"
```

## Response 200

The request succeeded.

- `issues` (object[], required)
  - `id` (number, required)
  - `workspaceId` (number, required)
  - `assetId` (number, required)
  - `title` (string, required)
  - `description` (string | null, required)
  - `severity` (string, required)
  - `status` (string, required)
  - `templateId` (string | null, required)
  - `dedupKey` (string, required)
  - `assignedTo` (number | null, required)
  - `resolution` (string | null, required)
  - `resolvedBy` (string | null, required)
  - `resolvedByScanId` (number | null, required)
  - `resolvedByUserId` (number | null, required)
  - `dismissedByUserId` (number | null, required)
  - `category` (string, required)
  - `dueDate` (string (date-time) | null, required)
  - `resolvedAt` (string (date-time) | null, required)
  - `lastReopenedAt` (string (date-time) | null, required)
  - `dismissReason` (string | null, required)
  - `dismissNotes` (string | null, required)
  - `dismissExpiresAt` (string (date-time) | null, required)
  - `firstSeenAt` (string (date-time), required)
  - `lastSeenAt` (string (date-time), required)
  - `lastCheckedAt` (string (date-time) | null, required)
  - `reachability` (string, required)
  - `verificationScanId` (number | null, required)
  - `verificationSkipped` (string | null, required)
  - `createdAt` (string (date-time), required)
  - `updatedAt` (string (date-time), required)
  - `assignee` (object, required)
    - `firstName` (string, required)
    - `lastName` (string, required)
  - `resolvedByUser` (object, required)
    - `firstName` (string, required)
    - `lastName` (string, required)
  - `dismissedByUser` (object, required)
    - `firstName` (string, required)
    - `lastName` (string, required)
  - `asset` (object, required)
    - `id` (number, required)
    - `name` (object | null, required)
    - `value` (string, required)
    - `type` (string, required)
    - `cdnProvider` (object | null, required)
    - `project` (object, required)
  - `findings` (object[], required)
    - `scanner` (string, required)
    - `remediation` (object | null, required)
    - `reference` (object | null, required)
    - `matchedAt` (object | null, required)
    - `scanId` (object | null, required)
    - `name` (string, required)
    - `templateId` (object | null, required)
  - `_count` (object, required)
    - `findings` (number, required)
  - `seenInLatestScan` (boolean, required)
  - `proof` (object | null, required)
  - `reproduce` (object | null, required)
  - `vantage` (object | null, required)
  - `verification` (object, required)
    - `status` (string, required) One of: `queued`, `running`, `done`, `failed`, `skipped`.
    - `scanId` (number | null, required)
    - `reason` (string | null, required): Why no re-check started: limit, asset_not_active, ownership_unverified, error
    - `nextScheduledAt` (string (date-time) | null, required): The asset's next scheduled scan, when no re-check started
- `total` (number, required)
- `page` (number, required)
- `limit` (number, required)
- `counts` (object, required)
  - `current` (number, required)
  - `fixed` (number, required)
  - `dismissed` (number, required)
  - `total` (number, required)
  - `byStatus` (object, required)
    - `open` (number, required)
    - `in_progress` (number, required)
    - `resolved` (number, required)
    - `dismissed` (number, required)
- `severityBreakdown` (object, required)
- `slaTargets` (object, required)
  - `critical` (number, required)
  - `high` (number, required)
  - `medium` (number, required)
  - `low` (number, required)

```json
{
  "issues": [
    {
      "id": 42,
      "workspaceId": 42,
      "assetId": 42,
      "title": "string",
      "description": "string",
      "severity": "string",
      "status": "string",
      "templateId": "string",
      "dedupKey": "string",
      "assignedTo": 1,
      "resolution": "string",
      "resolvedBy": "string",
      "resolvedByScanId": 42,
      "resolvedByUserId": 42,
      "dismissedByUserId": 42,
      "category": "string",
      "dueDate": "2026-10-16T12:00:00.000Z",
      "resolvedAt": "2026-10-16T12:00:00.000Z",
      "lastReopenedAt": "2026-10-16T12:00:00.000Z",
      "dismissReason": "string",
      "dismissNotes": "string",
      "dismissExpiresAt": "2026-10-16T12:00:00.000Z",
      "firstSeenAt": "2026-10-16T12:00:00.000Z",
      "lastSeenAt": "2026-10-16T12:00:00.000Z",
      "lastCheckedAt": "2026-10-16T12:00:00.000Z",
      "reachability": "string",
      "verificationScanId": 42,
      "verificationSkipped": "string",
      "createdAt": "2026-10-16T12:00:00.000Z",
      "updatedAt": "2026-10-16T12:00:00.000Z",
      "assignee": {
        "firstName": null,
        "lastName": null
      },
      "resolvedByUser": {
        "firstName": null,
        "lastName": null
      },
      "dismissedByUser": {
        "firstName": null,
        "lastName": null
      },
      "asset": {
        "id": null,
        "name": {},
        "value": null,
        "type": null,
        "cdnProvider": {},
        "project": {}
      },
      "findings": [
        {}
      ],
      "_count": {
        "findings": null
      },
      "seenInLatestScan": true,
      "proof": {},
      "reproduce": {},
      "vantage": {},
      "verification": {
        "status": "queued",
        "scanId": null,
        "reason": null,
        "nextScheduledAt": null
      }
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 1,
  "counts": {
    "current": 1,
    "fixed": 1,
    "dismissed": 1,
    "total": 1,
    "byStatus": {
      "open": 1,
      "in_progress": 1,
      "resolved": 1,
      "dismissed": 1
    }
  },
  "severityBreakdown": {},
  "slaTargets": {
    "critical": 1,
    "high": 1,
    "medium": 1,
    "low": 1
  }
}
```

## Errors

- 400: The request is not valid: a field is missing or has the wrong shape (the message names it).
- 401: No valid credentials: the API key or access token is missing, revoked or expired (INVALID_API_KEY, INVALID_TOKEN).
- 403: Not allowed: the key or token lacks this scope (SCOPE_REQUIRED), the route is dashboard-only (SESSION_REQUIRED), or a plan limit applies.
- 429: Too many requests (RATE_LIMITED): wait the seconds Retry-After gives.
