# 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).
