REST API Reference
The Product Security Hub REST API lets you read and update every data object in a product's cybersecurity file — components, threats, requirements, residual risks, vulnerabilities, SBOMs, and patches — programmatically. Use it to build automation pipelines or connect your own AI tools to your Product Security Hub data.
1 Authentication
Base URL
https://app.productsecurityhub.com/api/v1
Every request is authenticated with an API key passed in the X-Api-Key header. Keys are scoped to a tenant — use the key for the tenant that owns the product you are working with.
curl -H "X-Api-Key: <YOUR_API_KEY>" \
"https://app.productsecurityhub.com/api/v1/Products" Keep API keys secret and rotate them per your security policy. Never embed keys in client-side code or commit them to source control.
2 Conventions
Response envelope & pagination
List (GET) endpoints return a JSON object with a data array plus paging metadata. Use the pageSize query parameter to control page size.
curl -H "X-Api-Key: <KEY>" \
"https://app.productsecurityhub.com/api/v1/Products/{productId}/requirements?pageSize=2000" {
"data": [ { /* record */ }, { /* record */ } ],
"pageSize": 2000
/* ...paging fields... */
}
Single-record GET endpoints (e.g. /requirements/{requirementId}) return the record directly.
Identifiers
Each object carries several identifiers. Knowing which to use for imports is essential.
| Field | Example | Meaning |
|---|---|---|
| id | 88573 | Database id — not used for import matching |
| publicUniqueId | 221441 | The import match key — stable, shown in the UI, place in the template's Unique Id column |
| requirementUniqueId, componentId, threatId, etc. | R.1010010, A.152, T.2740 | Human-facing resource label shown in the UI |
3 The Import Model
🔑 Key Concept: Staged Review — nothing reaches production without approval
All write operations are performed by importing a file to a resource's /import endpoint. After submission, a background processing job runs approximately every 5 minutes. Once processed, the import is loaded into a staging environment and you receive an in-app notification. From the review screen you inspect every proposed change, then either Approve it (writes to your production file) or Abandon it (discards all changes).
AI-generated content, scripted bulk updates, and hand-entered data all travel the same import path with the same validation and the same approval step. The one exception is the CycloneDX SBOM component import, which loads directly so a scan can begin immediately.
How imports work
- Transport:
POSTasmultipart/form-datawith the file under the field namefile. CSV (text/csv) is the standard format. - Response: HTTP 200 immediately with an asynchronous confirmation. The background job processes the file within ~5 minutes, then stages it for review.
- Notification: You receive an in-app notification when the import is ready to review. Expect up to a few minutes from submission to notification.
- Review: Inspect every proposed change on the staging review screen. Approve to commit to production, or Abandon to discard entirely.
- Poll status (optional) with
GET /Products/imports.
curl -X POST \
-H "X-Api-Key: <KEY>" \
-F "file=@requirements_update.csv;type=text/csv" \
"https://app.productsecurityhub.com/api/v1/Products/{productId}/requirements/import" Create vs. update — match keys
An import row updates an existing record when its match key matches an existing record; otherwise it creates a new one.
| Resource | Match key (column) |
|---|---|
| Requirements | Unique Id (= publicUniqueId) |
| Residual Risks | Residual Risk Id (CRA.xxx) and/or Unique Id |
| Threats | Unique Id (= publicUniqueId) |
| Vulnerabilities | Vulnerability ID (VM.xxx) |
| Products | Id (product id) |
| Components | Component ID (A.xxx) |
Common mistakes to avoid
Always start from the pulled template — don't reconstruct it
Download the pre-populated import template for the resource. Reconstructing columns by hand leads to header-mismatch errors and misaligned data. The template carries the exact column headers and current values.
Blank cells overwrite editable text fields
On a requirement update, an empty HowWillThisBeMet, TestingNotes, or StatusNotes cell erases the existing value — even if you only intended to change the status. Starting from the pre-populated template is the natural defense since current values are already in the file.
4 Resource Reference
All paths are relative to https://app.productsecurityhub.com/api/v1.
Products
| Method | Path | Purpose |
|---|---|---|
| GET | /Products | List products in the tenant |
| GET | /Products/{id}/export | Full product export (JSON) |
| POST | /Products/import | Create or update product-level fields (match on Id) |
| GET | /Products/imports | Import job status |
Components
| Method | Path | Purpose |
|---|---|---|
| GET | /Products/{productId}/components | List components |
| POST | /Products/{productId}/components/import | Create/update components |
Component imports require the display component-type name (e.g. Operating System - Windows), not an internal type id.
Threats & Requirements
| Method | Path | Purpose |
|---|---|---|
| GET | /Products/{productId}/threats | List threats (incl. PM-CVSS, links) |
| POST | /Products/{productId}/threats/import | Update existing threats only |
| GET | /Products/{productId}/requirements | List requirements |
| GET | /Products/{productId}/requirements/{requirementId} | Single requirement |
| POST | /Products/{productId}/requirements/import | Update existing requirements only |
| POST | /Products/{productId}/threats-and-requirements/import | Create new threats and/or requirements |
Use the combined /threats-and-requirements/import endpoint to create new threats or requirements. The single-resource endpoints are update-only.
Residual Risks
| Method | Path | Purpose |
|---|---|---|
| GET | /Products/{productId}/residualrisks | List residual risks (CVSS, links, narrative) |
| GET | /Products/{productId}/residualrisks/{riskId} | Single residual risk |
| POST | /Products/{productId}/residualrisks/import | Create/update residual risks |
Vulnerabilities
| Method | Path | Purpose |
|---|---|---|
| GET | /Products/{productId}/vulnerabilities | List vulnerabilities (scan results, status) |
| POST | /Products/{productId}/vulnerabilities/import | Create/update vulnerabilities (VEX triage) |
Vulnerability imports match on Vulnerability ID (VM.xxx). Use the VEX model: Not Affected carries a Justification (e.g. Code_Not_Reachable); Affected carries a Response (e.g. Will_Not_Fix, Update).
SBOMs
| Method | Path | Purpose |
|---|---|---|
| GET | /Products/{productId}/sboms | List SBOM records |
| POST | /Products/{productId}/sboms/import | Create an SBOM record |
| POST | /Products/{productId}/sboms/{sbomId}/components/import | Import CycloneDX components into an SBOM |
| GET | /Products/{productId}/sboms/{sbomId}/export | Export an SBOM |
| POST | /Products/{productId}/sboms/{sbomId}/scan?scanType=OSV | Run an SCA scan (OSV or NVD) |
Typical flow: create the SBOM record → import the CycloneDX file → run a scan → triage vulnerabilities. Components with a PURL scan against OSV (scanType=OSV); components with a CPE scan against the NVD mirror (scanType=NVD).
Patches
| Method | Path | Purpose |
|---|---|---|
| POST | /Products/{productId}/patches/import | Create/update patches |
5 Bring-Your-Own-AI Workflow
The API is the substrate for using your own AI tools. Product Security Hub does not run your model — your data and model stay in your environment. The four-step pattern:
Pull
Use GET to fetch the product data you need — requirements, components, product details, residual risks, or vulnerabilities.
Process
Transform or generate content in your own environment — draft CVSS justifications, score risks, triage vulnerabilities, fill requirement narratives.
Import
Send the results back via the resource's /import endpoint. Start from the pre-populated template and match on publicUniqueId.
Review & Approve
A team member reviews all proposed changes on the staged review screen before anything is committed to the production file.
6 Versioning & Errors
| Status | Meaning |
|---|---|
| 200 | Import accepted — asynchronously staged for review. Poll GET /Products/imports for job status. Content validation surfaces on the review screen. |
| 401 | Missing or invalid X-Api-Key header |
| 404 | Unknown product or resource id |
The API is versioned in the path (/api/v1). For the exact, current column layout of any import, download that resource's import template — it is the authoritative schema.
7 Quick Field Reference
Key fields returned by the most commonly used GET endpoints.
Requirement
id, requirementUniqueId, publicUniqueId, applicable, securityRequirement, requirementAddendum, requirementStatus, statusNotes, howWillThisBeMet, testingNotes, vvId, componentId, componentName, threatUniqueIds, securityDomain, category, controlType, mdS2, nistcsf, nistcsfCategories, nisT80053Category, nisT80053Control, isO27001Control, fdaAppendixControlCategories
Residual Risk
id, residualRiskId, publicUniqueId, residualRiskStatus, componentId, componentName, threatId, mitigationDetails, remediationPlan, remediationDetails, considerationforIFULabeling, cvssScore, attackVector, attackComplexity, privilegesRequired, userInteraction, scope, confidentiality, integrity, availability, potentialSafetyRisk, vulnerabilityIds, requirementsMet, requirementsNotMet
Component
componentId, componentName, componentType, description, descriptionAddendum, trustBoundaryName, parentComponentIds, childComponentIds
Product
Product, Profile, DeviceClassification, RegulatorySubmissionType, Description, CyberSecurityDetails, CVSS31Enabled, CVSS40Enabled, Components
Ready to start building?
Get your API key from your Product Security Hub tenant settings and start pulling product data in minutes.