# Upload Evidence API

The Upload Evidence API allows you to programmatically upload evidence files to Sprinto monitors (controls and workflow checks) using a REST endpoint.

Use this API to automate evidence collection from CI/CD pipelines, internal tools, or third-party systems.

***

### How it works

The API accepts a `multipart/form-data` request with:

* `monitor_pk` to identify the target monitor
* One or more files as evidence

Sprinto validates the request, uploads the files, and attaches them to the specified monitor.

***

### Endpoint

<table><thead><tr><th width="155.01171875">Property</th><th width="443.82421875">Value</th></tr></thead><tbody><tr><td>URL</td><td><code>https://app.sprinto.com/api/v1/uploadEvidence</code></td></tr><tr><td>Method</td><td>POST</td></tr><tr><td>Content-Type</td><td>multipart/form-data</td></tr><tr><td>Authentication</td><td>API Token (header)</td></tr></tbody></table>

***

### Authentication

Generate API tokens from **Settings > Developer API**.

#### Header

```
api-token: <your-api-token>
```

#### Guidelines

* Keep tokens secure
* Use HTTPS only
* Ensure Admin-level permissions

***

### Request

#### Headers

<table><thead><tr><th width="160.84765625">Header</th><th width="120.38671875">Required</th><th width="188.26953125">Description</th></tr></thead><tbody><tr><td>api-token</td><td>Yes</td><td>API token</td></tr><tr><td>Content-Type</td><td>Yes</td><td>multipart/form-data</td></tr></tbody></table>

***

#### Body parameters

<table><thead><tr><th width="132.5234375">Parameter</th><th width="81.55859375">Type</th><th width="107.5">Required</th><th width="410.6640625">Description</th></tr></thead><tbody><tr><td>monitor_pk</td><td>string</td><td>Yes</td><td>The unique identifier (PK) of the monitor (control or workflow check) to which you want to upload evidence.</td></tr><tr><td>files</td><td>file</td><td>Yes</td><td>The evidence file(s) to upload. You can upload up to 10 files in a single request by repeating this field.</td></tr></tbody></table>

{% hint style="info" %}

#### Note

1. To upload multiple files, include the `files` field multiple times in the same request. Each occurrence should contain one file.
2. The `check_pk` parameter is deprecated. Use `monitor_pk`.
   {% endhint %}

***

### Examples

{% tabs %}
{% tab title="cURL" %}

```javascript
curl --request POST 'https://app.sprinto.com/api/v1/uploadEvidence' \
--header 'api-token: your-api-token' \
--form 'files=@/path/to/file.pdf;type=application/pdf' \
--form 'files=@file1.pdf' \
--form 'files=@file2.pdf' \
--form 'monitor_pk=your-monitor-pk'
--form 'monitor_pk=your-monitor-pk'
```

{% endtab %}

{% tab title="Node.js (Axios)" %}

```js
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

const data = new FormData();
data.append('files', fs.createReadStream('/path/to/file.pdf'));
data.append('monitor_pk', 'your-monitor-pk');

axios.post('https://app.sprinto.com/api/v1/uploadEvidence', data, {
  headers: {
    'api-token': 'your-api-token',
    ...data.getHeaders()
  }
})
.then(res => console.log(res.data))
.catch(err => console.error(err));
```

{% endtab %}

{% tab title="Ruby" %}

```python
import requests

url = 'https://app.sprinto.com/api/v1/uploadEvidence'

headers = {
    'api-token': 'your-api-token'
}

files = {
    'files': ('file.pdf', open('/path/to/file.pdf', 'rb'), 'application/pdf')
}

data = {
    'monitor_pk': 'your-monitor-pk'
}

response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())
```

{% endtab %}

{% tab title="HTTP" %}
POST /api/v1/uploadEvidence HTTP/1.1\
Host: app.sprinto.com\
api-token: your-api-token\
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

\------WebKitFormBoundary7MA4YWxkTrZu0gW\
Content-Disposition: form-data; name="files"; filename="file.pdf"\
Content-Type: application/pdf

(data)\
\------WebKitFormBoundary7MA4YWxkTrZu0gW\
Content-Disposition: form-data; name="monitor\_pk"

your-monitor-pk\
\------WebKitFormBoundary7MA4YWxkTrZu0gW
{% endtab %}
{% endtabs %}

***

### Response

#### Success (201 Created)

```json
{
  "success": true,
  "error": ""
}
```

***

#### Response fields

<table><thead><tr><th width="107.2421875">Field</th><th width="145.33203125">Type</th><th width="331.1640625">Description</th></tr></thead><tbody><tr><td>success</td><td>boolean</td><td>Indicates if the request succeeded</td></tr><tr><td>error</td><td>string / object</td><td>Error message (empty if successful)</td></tr></tbody></table>

***

### Error handling

#### 400 Bad Request

* Invalid file type
* Invalid parameters
* Monitor not found

```json
{
  "success": false,
  "error": "Monitor with pk <monitor_pk> not found."
}
```

***

#### 401 Unauthorized

```json
{
  "success": false,
  "error": {
    "message": "api-token not found"
  }
}
```

**Causes**

* Missing or invalid token
* Insufficient permissions

***

#### 429 Too Many Requests

Returned when rate limits are exceeded. Implement retry with backoff.

***

### Supported file types

<table><thead><tr><th width="144.40625">Category</th><th width="331.31640625">Extensions</th></tr></thead><tbody><tr><td>Images</td><td>.jpg, .jpeg, .png, .gif, .tiff, .bmp, .svg</td></tr><tr><td>Documents</td><td>.pdf, .doc, .docx, .odt</td></tr><tr><td>Spreadsheets</td><td>.xls, .xlsx, .ods</td></tr><tr><td>Archives</td><td>.zip, .tar</td></tr><tr><td>Videos</td><td>.mp4, .mov, .wmv</td></tr><tr><td>Data</td><td>.json, .csv, .txt</td></tr><tr><td>Email</td><td>.msg</td></tr></tbody></table>

#### Limits

* Maximum file size: 10 MB per file
* Maximum files per request: 10

***

### Finding the monitor PK

#### From dashboard

Navigate to the monitor and locate the PK in the URL or details section.

#### Using GraphQL

```graphql
query {
  monitors {
    nodes {
      pk
      name
      monitorType
    }
  }
}
```

***

### Workflow check restrictions

* Must be active
* Must not have a reviewer assigned

***

### Troubleshooting

<table><thead><tr><th width="201.3046875">Issue</th><th width="197.76953125">Cause</th><th width="275.34765625">Resolution</th></tr></thead><tbody><tr><td>401 Unauthorized</td><td>Invalid token</td><td>Verify API token</td></tr><tr><td>File type not allowed</td><td>Unsupported format</td><td>Use supported file types</td></tr><tr><td>Monitor not found</td><td>Invalid monitor_pk</td><td>Validate monitor PK</td></tr><tr><td>File too large</td><td>Exceeds 10 MB</td><td>Reduce file size</td></tr><tr><td>Evidence not visible</td><td>Processing delay</td><td>Refresh after a few seconds</td></tr></tbody></table>

***

### Need help?

If you have questions or run into issues while using the Upload Evidence API, contact [Sprinto support](mailto:support@sprinto.com).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sprinto.com/api-references/upload-evidence-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
