Generate an SBOM from uploaded files
Generate a dependency inventory from manifest and lockfile uploads without creating a project. Manifest-only inputs resolve concrete versions and transitives. Compatible lockfiles supply recorded versions for associated manifests; uncovered manifests resolve separately.
First request
Use a GitHits Bearer credential for an active account with the required terms accepted. In the example, private-auth.conf is a caller-owned protected curl configuration containing header = "Authorization: Bearer <token>"; replace the placeholder privately. Run from your repository root:
curl --config /path/to/private-auth.conf \
--fail-with-body --silent --show-error \
--form 'files[]=@Cargo.toml;filename=Cargo.toml' \
--form 'files[]=@Cargo.lock;filename=Cargo.lock' \
--output bom.cdx.json \
'https://api.githits.dev/v1/experimental/sbom?format=cyclonedx'
For npm, replace the two files with package.json and package-lock.json. For a nested project, use both the actual local path and the repository-relative filename, for example files[]=@app/package.json;filename=app/package.json. Repeat files[] for each file. Let curl set Content-Type and the multipart boundary. Send individual manifests and lockfiles, not an archive, repository URL or base64 data.
On success the output file contains the document itself. On an HTTP error, curl exits unsuccessfully and saves a JSON problem in that file; check the exit status before importing it as an SBOM.
Upload rules
Send repeated files[] parts with repository-relative filenames and raw UTF-8 contents. Keep directories intact, for example app/package.json and app/package-lock.json. Only files[] and optional format are accepted. The complete multipart body, including framing, is limited to 8,000,000 bytes: 1–256 files, each at most 5,242,880 bytes, with filenames at most 1,024 UTF-8 bytes. Empty, dot and parent path segments, backslashes and controls are invalid. Unknown fields, missing filenames and duplicate format values in one location are rejected. A malformed query format is invalid even when multipart supplies a format.
Supported lockfile families include Cargo, npm, pnpm, Yarn classic and Berry, uv, Poetry, PDM, Pipenv, Swift, Gradle, NuGet, Dart, Composer, Mix, Bundler, Rebar, Conan and Go dep. Filename and contents determine recognition; renaming an unsupported file does not add support. Lockfiles can be uploaded alone. A compatible same-directory lockfile supplies recorded versions for its manifest; this does not verify that the lockfile is up to date. For monorepos, preserve all relative paths; a nested manifest does not automatically inherit an ancestor lockfile.
Choose an output
format | Response Content-Type | Contents |
|---|---|---|
cyclonedx (default) | application/vnd.cyclonedx+json | CycloneDX 1.7 JSON |
spdx | text/spdx | SPDX 2.3 tag-value, not JSON |
text | text/plain | Human-readable inventory report, not a standard SBOM serialization |
All outputs use UTF-8 and are limited to 16,777,216 bytes. Change the example’s query to ?format=spdx or ?format=text, or add --form 'format=spdx'; the multipart value wins. Accept does not select the format. Success returns HTTP 200 with the direct document, without a JSON wrapper or retrieval URL. No fields selector is supported.
Standard document fields retain their standard spelling. The response schema describes an extensible subset of CycloneDX 1.7, not a field allowlist: additional standard metadata, component, license, dependency and other fields are accepted at every object level. Clients must preserve or ignore unfamiliar fields. SPDX tag-value documents may likewise include additional standard fields.
Interpret the inventory
One unusable file rejects the upload. Incomplete resolution and missing licenses can still produce a successful partial document. License declarations are evidence, not legal conclusions or artifact verification. Lockfile agreement and platform conditions are not checked. Preserve completeness, provenance, license expression/name variants and optional PURLs when consuming the result.
In CycloneDX, find the document-level property named githits:completeness by name rather than array position:
| Value | Meaning |
|---|---|
resolved_manifest_inventory | Inventory from manifest dependency resolution |
partial_manifest_inventory | Resolution is incomplete; the component list can be empty |
recorded_lockfile_inventory | Inventory recorded in uploaded lockfiles |
mixed_dependency_inventory | Lockfile records plus separately resolved manifests |
None guarantees an exact installed inventory or complete license coverage. Inspect githits:resolutions and githits:manifest_associations for per-manifest evidence. Structured githits: property values are JSON encoded inside strings and require a separate decode. Component names are not unique; retain bom-ref for document relationships. A missing version, PURL or license means unavailable evidence, not permission to invent a value.
Handle errors and retries
Errors use application/problem+json in every output format. Branch on code, not detail, and retain X-Request-ID for support. The response definitions below provide problem schemas and examples.
| Status / code | Caller action |
|---|---|
400 VALIDATION_ERROR | Correct multipart fields, filenames or format values before retrying. |
401 AUTHENTICATION_REQUIRED | Supply a valid Bearer credential. |
403 FORBIDDEN, ACCOUNT_INACTIVE, TERMS_ACCEPTANCE_REQUIRED | Resolve credential access, account eligibility or terms acceptance. |
408 UPLOAD_TIMEOUT | Ensure the upload can finish within 30 seconds. |
413 INPUT_TOO_LARGE | Reduce file count, path length or bytes to the documented limits. |
415 UNSUPPORTED_MEDIA_TYPE | Send multipart/form-data with a valid boundary. |
422 UNUSABLE_MANIFEST | Inspect files: each entry identifies the original path and status (unsupported, invalid_utf8 or unparsed). Correct or remove those inputs; the entire upload was rejected. |
422 NO_MANIFEST_EVIDENCE | Supply a manifest with named package evidence or a supported lockfile. |
422 UNREPRESENTABLE_SPDX | Request cyclonedx to preserve names or versions that SPDX tag-value cannot represent. |
422 SBOM_OUTPUT_TOO_LARGE | Reduce the requested inventory; the generated document exceeded an output limit. |
429 RATE_LIMITED | Respect Retry-After when present. |
502 UPSTREAM_ERROR, 503 SBOM_UNAVAILABLE / UPSTREAM_UNAVAILABLE | A service failure prevented generation; retry later if appropriate. |
504 TIMEOUT | Generation exceeded a service deadline; a retry may repeat work. |
Uploads and documents are not retained for retrieval. Save the response. Repeated requests recompute and consume the same upstream REST quota. Client upload has a 30-second deadline; the default upstream deadline is 90 seconds, in addition to upload time. A timeout does not guarantee remote work stopped. Avoid unconditional retries: there is no idempotency key or saved result to resume.
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Optional client attribution: trimmed printable ASCII, at most 80 bytes. Invalid optional values are dropped.
Optional client-version attribution: trimmed printable ASCII, at most 80 bytes. Invalid optional values are dropped.
Optional agent attribution: trimmed printable ASCII, at most 160 bytes. Invalid optional values are dropped.
Optional session attribution: trimmed printable ASCII, at most 128 bytes. Invalid optional values are dropped; no session is created.
Query Parameters
Output format; a multipart format field overrides this value. No Accept negotiation. Duplicate values and unknown query fields are rejected. cyclonedx returns CycloneDX 1.7 JSON (application/vnd.cyclonedx+json); spdx returns SPDX 2.3 tag-value (text/spdx); text returns a human-readable report (text/plain). All outputs use UTF-8. Accept does not select the successful output format.
cyclonedx, spdx, text Body
Send a multipart upload. The complete request, including multipart headers and boundaries, must fit within 8,000,000 bytes.
Repeat the literal field name files[] once per file, with raw UTF-8 file contents rather than base64. Set each part's filename to the file's path relative to a common repository root, for example app/package.json and app/package-lock.json. Preserve directory structure so manifests can be associated with their lockfiles.
Send 1–256 files, each at most 5,242,880 bytes. Each filename must be at most 1,024 UTF-8 bytes and must be relative, with no empty, dot (.) or parent (..) path segments, backslashes or control characters. Every file must be a supported, readable manifest or lockfile; one unusable file rejects the entire upload.
1 - 256 elementsSelect the response format. This value overrides the query parameter; omit both to receive CycloneDX JSON.
cyclonedx, spdx, text Response
Complete UTF-8 document, at most 16,777,216 bytes. Inventory and license evidence may be partial; save this response because no retrieval URL is created.
Extensible CycloneDX 1.7 document. This schema describes a compatible subset, not the entire standard. Additional fields are allowed at every object level; clients must preserve or ignore unfamiliar data. Inventory and license completeness must be read from evidence, not inferred from this schema.
CycloneDX 1.7 Named project roots and dependency entries. Unresolved declarations remain in document properties rather than becoming package components. The array may be empty when no concrete packages or named roots are available. Separate lockfile occurrences may have the same name and version; do not deduplicate by those fields alone.
Completeness declaration for the listed component references.
Document evidence. githits:completeness distinguishes resolved_manifest_inventory, partial_manifest_inventory, recorded_lockfile_inventory and mixed_dependency_inventory; none guarantees that every license is known. githits:resolution_basis distinguishes manifest_resolution, lockfile_records and lockfile_records_and_manifest_resolution. Inspect githits:resolutions for per-manifest outcomes, githits:declarations for original requirements, and githits:lockfiles and githits:manifest_associations for lockfile coverage. githits:notice summarizes limitations.
Unique identifier for this generated document. This URN is not a retrieval URL.
^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$Document revision, not a package version.
x >= 1