Scanning API
32 endpoints. Request and response schemas are described on the schemas page; the other tags are listed in the API index.
Endpoints
GET /api/v1/admin/license/policies
List all license policies
List all license policies (admin only)
Responses
| Status | Description | Body |
|---|---|---|
200 | List of license policies | - |
403 | Forbidden | application/json: Error |
POST /api/v1/admin/license/policies
Create global license policy
Create a global license policy (admin only)
Request body (required)
application/json: LicensePolicy
Responses
| Status | Description | Body |
|---|---|---|
201 | License policy created | - |
400 | Invalid request | application/json: Error |
403 | Forbidden | application/json: Error |
GET /api/v1/repositories/{name}/license/policies
List license policies
List license policies for a repository
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | List of license policies | - |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Repository or addressed resource not found | application/json: Error |
POST /api/v1/repositories/{name}/license/policies
Create license policy
Create a license policy for a repository
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
Request body (required)
application/json: LicensePolicy
Responses
| Status | Description | Body |
|---|---|---|
201 | License policy created | - |
400 | Invalid request | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Repository or addressed resource not found | application/json: Error |
PUT /api/v1/repositories/{name}/license/policies/{id}
Update license policy
Update a license policy for a repository
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
Request body (required)
application/json: LicensePolicy
Responses
| Status | Description | Body |
|---|---|---|
200 | License policy updated | - |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Repository or addressed resource not found | application/json: Error |
DELETE /api/v1/repositories/{name}/license/policies/{id}
Delete license policy
Delete a license policy
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
204 | License policy deleted | - |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Repository or addressed resource not found | application/json: Error |
POST /api/v1/repositories/{name}/license/scan
Scan licenses
Detect the licenses of an artifact from its stored package file (the wheel METADATA, package.json, Cargo.toml, .nuspec, pom or gemspec it declares) and from its license properties, evaluate the license policies and record the result. A violated policy with action block quarantines the artifact: downloads answer 403 ARTIFACT_QUARANTINED until an admin approves it.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
Request body (required)
application/json: object
| Field | Type | Required | Description |
|---|---|---|---|
artifact_id | string | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | License scan result with the policy violations | application/json: LicenseScanRunResult |
400 | Invalid body | - |
403 | Admin access required | - |
404 | Repository not found | - |
422 | The artifact's metadata is too large or ambiguous to be read safely (unsafe_artifact), or its license cannot be read from its file while a blocking license policy applies (unreadable_artifact) | - |
GET /api/v1/repositories/{name}/license/scans
List license scans
List license scans for a repository
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | List of license scans | application/json: object |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Repository or addressed resource not found | application/json: Error |
Fields of the 200 response (application/json):
| Field | Type | Required | Description |
|---|---|---|---|
scans | array of LicenseScanResult | no | - |
GET /api/v1/repositories/{name}/license/scans/{id}
Get license scan
Get details of a specific license scan
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | License scan details | application/json: LicenseScanResult |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Scan not found | - |
POST /api/v1/repositories/{name}/license/scans/{id}/quarantine
Quarantine or approve license scan artifact
Quarantine (quarantined: true) or approve (quarantined: false) the artifact of a license scan (admin only). An artifact quarantined by a blocking license policy stays quarantined, also across re-scans of the same licenses, until it is approved here.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
Request body (required)
application/json: object
| Field | Type | Required | Description |
|---|---|---|---|
quarantined | boolean | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | Updated license scan | application/json: LicenseScanResult |
400 | Invalid body | - |
403 | Admin access required | - |
404 | Repository or scan not found | - |
POST /api/v1/repositories/{name}/secrets/scan
Scan secrets
Trigger a secrets scan for a repository
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
201 | Secrets scan started | - |
400 | Invalid request | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Repository or addressed resource not found | application/json: Error |
GET /api/v1/repositories/{name}/secrets/scans
List secrets scans
List secrets scans for a repository
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | List of secrets scans | application/json: object |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Repository or addressed resource not found | application/json: Error |
Fields of the 200 response (application/json):
| Field | Type | Required | Description |
|---|---|---|---|
scans | array of ScanResult | no | - |
GET /api/v1/repositories/{name}/secrets/scans/export
Export secrets scans of a repository
Findings of all (or with flagged=true the flagged) secrets scans of a repository as SARIF, CSV or JSON (admin only). Never contains a secret value, redacted or not.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
flagged | query | boolean | no | - |
format | query | string | no | sarif (SARIF 2.1.0, GitHub code scanning compatible), csv or json (default). One of: sarif, csv, json. Default: json. |
Responses
| Status | Description | Body |
|---|---|---|
200 | The export as a download. SARIF is application/sarif+json, CSV text/csv, JSON application/json. X-Export-Truncated: true means findings were held back (SARIF: more than 25000 results; cross-repository: more than 2000 scans). | application/json: object; application/sarif+json: object; text/csv: string |
400 | Unknown format or filter (validation_failed) | - |
403 | Admin access required | - |
404 | Repository not found | - |
GET /api/v1/repositories/{name}/secrets/scans/{id}
Get secrets scan
Get details of a specific secrets scan
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | Secrets scan details | - |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Scan not found | - |
DELETE /api/v1/repositories/{name}/secrets/scans/{id}
Delete secrets scan
Delete a secrets scan
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
204 | Secrets scan deleted | - |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Scan not found | - |
GET /api/v1/repositories/{name}/secrets/scans/{id}/export
Export a secrets scan
Findings of one secrets scan as SARIF, CSV or JSON (admin only). Never contains a secret value, redacted or not.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
format | query | string | no | sarif (SARIF 2.1.0, GitHub code scanning compatible), csv or json (default). One of: sarif, csv, json. Default: json. |
Responses
| Status | Description | Body |
|---|---|---|
200 | The export as a download. SARIF is application/sarif+json, CSV text/csv, JSON application/json. X-Export-Truncated: true means findings were held back (SARIF: more than 25000 results; cross-repository: more than 2000 scans). | application/json: object; application/sarif+json: object; text/csv: string |
400 | Unknown format or filter (validation_failed) | - |
403 | Admin access required | - |
404 | Scan not found | - |
POST /api/v1/repositories/{name}/secrets/scans/{id}/quarantine
Quarantine secrets scan artifact
Quarantine an artifact found in a secrets scan
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | Artifact quarantined | - |
400 | Invalid request | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Repository or addressed resource not found | application/json: Error |
GET /api/v1/repositories/{name}/security/summary
Security summary of a repository, package or version
Counts only: vulnerabilities by severity, license violations, secret findings, AI flags and whether a result is quarantined. It carries no finding ids, titles or other details, so it needs only read access to the repository: it is what viewers, developers and tokens that cannot list findings show. Narrow it to a package with package_name and to one version with version.
Security: bearerAuth or cookieAuth or .
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
package_name | query | string | no | Only this package. |
version | query | string | no | Only this version of the package; needs package_name. |
Responses
| Status | Description | Body |
|---|---|---|
200 | The counts | application/json: RepoSecuritySummary |
400 | version without package_name, or a value that is too long (validation_failed) | - |
403 | No read access to the repository | - |
404 | Repository not found | - |
POST /api/v1/repositories/{name}/vuln/scan
Scan vulnerabilities
Start a vulnerability scan for an artifact. The scan runs in the background: poll the scan until scan_status is completed, partial or failed. A scanner that cannot run (not installed, timeout, non-zero exit, unreadable output, upstream error, unsupported ecosystem) is recorded as failed instead of completed with zero findings.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
Request body (required)
application/json: VulnScanRequest
Responses
| Status | Description | Body |
|---|---|---|
200 | Vulnerability scan started (scan_status is scanning) | application/json: VulnScanResult |
400 | Invalid body or unknown scanner | - |
403 | Admin access required | - |
404 | Repository not found | - |
GET /api/v1/repositories/{name}/vuln/scanners
List vulnerability scanners
Report which vulnerability scanners can run on the server: osv is always ready; trivy and grype need their binary and a downloaded vulnerability database (see the scanning guide). A client should disable a scanner that is not ready and show its message.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | Scanners in the order osv, trivy, grype | application/json: object |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Admin access required | - |
Fields of the 200 response (application/json):
| Field | Type | Required | Description |
|---|---|---|---|
scanners | array of VulnScanner | yes | - |
GET /api/v1/repositories/{name}/vuln/scans
List vulnerability scans
List vulnerability scans for a repository
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | List of vulnerability scans | application/json: object |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Repository or addressed resource not found | application/json: Error |
Fields of the 200 response (application/json):
| Field | Type | Required | Description |
|---|---|---|---|
scans | array of VulnScanResult | no | - |
GET /api/v1/repositories/{name}/vuln/scans/{id}
Get vulnerability scan
Get details of a specific vulnerability scan
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | Vulnerability scan details | application/json: VulnScanResult |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Scan not found | - |
DELETE /api/v1/repositories/{name}/vuln/scans/{id}
Delete vulnerability scan
Delete a vulnerability scan
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
204 | Vulnerability scan deleted | - |
400 | Invalid request, including a NUL byte in the URL or the body | application/json: Error |
403 | Forbidden | application/json: Error |
404 | Scan not found | - |
GET /api/v1/repositories/{name}/vuln/scans/{id}/export
Export a vulnerability scan
Findings of one scan as SARIF, CSV or JSON (admin only).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
format | query | string | no | sarif (SARIF 2.1.0, GitHub code scanning compatible), csv or json (default). One of: sarif, csv, json. Default: json. |
Responses
| Status | Description | Body |
|---|---|---|
200 | The export as a download. SARIF is application/sarif+json, CSV text/csv, JSON application/json. X-Export-Truncated: true means findings were held back (SARIF: more than 25000 results; cross-repository: more than 2000 scans). | application/json: object; application/sarif+json: object; text/csv: string |
400 | Unknown format or filter (validation_failed) | - |
403 | Admin access required | - |
404 | Scan not found | - |
POST /api/v1/repositories/{name}/vuln/scans/{id}/quarantine
Quarantine vulnerability scan artifact
Quarantine (quarantined: true) or release (quarantined: false) the artifact of a vulnerability scan (admin only).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | path | string | yes | - |
id | path | string (uuid) | yes | - |
Request body (required)
application/json: object
| Field | Type | Required | Description |
|---|---|---|---|
quarantined | boolean | yes | - |
Responses
| Status | Description | Body |
|---|---|---|
200 | Updated vulnerability scan | application/json: VulnScanResult |
400 | Invalid body | - |
403 | Admin access required | - |
404 | Repository or scan not found | - |
GET /api/v1/security/findings
List security findings of all repositories
Vulnerability, license, secret and AI findings across repositories, worst first: highest severity, then newest scan, then id. One finding is one stored scan result (a package version of one type) that reports something; clean results are not listed. Keyset paging: follow next_cursor while has_more is true. The cursor is bound to the order, not to the filters: send the same filters with it. Global administrators see every repository; a project maintainer or owner sees the repositories of the projects they maintain or own. Everyone else (viewers and developers, anonymous callers, scoped and deploy tokens) gets 403: they use GET /api/v1/repositories/{name}/security/summary instead.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
type | query | string | no | Comma-separated finding types to include: vuln, license, secret, ai. Default: all four. |
repo | query | string | no | Only the findings of this repository (by name). |
project | query | string | no | Only the findings of the repositories of this project (by name). |
severity | query | string | no | Only findings whose highest severity is exactly this one (the summary strip counts the same way). One of: critical, high, medium, low. |
status | query | string | no | Only findings in this state. One of: open, quarantined, suppressed. |
q | query | string | no | Case-insensitive substring of the repository name or of name@version. |
limit | query | integer | no | Page size, default 50. Minimum: 1. Maximum: 200. |
cursor | query | string | no | Opaque next_cursor of the previous page. |
Responses
| Status | Description | Body |
|---|---|---|
200 | One page of findings | application/json: object |
400 | Invalid filter or cursor (validation_failed) | - |
403 | Neither a global administrator nor a project maintainer or owner | - |
Fields of the 200 response (application/json):
| Field | Type | Required | Description |
|---|---|---|---|
findings | array of SecurityFinding | yes | - |
has_more | boolean | yes | True when findings follow this page. |
next_cursor | string | no | Pass as cursor to fetch the next page. Absent when has_more is false. |
GET /api/v1/security/findings/export
Export security findings
Every finding the list's filters select (no paging), as CSV, JSON or a CycloneDX VEX document. CSV and JSON hold at most 10000 findings; vex speaks about the artifacts of the vulnerability findings (at most 500 of them) with all their vulnerabilities and VEX decisions: the type filter is ignored, the other filters pick the artifacts, and an artifact hosted in several repositories appears once, keyed by its package URL. X-Export-Truncated: true means findings were held back. Global administrators see every repository; a project maintainer or owner sees the repositories of the projects they maintain or own. Everyone else (viewers and developers, anonymous callers, scoped and deploy tokens) gets 403: they use GET /api/v1/repositories/{name}/security/summary instead.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
type | query | string | no | Comma-separated finding types to include: vuln, license, secret, ai. Default: all four. |
repo | query | string | no | Only the findings of this repository (by name). |
project | query | string | no | Only the findings of the repositories of this project (by name). |
severity | query | string | no | Only findings whose highest severity is exactly this one (the summary strip counts the same way). One of: critical, high, medium, low. |
status | query | string | no | Only findings in this state. One of: open, quarantined, suppressed. |
q | query | string | no | Case-insensitive substring of the repository name or of name@version. |
format | query | string | no | csv, json (default) or vex (CycloneDX VEX of the vulnerability findings). One of: csv, json, vex. Default: json. |
Responses
| Status | Description | Body |
|---|---|---|
200 | The export as a download. CSV is text/csv, JSON application/json ({findings, truncated}), VEX application/vnd.cyclonedx+json. | application/json: object; application/vnd.cyclonedx+json: object; text/csv: string |
400 | Unknown format or filter (validation_failed) | - |
403 | Neither a global administrator nor a project maintainer or owner | - |
GET /api/v1/security/findings/summary
Count security findings by type
Findings per type (total, by highest severity, quarantined) and how many of the repositories that hold artifacts have a completed scan, within the caller's scope. Global administrators see every repository; a project maintainer or owner sees the repositories of the projects they maintain or own. Everyone else (viewers and developers, anonymous callers, scoped and deploy tokens) gets 403: they use GET /api/v1/repositories/{name}/security/summary instead.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
repo | query | string | no | Only the findings of this repository (by name). |
project | query | string | no | Only the findings of the repositories of this project (by name). |
Responses
| Status | Description | Body |
|---|---|---|
200 | The counts | application/json: SecuritySummary |
400 | Invalid filter (validation_failed) | - |
403 | Neither a global administrator nor a project maintainer or owner | - |
GET /api/v1/security/health
Security health
Scanner readiness, the scan queue, the Dependency-Track and AI integrations and the scan coverage in one call (admin only).
Responses
| Status | Description | Body |
|---|---|---|
200 | The health aggregate | application/json: SecurityHealth |
403 | Admin access required | - |
GET /api/v1/vuln/scans
List vulnerability scans of all repositories
Overview of the vulnerability scans of every repository (admin only), worst first: most critical findings, then high, medium and low, then newest, then id. Keyset paging: follow next_cursor while has_more is true; no row is counted. Rows carry no findings. The cursor is bound to the order, not to the filters: send the same filters with it.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
repo | query | string | no | Only the scans of this repository (by name). |
severity | query | string | no | Only scans with at least one finding of this severity or worse. One of: critical, high, medium, low. |
status | query | string | no | Only scans in this state; scanning is pending or running. One of: completed, partial, failed, scanning. |
scanner | query | string | no | Only scans run by this scanner (a scan run by several matches each). One of: osv, trivy, grype. |
quarantined | query | boolean | no | Only quarantined (true) or not quarantined (false) scans. |
limit | query | integer | no | Page size, default 25. Minimum: 1. Maximum: 100. |
cursor | query | string | no | Opaque next_cursor of the previous page. |
Responses
| Status | Description | Body |
|---|---|---|
200 | One page of scans | application/json: object |
400 | Invalid filter or cursor (validation_failed) | - |
403 | Admin access required | - |
Fields of the 200 response (application/json):
| Field | Type | Required | Description |
|---|---|---|---|
has_more | boolean | no | True when scans follow this page. |
next_cursor | string | no | Pass as cursor to fetch the next page. Absent when has_more is false. |
scans | array of VulnScanOverviewRow | no | - |
GET /api/v1/vuln/scans/export
Export vulnerability scans of all repositories
Findings of every scan the overview filters select (admin only), as SARIF, CSV or JSON. No paging: at most 2000 scans are read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
repo | query | string | no | Only this repository (by name). |
severity | query | string | no | Scans with a finding of this severity or worse. One of: critical, high, medium, low. |
status | query | string | no | One of: completed, partial, failed, scanning. |
scanner | query | string | no | One of: osv, trivy, grype. |
quarantined | query | boolean | no | - |
format | query | string | no | sarif (SARIF 2.1.0, GitHub code scanning compatible), csv or json (default). One of: sarif, csv, json. Default: json. |
Responses
| Status | Description | Body |
|---|---|---|
200 | The export as a download. SARIF is application/sarif+json, CSV text/csv, JSON application/json. X-Export-Truncated: true means findings were held back (SARIF: more than 25000 results; cross-repository: more than 2000 scans). | application/json: object; application/sarif+json: object; text/csv: string |
400 | Unknown format or filter (validation_failed) | - |
403 | Admin access required | - |
GET /api/v1/vuln/scans/summary
Count vulnerability scans of all repositories
Totals of the overview by status, quarantine and worst severity (admin only), for every repository or the one named by repo.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
repo | query | string | no | Only the scans of this repository (by name). |
Responses
| Status | Description | Body |
|---|---|---|
200 | Counts | application/json: VulnScanSummary |
400 | Invalid repository name (validation_failed) | - |
403 | Admin access required | - |