GET/v1/products/{productId}/sboms
Uploads eines Produkts auflisten
Gibt die Uploads des Produkts zurück, die neuesten zuerst, jeweils mit der Angabe, ob er auf dem Markt ist und ob er überwacht wird. Erfordert die Berechtigung sboms:read.
Scope: sboms:read
Parameter
Antworten
200 Die Uploads des Produkts. SBOMList
{
"sboms": [
{
"id": "5d7e9f10-2b4c-4d6e-8f90-a1b2c3d4e5f6",
"product_id": "3f1b0c9e-6a27-4f5b-9c1d-2e8a7b4d5c60",
"format": "cyclonedx",
"spec_version": "1.6",
"sha256": "9f2c4a7b1e3d5f60829a4b6c8d0e1f2a3b4c5d6e7f80910a2b3c4d5e6f708192",
"component_count": 412,
"source": "api",
"created_at": "2026-09-18T06:31:10Z",
"release": "2.4.1",
"on_market": true,
"monitored": true
}
]
}
Beispiel
curl --fail-with-body -sS \
-H "Authorization: Bearer $BITHIVE_TOKEN" \
"https://app.bithive-it.com/v1/products/$PRODUCTID/sboms"
POST/v1/products/{productId}/sboms
Stückliste für ein Produkt hochladen
Speichert ein CycloneDX- oder SPDX-Dokument in JSON, höchstens 10 MiB groß, und indexiert seine Komponenten. Das Format wird aus dem Dokument gelesen, nicht aus dem Content-Type. Werden dieselben Bytes für dasselbe Produkt erneut hochgeladen, lautet die Antwort 200 mit dem vorhandenen Upload, statt ein zweites Mal zu speichern; eine Build-Pipeline, die auf einem unveränderten Quellstand zweimal läuft, richtet also keinen Schaden an.
Überwacht wird jede Produktversion auf dem Markt, nicht nur der neueste Upload (Cyberresilienz-Verordnung, Artikel 14). Benennen Sie die Produktversion mit release und geben Sie mit on_market=true an, dass sie auf dem Markt ist; dann bleibt sie auch nach neueren Uploads überwacht. Der neueste Upload eines Produkts wird immer überwacht. Bis zu 25 Produktversionen eines Produkts können auf dem Markt sein, in jedem Tarif; sie zählen nicht zur Produktgrenze. Wegen dieser Obergrenze von 25 wird ein Upload nie abgewiesen: Darüber hinaus wird das Dokument gespeichert, und on_market_refused ist true. Wird dasselbe Dokument erneut hochgeladen, gilt ein mitgegebenes release oder on_market=true trotzdem; on_market=false ändert nichts (eine Produktversion nehmen Sie mit PATCH /v1/sboms/{sbomId} vom Markt).
Keine Stückliste zur Hand? Senden Sie die Lockfiles oder Manifeste, die Ihr Build schon hat, als multipart/form-data, jede Datei in einem Teil namens file (API 0.9.0): package-lock.json (npm), poetry.lock oder eine requirements.txt mit exakten Versionen (PyPI), go.mod mit seiner go.sum (Go), packages.lock.json (NuGet) oder eine pom.xml (Maven). Der Reporting Desk schreibt daraus auf seinen eigenen Servern ein CycloneDX-Dokument und speichert es wie ein hochgeladenes, mit generated_from, das die Dateien nennt. Die Dateien werden nur gelesen: Nichts wird installiert, abgerufen oder ausgeführt, und die Dateien selbst werden nicht aufbewahrt. Eine pom.xml nennt keine transitive Abhängigkeit, ein go.mod für ein Go vor 1.17 nennt nur die direkten, eine requirements.txt nennt sie nur, wenn jede festgelegte Zeile einen --hash trägt, wie pip-compile --generate-hashes sie schreibt (pip installiert dann nichts, was die Datei nicht nennt), und eine Zeile einer requirements.txt ohne exakte Version nennt keine Version: Das Dokument ist dann als partial gekennzeichnet, und left_out zählt, was keine exakte Version hatte. Höchstens 20 Dateien mit je 2 MiB und höchstens 10 geschriebene Dokumente pro Stunde für ein Konto (darüber 429; dieselben Dateien erneut speichern nichts Neues und gehen immer durch). Der Reporting Desk schreibt höchstens zwei solche Dokumente gleichzeitig und eines je Konto: Eine Anfrage darüber hinaus wird abgewiesen, bevor etwas davon gelesen ist, mit 429, solange eine andere Anfrage des Kontos geschrieben wird, und mit 503, solange andere geschrieben werden, jeweils mit Retry-After in Sekunden. Eine Anfrage für ein Produkt, das das Konto nicht hat, oder über der Stundengrenze für ein Produkt, zu dem noch kein Dokument aus Lockfiles geschrieben wurde, wird ebenfalls abgewiesen, bevor sie gelesen ist. Dieselben Dateien unter denselben Namen ergeben dasselbe Dokument; sie erneut zu senden, ergibt also 200.
Erfordert die Berechtigung sboms:upload, die hochlädt und sonst nichts, oder sboms:write. Nimmt einen Idempotency-Key an.
Scope: sboms:write
Parameter
Anfragekörper
Das Dokument selbst, so wie das Build-Werkzeug es sendet; oder Lockfiles und Manifeste als `multipart/form-data`, jede Datei in einem Teil namens `file`.
application/jsonapplication/vnd.cyclonedx+jsonapplication/spdx+jsonmultipart/form-data
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"components": [
{
"name": "openssl",
"version": "3.0.8",
"purl": "pkg:generic/openssl@3.0.8"
},
{
"name": "zlib",
"version": "1.2.13"
}
]
}
Antworten
200 Dasselbe Dokument war für dieses Produkt bereits gespeichert; nichts Neues wurde gespeichert, ein mitgegebenes `release` oder `on_market=true` wurde aber übernommen. SBOM
{
"id": "5d7e9f10-2b4c-4d6e-8f90-a1b2c3d4e5f6",
"product_id": "3f1b0c9e-6a27-4f5b-9c1d-2e8a7b4d5c60",
"format": "cyclonedx",
"spec_version": "1.6",
"sha256": "9f2c4a7b1e3d5f60829a4b6c8d0e1f2a3b4c5d6e7f80910a2b3c4d5e6f708192",
"component_count": 412,
"source": "api",
"created_at": "2026-09-18T06:31:10Z",
"release": "2.4.1",
"on_market": true,
"monitored": true
}
400 Das Dokument ist leer, kein JSON, in keinem der beiden Formate oder führt etwas Unbrauchbares auf. Problem
{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "The document is not JSON."
}
415 Der Content-Type ist keiner der angenommenen JSON-Typen. Problem
{
"type": "about:blank",
"title": "Unsupported Media Type",
"status": 415,
"detail": "Send the document as application/json, application/vnd.cyclonedx+json or application/spdx+json."
}
422 Der Name der Produktversion ist länger als 100 Zeichen oder enthält einen Zeilenumbruch oder ein anderes Steuerzeichen. Problem
{
"type": "about:blank",
"title": "Unprocessable Entity",
"status": 422,
"detail": "A release name is at most 100 characters, on one line."
}
503 Nur bei Lockfiles: Der Reporting Desk schreibt gerade so viele Dokumente aus Lockfiles, wie er gleichzeitig schreibt. Nichts wurde gelesen oder gespeichert; senden Sie die Dateien nach `Retry-After` erneut. Problem
Beispiel
Beispiel
curl --fail-with-body -sS -X POST \
-H "Authorization: Bearer $BITHIVE_TOKEN" \
-H "Content-Type: application/vnd.cyclonedx+json" \
--data-binary @sbom.json \
"https://app.bithive-it.com/v1/products/$PRODUCTID/sboms"
PATCH/v1/sboms/{sbomId}
Produktversion benennen, auf den Markt bringen oder vom Markt nehmen
Ändert, was über die Produktversion gesagt ist, die ein Upload beschreibt: ihren Namen und ob sie auf dem Markt ist. Eine Produktversion auf dem Markt wird auch nach neueren Uploads überwacht; eine vom Markt genommene eröffnet keine neuen Fälle mehr, und die bereits offenen Fälle bleiben bestehen. Ein weggelassenes Feld bleibt, wie es ist. Bis zu 25 Produktversionen eines Produkts können auf dem Markt sein; darüber hinaus wird die Änderung mit 409 abgewiesen, und nichts davon wird übernommen. Jede Änderung wird im Protokoll des Kontos als Änderung des Tokens erfasst. Erfordert die Berechtigung sboms:write. Nimmt einen Idempotency-Key an.
Scope: sboms:write
Parameter
Anfragekörper
{
"on_market": true
}
Antworten
400 Das Dokument ist leer, kein JSON, in keinem der beiden Formate oder führt etwas Unbrauchbares auf. Problem
Beispiel
409 Das Produkt hat bereits so viele Produktversionen auf dem Markt, wie es haben darf. Problem
{
"type": "about:blank",
"title": "Conflict",
"status": 409,
"detail": "This product already has 25 releases on the market. Take one off first, with \"on_market\": false."
}
415 Der Content-Type ist keiner der angenommenen JSON-Typen. Problem
Beispiel
422 Der Name der Produktversion ist länger als 100 Zeichen oder enthält einen Zeilenumbruch oder ein anderes Steuerzeichen. Problem
Beispiel
Beispiel
curl --fail-with-body -sS -X PATCH \
-H "Authorization: Bearer $BITHIVE_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @release-change.json \
"https://app.bithive-it.com/v1/sboms/$SBOMID"