curl --request POST \
--url https://public.api.live.turrisfi.com/v2/downstream/documents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form 'category=E&O' \
--form file=@example-file \
--form downstreamEntityId=6610b3d2c2e0a51b8c0d1f02const form = new FormData();
form.append('category', 'E&O');
form.append('file', '<string>');
form.append('downstreamEntityId', '6610b3d2c2e0a51b8c0d1f02');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://public.api.live.turrisfi.com/v2/downstream/documents', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://public.api.live.turrisfi.com/v2/downstream/documents"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"category": "E&O",
"downstreamEntityId": "6610b3d2c2e0a51b8c0d1f02"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text){
"data": {
"fileDocumentId": "66a1b2c3d4e5f6a7b8c9d0e3",
"name": "E&O Policy",
"category": "E&O",
"versions": [
{
"s3VersionId": "xN3TmQ8bJ0dY5fLpQ2rV9wK1sA6cE4hZ",
"metadataModel": "EAndOPolicy",
"size": 284913,
"mimeType": "application/pdf",
"originalFileName": "example-eando-2026.pdf"
}
],
"subCategory": "<string>",
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2026-02-12T09:00:00.000Z"
},
"requestId": "dev-2c5e7cf2-9acf-4c8c-ab2f-b81f39d775a8",
"timestamp": "2025-11-12T20:49:03.293Z"
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}Upload a Document
Upload a compliance PDF into one of four slots, or a Surplus Lines file
curl --request POST \
--url https://public.api.live.turrisfi.com/v2/downstream/documents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form 'category=E&O' \
--form file=@example-file \
--form downstreamEntityId=6610b3d2c2e0a51b8c0d1f02const form = new FormData();
form.append('category', 'E&O');
form.append('file', '<string>');
form.append('downstreamEntityId', '6610b3d2c2e0a51b8c0d1f02');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://public.api.live.turrisfi.com/v2/downstream/documents', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://public.api.live.turrisfi.com/v2/downstream/documents"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"category": "E&O",
"downstreamEntityId": "6610b3d2c2e0a51b8c0d1f02"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text){
"data": {
"fileDocumentId": "66a1b2c3d4e5f6a7b8c9d0e3",
"name": "E&O Policy",
"category": "E&O",
"versions": [
{
"s3VersionId": "xN3TmQ8bJ0dY5fLpQ2rV9wK1sA6cE4hZ",
"metadataModel": "EAndOPolicy",
"size": 284913,
"mimeType": "application/pdf",
"originalFileName": "example-eando-2026.pdf"
}
],
"subCategory": "<string>",
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2026-02-12T09:00:00.000Z"
},
"requestId": "dev-2c5e7cf2-9acf-4c8c-ab2f-b81f39d775a8",
"timestamp": "2025-11-12T20:49:03.293Z"
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}{
"statusCode": 123,
"requestId": "<string>",
"errorType": "validation_error",
"errorMessage": [
"<string>"
],
"timestamp": "<string>",
"details": {}
}multipart/form-data with the file in the file part.
A category is a slot, not a folder
An entity holds one errors-and-omissions document, one cyber, one W9, one crime-and-fidelity. Uploading into a slot the entity already fills adds a version to that document and returns the samefileDocumentId — which is what a renewal should do.
If your client expects a new id per upload, this is the one thing to change. Read fileDocumentId from the response rather than assuming it is new.
Surplus Lines uploads
The category Surplus Lines is not a slot. It is for a file you will put on a Surplus Lines filing. Every upload creates a new document;data.fileDocumentId is its id.
The file is on no filing until you attach it. Files on a Surplus Lines Filing walks through the whole flow: upload, attach, download.
To fetch any document back later, use Get a Download URL for a Document.
Limits
PDF only
10 MB maximum
Visibility
A document uploaded here is visible to you and not to your carriers. The agency application’s “share with all markets” switch is deliberately not exposed: it fans ownership out to every carrier from a single flag, and this API has no way to undo that.Extraction
Turris reads the policy details out of a compliance PDF after upload. That runs asynchronously, so the fields it populates are not on the response to this request. Poll List Documents or check the compliance status shortly afterwards. Surplus Lines uploads are not extracted. Send anIdempotency-Key header. See Idempotency.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
UUID to ensure idempotent request processing
"550e8400-e29b-41d4-a716-446655440000"
Alternative UUID header for idempotent request processing
"550e8400-e29b-41d4-a716-446655440000"
Body
Which compliance slot this document fills, or Surplus Lines for a file you will attach to a surplus-lines filing.
E&O, Cyber, Crime & Fidelity, W9, Surplus Lines "E&O"
The file to upload, 10 MB maximum. PDF only, except Surplus Lines, which also accepts DOC, DOCX, JPEG and PNG.
Which of your entities holds this document. Defaults to your own organization. Compliance is tracked per legal entity, so a branch policy must name the branch.
"6610b3d2c2e0a51b8c0d1f02"
Was this page helpful?