---
metadata:
  - name: generator
    content: Diplodoc Platform v5.64.0
alternate:
  - https://sourcecraft.dev/portal/docs/en/sec-api-ref/Report-Upload/v1reportsupload-post.md
  - https://sourcecraft.dev/portal/docs/ru/sec-api-ref/Report-Upload/v1reportsupload-post.md
  - href: https://sourcecraft.dev/portal/docs/en/sec-api-ref/Report-Upload/v1reportsupload-post.md
    type: text/markdown
    title: Markdown version
  - href: https://sourcecraft.dev/portal/docs/en/llms.txt?revision=r21725674
    rel: describedby
---
> **Documentation Index:** Fetch the complete configuration index at https://sourcecraft.dev/portal/docs/en/llms.txt?revision=r21725674

<div class="openapi">

# Upload a security analysis report

<!-- markdownlint-disable-file -->

Accepts a SARIF/SBOM/TEXT/AUDIT report as multipart/form-data and processes it for the given repository.

The `file` part can be either a raw report file or a ZIP archive.

ZIP archive requirements:
- exactly one report file;
- the report file must be in the archive root;
- directories, nested paths, and extra files are rejected;
- the single uncompressed entry must be no larger than 100 MB.

The file content must match `reportType`: SARIF uploads should contain a SARIF report, and SBOM uploads should contain SPDX or CycloneDX JSON. The REST request body is limited to 100 MB.

Create archives without parent directories: `zip report.zip report.sarif`. Do not zip a folder with `zip -r report.zip reports/`, because nested paths are rejected.

Set `isReactive=true` to process in the background — note that it answers 202 before parsing, so a report rejected later is reported only in the logs. Keep the default `isReactive=false` to get 400 with the reason the report was rejected, which is what an AUDIT upload needs: its message names every result and field to fix before uploading the corrected report again.

## Request

<div class="openapi__requests">

<div class="openapi__request__wrapper" style="--method: var(--dc-openapi-methods-post);margin-bottom: 12px">

<div class="openapi__request">

POST {.openapi__method}
```text translate=no
https://appsec.sourcecraft.tech/v1/reports/upload
```

</div>

</div>

</div>

### Query parameters

#|
|| **Name** | **Description** ||
||

_gitRepo_{.json-schema-reset .json-schema-property .json-schema-required}
{.table-cell}|
**Type**: string

Repository identifier. Accepts either internal repository ID (e.g., 88769874964302633) or public UUID (e.g., 0199140f-4343-7c06-a7e3-b835c305b629). These values can be obtained from the getRepo API (fields: id and uuid).

_Pattern:_{.json-schema-reset .json-schema-assertion} `\S`

_Example:_{.json-schema-reset .json-schema-example} `0199140f-4343-7c06-a7e3-b835c305b629`
{.table-cell}
||
|#{.json-schema-properties}

<div class="openapi-entity">

### Body

{% cut "multipart/form-data" %}

```json translate=no
{
  "file": "example",
  "commit": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
  "engineName": "Trivy",
  "reportType": "SARIF",
  "engineType": "SCA",
  "scanBasePathAbsolute": "/home/user/workspace/my-project",
  "scanTime": 1640995200000,
  "shouldTriggerEnrichment": true,
  "isReactive": true,
  "scanUuid": "example",
  "expectedReportCount": 3,
  "prUuid": "example",
  "reactive": true
}
```

{% endcut %}

#|
|| **Name** | **Description** ||
||

_commit_{.json-schema-reset .json-schema-property .json-schema-required}
{.table-cell}|
**Type**: string

Full SHA commit hash identifying the scanned code revision.

_Example:_{.json-schema-reset .json-schema-example} `a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2`
{.table-cell}
||
||

_engineName_{.json-schema-reset .json-schema-property .json-schema-required}
{.table-cell}|
**Type**: string

Human-readable name of the analysis tool that produced the report.

_Example:_{.json-schema-reset .json-schema-example} `Trivy`
{.table-cell}
||
||

_file_{.json-schema-reset .json-schema-property .json-schema-required}
{.table-cell}|
**Type**: string&lt;binary&gt;

Raw report file content, or a ZIP archive with exactly one report file in the archive root. Do not include directories or extra files. The uncompressed ZIP entry must be no larger than 100 MB.

_Example:_{.json-schema-reset .json-schema-example} `example`
{.table-cell}
||
||

_reportType_{.json-schema-reset .json-schema-property .json-schema-required}
{.table-cell}|
**Type**: string

Format of the uploaded report.

_Enum:_{.json-schema-reset .json-schema-value} `TEXT`, `SARIF`, `SBOM`, `JSON`, `DIR`, `AUDIT`
{.table-cell}
||
||

_engineType_{.json-schema-reset .json-schema-property}
{.table-cell}|
**Type**: string

Category of the analysis engine. Defaults to UNSPECIFIED when absent.

_Enum:_{.json-schema-reset .json-schema-value} `UNSPECIFIED`, `SECRETS`, `SCA`, `SAST`, `SA`, `SBOM_SPDX`, `SBOM_CYCLONEDX`
{.table-cell}
||
||

_expectedReportCount_{.json-schema-reset .json-schema-property}
{.table-cell}|
**Type**: integer &#124; null

Total reports expected for a scan across all uploaders. Sets the total for a new scan or an existing scan whose total is still zero; a nonzero total is preserved. Omit or send zero when unknown (legacy clients).

_Min value:_{.json-schema-reset .json-schema-assertion} `0`
{.table-cell}
||
||

_isReactive_{.json-schema-reset .json-schema-property}
{.table-cell}|
**Type**: boolean

When true, respond 202 immediately and process the report in the background; otherwise process synchronously and respond 200 (or 400 on parse errors).
{.table-cell}
||
||

_prUuid_{.json-schema-reset .json-schema-property}
{.table-cell}|
**Type**: string &#124; null

Pull Request UUID (CI env SOURCECRAFT_PR_UUID).

_Example:_{.json-schema-reset .json-schema-example} `example`
{.table-cell}
||
||

_reactive_{.json-schema-reset .json-schema-property}
{.table-cell}|
**Type**: boolean
{.table-cell}
||
||

_scanBasePathAbsolute_{.json-schema-reset .json-schema-property}
{.table-cell}|
**Type**: string &#124; null

Absolute path where the scan ran; stripped from report file paths for normalization.

_Example:_{.json-schema-reset .json-schema-example} `/home/user/workspace/my-project`
{.table-cell}
||
||

_scanTime_{.json-schema-reset .json-schema-property}
{.table-cell}|
**Type**: integer

Unix timestamp (ms) when the scan was initiated.
{.table-cell}
||
||

_scanUuid_{.json-schema-reset .json-schema-property}
{.table-cell}|
**Type**: string &#124; null

Scan UUID. Used as the HMAC payload for SBOM upload tokens.

_Example:_{.json-schema-reset .json-schema-example} `example`
{.table-cell}
||
||

_shouldTriggerEnrichment_{.json-schema-reset .json-schema-property}
{.table-cell}|
**Type**: boolean

When true, run additional security enrichment (SCA, risk scoring, etc.).
{.table-cell}
||
|#{.json-schema-properties}

</div>

## Responses

<div class="openapi__response__code__200">

## 200 OK

Report processed successfully (synchronous mode)

<div class="openapi-entity">

### Body

{% cut "application/json" %}

`null`

{% endcut %}

**Type**: unknown

</div>

</div>

<div class="openapi__response__code__202">

## 202 Accepted

Report accepted for background processing (isReactive=true)

</div>

<div class="openapi__response__code__400">

## 400 Bad Request

Invalid request: missing/invalid fields or unparseable report

</div>

<div class="openapi__response__code__401">

## 401 Unauthorized

Missing or invalid authorization token

</div>

<div class="openapi__response__code__403">

## 403 Forbidden

Permission denied or security disabled for the repository

</div>

<div class="openapi__response__code__404">

## 404 Not Found

Repository not found

</div>

</div>

[*Deprecated]: No longer supported, please use an alternative and newer version.