Upload evidence attachments
Uploads one or more files to an evidence record.
Maximum 5 files per request. Combined size must not exceed 100 MB.
evidenceDate is Unix epoch milliseconds and cannot be in the future.
Idempotency-Key is required. The same key and payload replays the stored 2xx for 24 hours.
Requires scope evidence:write.
One or more files in a supported format. See Supported file types in this operation description. Use the multipart field files for every attachment (same field name for each file, up to 5 per request). Example: -F "files=@access-review.pdf" -F "files=@appendix.pdf".
Example request (cURL)
For file uploads, copy this command (includes -F "files=@…"). The auto-generated cURL tab may show a text placeholder for files until you choose a file in the playground.
curl -X POST "https://api.scrut.io/v1/evidence/92af7e7f-b18e-495b-bf92-61c23ebd34a7/attachments" \
-H "Authorization: Bearer $SCRUT_ACCESS_TOKEN" \
-H "Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \
-F "evidenceDate=1715904000000" \
-F "note=Q2 access review — identity verification records" \
-F "files=@access-review.pdf"
Supported file types
Same list as Upload Evidence — Supported File Types.
| Type | Extensions |
|---|---|
| Word | .doc, .docx, .dotx |
| Excel | .xls, .xlsx, .xlsm |
| PowerPoint | .ppt, .pptx |
| Text | .txt, .log, .html |
| Markdown | .md |
| YAML | .yaml, .yml |
| CSV | .csv |
| JSON | .json |
| XML | .xml |
| Images | Any image type, such as PNG, JPG, GIF, SVG |
| Video | .mp4, .avi |
| Audio | .mp3, .wav |
| Archives | .zip, .rar |
| Apple iWork | .numbers, .pages |
| .eml, .msg | |
| Other | .dwf, .evtx |
Note: Scrut accepts Apple iWork files (.numbers, .pages) only when it detects them as zip packages. If Scrut rejects an iWork file, export it to PDF, Excel, or Word and upload it again.
curl -X POST "https://api.scrut.io/v1/evidence/92af7e7f-b18e-495b-bf92-61c23ebd34a7/attachments" \
-H "Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \
-H "Authorization: Bearer YOUR_API_TOKEN (JWT)" \
--form evidenceDate=1715904000000 \
--form note=Q2 access review — identity verification records \
--form files=@access-review.pdf
import requests
import json
url = "https://api.scrut.io/v1/evidence/92af7e7f-b18e-495b-bf92-61c23ebd34a7/attachments"
headers = {
"Idempotency-Key": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"Authorization": "Bearer YOUR_API_TOKEN (JWT)"
}
data = {
"evidenceDate": "1715904000000",
"note": "Q2 access review — identity verification records",
"files": "@access-review.pdf"
}
response = requests.post(url, headers=headers, data=data)
print(response.json())
const formData = new FormData();
formData.append("evidenceDate", "1715904000000");
formData.append("note", "Q2 access review — identity verification records");
formData.append("files", "@access-review.pdf");
const response = await fetch("https://api.scrut.io/v1/evidence/92af7e7f-b18e-495b-bf92-61c23ebd34a7/attachments", {
method: "POST",
headers: {
"Idempotency-Key": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"Authorization": "Bearer YOUR_API_TOKEN (JWT)"
},
body: formData
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"mime/multipart"
)
func main() {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
writer.WriteField("evidenceDate", "1715904000000")
writer.WriteField("note", "Q2 access review — identity verification records")
writer.WriteField("files", "@access-review.pdf")
writer.Close()
req, err := http.NewRequest("POST", "https://api.scrut.io/v1/evidence/92af7e7f-b18e-495b-bf92-61c23ebd34a7/attachments", body)
if err != nil {
panic(err)
}
req.Header.Set("Idempotency-Key", "7c9e6679-7425-40de-944b-e07fc1f90ae7")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN (JWT)")
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://api.scrut.io/v1/evidence/92af7e7f-b18e-495b-bf92-61c23ebd34a7/attachments')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Idempotency-Key'] = '7c9e6679-7425-40de-944b-e07fc1f90ae7'
request['Authorization'] = 'Bearer YOUR_API_TOKEN (JWT)'
request.set_form([
["evidenceDate", "1715904000000"],
["note", "Q2 access review — identity verification records"],
["files", "@access-review.pdf"]
], 'multipart/form-data')
response = http.request(request)
puts response.body
{
"data": {
"evidenceId": "92af7e7f-b18e-495b-bf92-61c23ebd34a7",
"modifiedOn": 1711929600000
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "validation_failed",
"message": "Request validation failed.",
"details": [
{
"field": "status",
"message": "status contains unknown value(s): unknown"
}
]
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "unauthorized",
"message": "Missing, malformed, or invalid Bearer token.",
"details": []
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "token_revoked",
"message": "The API credential was revoked.",
"details": []
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "token_stale",
"message": "The access token is stale; obtain a new token.",
"details": []
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "forbidden",
"message": "Insufficient scope.",
"details": []
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "not_found",
"message": "The requested resource was not found.",
"details": []
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "idempotency_key_reused",
"message": "Idempotency key was reused with a different request body.",
"details": []
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "idempotency_request_in_progress",
"message": "A request with this idempotency key is already being processed.",
"details": []
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded.",
"details": [
{
"retryAfterSec": 12
}
]
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "internal_error",
"message": "An unexpected error occurred.",
"details": []
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
{
"error": {
"code": "upstream_unavailable",
"message": "Upstream service is unavailable.",
"details": [
{
"dependency": "frameworks",
"issue": "Failed to process frameworks."
}
]
},
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
/v1/evidence/{evidenceId}/attachmentsTarget server for requests. Edit to use your own host.
Machine access token from POST /oauth/token. Send Authorization: Bearer $SCRUT_ACCESS_TOKEN on every /v1 request.
POST /oauth/token. Send Authorization: Bearer $SCRUT_ACCESS_TOKEN on every /v1 request.Evidence identifier returned by list and get endpoints.
The media type of the request body
Client-generated key identifying one logical write. 1–128 characters; letters, numbers, and . _ ~ - only. Reuse the same key and body to retry safely. Reusing a key with a different body returns 409 idempotency_key_reused. Successful 2xx responses are replayed for 24 hours.
Unix epoch milliseconds (number or numeric string). Must not be in the future.
Optional note stored with the upload.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token (JWT). Machine access token from POST /oauth/token. Send Authorization: Bearer $SCRUT_ACCESS_TOKEN on every /v1 request.
Path Parameters
Evidence identifier returned by list and get endpoints.
92af7e7f-b18e-495b-bf92-61c23ebd34a7Headers
Client-generated key identifying one logical write. 1–128 characters; letters, numbers, and . _ ~ - only. Reuse the same key and body to retry safely. Reusing a key with a different body returns 409 idempotency_key_reused. Successful 2xx responses are replayed for 24 hours.
7c9e6679-7425-40de-944b-e07fc1f90ae7Body
Unix epoch milliseconds (number or numeric string). Must not be in the future.
1715904000000Optional note stored with the upload.
Q2 access review — identity verification records@access-review.pdf