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

# Read workspace data

> GET /api/v1/vulnerabilities, incidents, events, sboms and advisories: read your workspace's data with a read token.

> [!NOTE]
>
> **Plans:** Every plan. Reading keeps working while the workspace is read-only or closed. **Who:** anyone with a read
> token, or an [agent connected over OAuth](https://docs.pharussecurity.com/api-reference/mcp-server.md); owners and admins create read tokens.

The read endpoints return what the Vulnerabilities, Incidents, Audit trail, SBOMs and Advisories pages show, as JSON, so
an internal dashboard, a script or a report can use it. They only read: nothing in Pharus changes.

```text theme={null}
GET https://app.pharussecurity.com/api/v1/vulnerabilities
GET https://app.pharussecurity.com/api/v1/vulnerabilities/{id}
GET https://app.pharussecurity.com/api/v1/incidents
GET https://app.pharussecurity.com/api/v1/incidents/{reference}
GET https://app.pharussecurity.com/api/v1/events
GET https://app.pharussecurity.com/api/v1/sboms
GET https://app.pharussecurity.com/api/v1/sboms/{id}
GET https://app.pharussecurity.com/api/v1/advisories
GET https://app.pharussecurity.com/api/v1/advisories/{trackingId}
GET https://app.pharussecurity.com/api/v1/deadlines
GET https://app.pharussecurity.com/api/v1/families
```

## Authentication

Every request needs a read token in the `Authorization` header:

```http theme={null}
Authorization: Bearer phr_...
```

Create one under **Settings → API tokens** with **Create token**, and under **Access** choose **Read workspace data (MCP
server and API)**. A read token reads the whole workspace and can't change anything. A CI upload token or an alert
destinations token gets `401` here, and a read token gets `401` on the upload and alert destination endpoints. See
[create a token](https://docs.pharussecurity.com/api-reference/introduction.md#create-a-token).

A read token stops working when the person who created it leaves the company or stops being an owner or admin. The audit
trail records it as revoked by Pharus, with the reason.

An agent connected over OAuth with the `workspace:read` scope reads the same endpoints with its own token (`pho_...`). See
the [MCP server](https://docs.pharussecurity.com/api-reference/mcp-server.md).

## What the responses contain

* Field names are in English, and so are the audit trail's titles. Dates are ISO 8601 in UTC.
* Every item has a `url` to the same thing in Pharus.
* The responses never contain drafts of reports to the authorities, a reporter's details, email addresses, member ids or
  token hashes. Owners show as names.
* Responses are sent with `Cache-Control: private, no-store`.

Reading isn't recorded in the audit trail. The token's **Last used** under **Settings → API tokens** shows when it was
last used.

## Example: overdue fixes

```bash theme={null}
export PHARUS_READ_TOKEN=phr_...   # a read token from Settings → API tokens

curl --fail-with-body -sS "https://app.pharussecurity.com/api/v1/vulnerabilities?due=overdue" \
  -H "Authorization: Bearer $PHARUS_READ_TOKEN"
```

```json theme={null}
{
  "vulnerabilities": [
    {
      "id": "6f1c2b9e-0d4a-4e57-8b1a-2c3d4e5f6a70",
      "vulnerability": "CVE-2026-1234",
      "aliases": { "cve": ["CVE-2026-1234"], "osv": ["GHSA-xxxx-xxxx-xxxx"], "euvd": "EUVD-2026-5678" },
      "component": { "name": "openssl", "version": "3.0.13", "purl": "pkg:generic/openssl@3.0.13" },
      "family": { "id": "0f8fad5b-d9cb-469f-a165-70867728950e", "name": "Gateway G3" },
      "productVersions": ["4.2.0"],
      "severity": { "level": "high", "score": 7.5, "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "cvssVersion": "3.1", "source": "osv" },
      "exploited": false,
      "exploitedAt": null,
      "exploitation": { "kev": false, "euvd": false, "ssvcActive": false },
      "epss": { "score": 0.0213, "percentile": 0.84 },
      "vex": { "status": "affected", "justification": null, "detail": null, "setByPharus": false },
      "fixedVersions": ["3.0.14"],
      "patchedProductVersions": [],
      "remediation": { "owner": "Kari Nordmann", "dueAt": "2026-10-28T09:12:00.000Z", "priority": "severe" },
      "incident": null,
      "matchedBy": { "method": "osv_purl", "confidence": "exact" },
      "firstSeenAt": "2026-09-28T09:12:00.000Z",
      "lastSeenAt": "2026-10-31T06:00:00.000Z",
      "goneAt": null,
      "url": "https://app.pharussecurity.com/vulnerabilities/CVE-2026-1234"
    }
  ],
  "total": 1,
  "page": 1,
  "pageCount": 1,
  "pageSize": 50
}
```

## Vulnerabilities

### List vulnerabilities

`GET /api/v1/vulnerabilities` returns one row per vulnerability, component and product family, 50 per page, as on the
[Vulnerabilities list](https://docs.pharussecurity.com/monitoring/vulnerabilities.md#the-vulnerabilities-list). Matches of archived product families are
left out. The query parameters are the list's filters; an invalid value is ignored.

| Parameter | Values |
| - | - |
| `tab` | `all` (the default), `exploited`, `investigating` or `not_affected` |
| `source` | `kev`, `euvd` or `exploited` (either) |
| `vex` | `affected`, `under_investigation`, `not_affected` or `fixed` |
| `family` | A product family's `id` |
| `q` | Text to search for: a CVE, a component name or a purl |
| `gone` | `1` to include components no longer in an active SBOM |
| `epss` | `1`, `10` or `50`: only matches with an EPSS of at least that many percent |
| `owner` | `none`: only fixes nobody owns |
| `due` | `overdue`, `week` (due within 7 days) or `none` (no deadline yet) |
| `sort` | `due` (the default: nearest deadline first), `newest` (exploited, then newest) or `epss` (highest EPSS first) |
| `page` | The page number, from 1 |

The response is `{ vulnerabilities, total, page, pageCount, pageSize }`. Each row has:

| Field | What it holds |
| - | - |
| `vulnerability`, `aliases` | The vulnerability's id, and its CVE, OSV and EUVD ids |
| `component`, `family`, `productVersions` | The matched component (`name`, `version`, `purl`), its product family (`id`, `name`), and the product versions whose SBOMs contain it |
| `severity` | `level` (`critical`, `high`, `medium`, `low`, `none` or `unknown`), the CVSS `score`, `vector` and `cvssVersion`, and its `source` (`osv`, `euvd` or `nvd`) |
| `exploited`, `exploitedAt`, `exploitation` | Whether the vulnerability is known to be exploited, since when, and the signals: `kev` (in CISA KEV), `euvd` (marked exploited in EUVD), `ssvcActive` (CISA SSVC rates exploitation Active) |
| `epss` | FIRST's EPSS `score` and `percentile`, both from 0 to 1, or `null` |
| `vex` | The VEX `status`, the `justification` for not affected, the `detail`, and `setByPharus` when Pharus set it from evidence rather than a person |
| `fixedVersions` | Versions of the component that fix it |
| `patchedProductVersions` | Product versions whose SBOM already patches it |
| `remediation` | The fix's `owner` (a name), its deadline `dueAt` and its `priority`: `exploited`, `likely`, `severe` or `other`. See [Fix deadlines](https://docs.pharussecurity.com/monitoring/fix-deadlines.md). |
| `incident` | The linked incident's `reference` and `status`, or `null` |
| `matchedBy` | How Pharus matched it: the `method`, and the `confidence`, `exact` or `name` (a name-only match whose version isn't verified) |
| `firstSeenAt`, `lastSeenAt`, `goneAt` | When Pharus first and last saw the match, and when the component left the SBOMs |

### Get a vulnerability

`GET /api/v1/vulnerabilities/{id}` takes a CVE, GHSA or EUVD id, for example `CVE-2026-1234`. It returns the
vulnerability with every match in the workspace, as on its page in Pharus:

| Field | What it holds |
| - | - |
| `vulnerability`, `aliases`, `summary`, `details`, `published`, `modified` | The vulnerability as OSV.dev describes it |
| `severity`, `epss` | As in the list. `epss` adds the `date` it was scored. |
| `exploited` | `true` when CISA KEV lists it, EUVD marks it exploited or CISA SSVC rates exploitation Active |
| `exploitation` | `kev` (`dateAdded`, `dueDate`, `requiredAction`, `knownRansomwareUse`), `euvd` (`id`, `exploited`) and `ssvc` (`exploitation`, `automatable`, `technicalImpact`, `assessedAt`), each `null` when there is nothing |
| `cwes`, `references` | The weaknesses NVD lists, and the reference URLs |
| `matches` | Every match, with the fields of the list and `familyArchived` |
| `incidents` | Linked incidents: `reference`, `title`, `status`, `closeReason`, `family`, `awareAt` and `url` |

`404` with `not_found` when no product in the workspace matches the vulnerability.

## Incidents

### List incidents

`GET /api/v1/incidents` returns the workspace's incidents, without drills. `status=open`, the default, lists open
incidents with the nearest deadline first; `status=closed` lists closed ones, the most recently closed first.

The response is `{ incidents, counts, truncated }`: at most 500 incidents, `counts` with the number `open` and `closed`,
and `truncated` when there are more than were returned. Each incident has:

| Field | What it holds |
| - | - |
| `reference`, `title` | For example `INC-0042` |
| `kind` | `exploited_vulnerability` or `severe_incident` |
| `source` | How it started: `kev_match`, `euvd_match`, `manual` or `inbox_report` |
| `status`, `closeReason`, `closedAt` | `open` or `closed`, and why it was closed: `not_reportable`, `reported` or `duplicate` |
| `awareAt` | When the company became aware, which starts the CRA clocks. `null` while the incident is being assessed. |
| `vulnerability`, `productVersions`, `family`, `exploited` | What it is about |
| `determination`, `approval` | The latest determination, and whether it is `fullyApproved`, how many approvals are `pending` and whether one was `declined` |
| `craStatus` | Whether the CRA applies: `triggered`, `under_review`, `not_applicable` or `tracked` |
| `nextDeadline` | The open report with the earliest deadline over every regime: `regime`, `report`, `deadline` and `state`. `null` once closed. |

### Get an incident

`GET /api/v1/incidents/{reference}` takes the reference in any case, for example `INC-0042`. It returns what happened,
the decision, every regime's clocks and what was filed. It never contains the drafts of the reports.

| Field | What it holds |
| - | - |
| `summary`, `awareBasis` | The incident's summary, and the basis for the awareness time, or what flagged it while it is being assessed |
| `agentSummary` | What the [agent](https://docs.pharussecurity.com/incidents/agents.md) that registered it said, if one did. It isn't in any report. |
| `fixAvailableAt`, `fixNote` | When a fix became available, which starts the final report's clock, and the note about it |
| `memberStates`, `suspectedMalicious` | The member states where the product is made available, as entered on the incident (empty means the family's), and whether an unlawful or malicious act is suspected |
| `vulnerability` | The vulnerability's `key`, the `component`, `kev`, `euvdExploited`, `epss` and `url` |
| `determination`, `doraClassification` | The latest decision: `determination`, `rationale`, `decidedBy`, `decidedAt`, `fullyApproved`, `pendingApprovals` and `declined` |
| `craRecipient` | Where the CRA reports go. See [routing](https://docs.pharussecurity.com/incidents/routing.md). |
| `craClocks` | The early warning, the notification and the final report, each with `report`, `window` (`24h`, `72h`, `14d` or `1mo`), `startedAt`, `deadline`, `state`, `submittedAt` and `receiptRef` |
| `notices` | Each other regime's notice, such as `digitalsikkerhetsloven`, `gdpr` or `dora`: `regime`, `status`, `recipient`, `awareAt` and its `clocks` |
| `filings` | Every report marked as submitted, receipt recorded, voided or updated: `regime`, `report`, `action`, `recipient`, `occurredAt` and `receiptRef` |

A clock's `state` is `pending` (not started yet), `running`, `overdue`, `submitted`, `received` or `not_required`. See
[clocks](https://docs.pharussecurity.com/incidents/clocks.md).

`404` with `not_found` when the workspace has no incident with that reference.

## Audit trail

`GET /api/v1/events` returns the [audit trail](https://docs.pharussecurity.com/reports/audit-trail.md), newest first.

| Parameter | Values |
| - | - |
| `incident` | An incident reference: only its entries |
| `group` | `incidents`, `decisions`, `filings`, `sboms`, `settings` or `agents`, the page's type filters |
| `actor` | `system`: only what Pharus did by itself. `agent`: only what agents did. |
| `limit` | 1 to 100 entries. The default is 100. |
| `before` | The `nextBefore` of the previous response, for the next page |

The response is `{ events, nextBefore }`. `nextBefore` is `null` on the last page. Each event has the `id`, `occurredAt`,
the `action` key (for example `report.submitted`), the `title` and `detail` as the page shows them in English, the
`actor` and `actorKind` (`user`, `system`, `api_token`, `partner` for the Pharus team, or `agent`), `onBehalfOf` (the person
an agent acted for, otherwise `null`), and the `incident` reference when there is one. Email addresses are removed, and so are a reporter's subject line, the recipients of invoices and
pages, and why someone is off call.

## SBOMs

### List SBOMs

`GET /api/v1/sboms` returns the SBOMs of the active product families, newest first, 50 per page. `family` (a product
family's `id`) narrows it to one family, `retired=1` includes SBOMs that a newer one replaced or a person retired, and
`page` picks the page.

The response is `{ sboms, total, page, pageCount, pageSize }`. Each SBOM has its `id`, `family`, `productVersion`,
`format` and `specVersion`, the `source` (`upload`, `github`, `azure_devops`, `dependency_track`, `sbomify` or `api`), the
`status` (`received`, `parsed`, `matched` or `failed`, with the `error`), `componentCount`, `receivedAt`, `retiredAt`, the
`quality` check as the [upload response](https://docs.pharussecurity.com/api-reference/sboms.md#responses) gives it, and `endOfLifeComponents`: how many
components are on a release line past [end of life upstream](https://docs.pharussecurity.com/monitoring/end-of-life.md).

### Get an SBOM

`GET /api/v1/sboms/{id}` returns one SBOM with its details (`productName`, `serialNumber`, the `ci` details sent with it,
`sha256`, `sizeBytes`, `parsedAt`, `matchedAt` and `uploadedBy`) and its `components`, those with the most exploited and
known vulnerabilities first. Each component has its `name`, `group`, `version`, `purl` and `cpe`, the number of
`vulnerabilities` and how many of them are `exploited`, and `endOfLife` (`product`, `cycle`, `from`) when its release
line is past end of life.

| Parameter | Values |
| - | - |
| `vulnerable` | `1`: only components with vulnerabilities |
| `limit` | At most this many components, up to 10 000. The default is 1 000. `componentsTruncated` is `true` when there were more. |

A retired SBOM's components have no vulnerabilities: Pharus only checks the SBOMs in use.

## Advisories

### List advisories

`GET /api/v1/advisories` returns the workspace's [security advisories](https://docs.pharussecurity.com/disclosure/advisories.md), the most recently
updated first. `status` (`draft`, `in_review` or `published`) narrows the list. The response is
`{ advisories, truncated }`: at most 500, with `truncated` when there are more. Each advisory has its `trackingId`,
`title`, `status`, `tlp`, `vulnerabilities`, `families`, `currentVersion`, `updatedAt` and the `incident` reference.

### Get an advisory

`GET /api/v1/advisories/{trackingId}` takes the tracking ID in any case. Besides the fields of the list, it returns
the `publicUrl`, the `releases` (`version`, `tlp`, `publishedAt`, `publishedBy`, `filename` and `publicUrl` of each), the
CSAF document of the current release as `csaf`, and while a new version is a draft or in review, the CSAF document it would
publish as `draftCsaf`.

## Deadlines

`GET /api/v1/deadlines` returns every deadline in the workspace, nearest first. Overdue ones are always in. The rest come
within `within_days`, from 1 to 90 days ahead. The default is 14. Drills and archived product families are left out.

The response is `{ deadlines, now, withinDays, fixesTruncated }`. `fixesTruncated` is `true` when there were more than the
200 nearest fix deadlines. Each deadline has a `kind`, its `deadline`, `overdue` and a `url`, and:

| `kind` | What it is | Also has |
| - | - | - |
| `report` | A report due on an open incident, under any regime | `regime`, `report`, `window`, `state` (`running` or `overdue`), `incident` (`reference`, `title`) and `family` |
| `assessment` | An incident still [being assessed](https://docs.pharussecurity.com/incidents/clocks.md) | `incident` and `family` |
| `fix` | A vulnerability's [fix deadline](https://docs.pharussecurity.com/monitoring/fix-deadlines.md) | `vulnerability`, `component` (`name`, `version`), `family`, `owner` (a name) and `priority` |

## Product families

`GET /api/v1/families` returns the active product families, by name, as `{ families }`. Each has its `id`, `name`, `description`, `currentVersion`, `memberStates`, `soldInEu`, `newestSbomOnly`, `componentCount`, `lastSbomAt` and `url`. `newestSbomOnly` is `true` when [only the newest SBOM is in use](https://docs.pharussecurity.com/monitoring/sboms.md#only-the-newest-sbom-in-use): each new SBOM retires every older one in the family, not just the one for its own version.

## Errors

Errors have the same shape as everywhere in the API: `{ "error": "...", "message": "..." }`. See
[responses](https://docs.pharussecurity.com/api-reference/introduction.md#responses).

| Status | `error` | Meaning |
| - | - | - |
| 200 | | The data |
| 401 | `unauthorized` | The token is missing, invalid, revoked or expired, or isn't a read token or an agent's token |
| 403 | `agents_disabled`, `insufficient_scope` | An agent's token only: the workspace doesn't allow agents, or the person didn't allow reading |
| 404 | `not_found` | The workspace has no vulnerability match, incident, SBOM or advisory with that id |
| 429 | `rate_limited` | The token made 600 requests in the last hour. Wait the number of seconds in `Retry-After`. |

Each read token can make 600 requests per hour, counted together across the read endpoints.

## Related

> [card] [API introduction](https://docs.pharussecurity.com/api-reference/introduction.md)

> [card] [Vulnerabilities](https://docs.pharussecurity.com/monitoring/vulnerabilities.md)

> [card] [Fix deadlines](https://docs.pharussecurity.com/monitoring/fix-deadlines.md)

> [card] [Audit trail](https://docs.pharussecurity.com/reports/audit-trail.md)

> [card] [MCP server](https://docs.pharussecurity.com/api-reference/mcp-server.md)


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