Skip to main content
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; 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.

Authentication

Every request needs a read token in the Authorization header:
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. 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.

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

Vulnerabilities

List vulnerabilities

GET /api/v1/vulnerabilities returns one row per vulnerability, component and product family, 50 per page, as on the Vulnerabilities list. Matches of archived product families are left out. The query parameters are the list’s filters; an invalid value is ignored. The response is { vulnerabilities, total, page, pageCount, pageSize }. Each row has:

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: 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:

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. A clock’s state is pending (not started yet), running, overdue, submitted, received or not_required. See clocks. 404 with not_found when the workspace has no incident with that reference.

Audit trail

GET /api/v1/events returns the audit trail, newest first. 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 gives it, and endOfLifeComponents: how many components are on a release line past end of life upstream.

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. 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, 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:

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: 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. Each read token can make 600 requests per hour, counted together across the read endpoints.

API introduction

Vulnerabilities

Fix deadlines

Audit trail

MCP server