Skip to content

Upload a document to a contract

POST
/contracts/{id}/documents
curl --request POST \
--url https://api.vendorica.com/v1/contracts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/documents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file=@file \
--form docType=example \
--form supersedesDocumentId=example

Files a document (agreement, DPA, SLA, order form, amendment, exit plan) against an existing contract. supersedesDocumentId stamps the document it replaces in the same transaction, and a replacement inherits the type it replaces unless docType says otherwise. Naming a supersession target disables the content replay — it is an instruction about the register, not a retry. Idempotent on content: if the target already carries CURRENT bytes with this hash, the existing record is returned with 200 and Idempotent-Replay: true instead of filing a duplicate. Sending X-Checksum-Sha256 lets that be answered BEFORE the body is transferred, which is what makes a interrupted bulk run cheap to resume. The response file.scanStatus reports the asynchronous malware-scan state — a document is not necessarily downloadable the moment this returns.

id
required
string format: uuid
filename
string
docType
string
supersedesDocumentId
string format: uuid

Either multipart/form-data with a file part (metadata in sibling text fields), or a raw application/octet-stream body (metadata in the query string, filename via ?filename=, X-Filename or Content-Disposition). Raw bodies MUST send Content-Length. Optional X-Checksum-Sha256 is verified against the stored bytes; on mismatch nothing is written.

object
file
required
string format: binary
docType
string
supersedesDocumentId
string

Success

Media typeapplication/json
object
success
required
boolean
data
required
object
id
required
string format: uuid
contractId
required
string format: uuid
docType
required
string
fileId
required
string | null format: uuid
filename
required
string | null
mimeType
required
string | null
sizeBytes
required
integer | null
scanStatus
required
string | null
addedByUserId
required
string | null format: uuid
createdAt
required
string | null format: date-time
supersededById
required
string | null format: uuid
supersededAt
required
string | null format: date-time
timestamp
required
string format: date-time
requestId
string
message
string
Example
{
"success": true,
"data": {
"id": "107f33ba-b03e-4aa8-8d41-eb3143c5446f",
"contractId": "19446614-dcac-44a2-84e0-5973242cd655",
"docType": "string",
"fileId": "fb1348a8-e95b-439e-87dd-d027552ea719",
"filename": "string",
"mimeType": "string",
"sizeBytes": 1,
"scanStatus": "string",
"addedByUserId": "881ac022-621c-4260-85c8-11d966f41ee7",
"createdAt": "2026-08-19T09:41:12.004Z",
"supersededById": "d903bf39-dbe6-49e1-8d21-8ec66dd3bb66",
"supersededAt": "2026-08-19T09:41:12.004Z"
},
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J5X8ZC3K4T7Q9M2W6B0N1V4H",
"message": "string"
}

Validation error

Media typeapplication/json
object
success
required
boolean
error
required
string
code
required
string
details
timestamp
required
string format: date-time
requestId
string
Example
{
"success": false,
"error": "Bad request",
"code": "BAD_REQUEST",
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"
}

Unauthorized

Media typeapplication/json
object
success
required
boolean
error
required
string
code
required
string
details
timestamp
required
string format: date-time
requestId
string
Example
{
"success": false,
"error": "Unauthorized",
"code": "UNAUTHORIZED",
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"
}

Storage quota exhausted for the organization plan

Media typeapplication/json
object
success
required
boolean
error
required
string
code
required
string
details
timestamp
required
string format: date-time
requestId
string
Example
{
"success": false
}

Forbidden — missing scope

Media typeapplication/json
object
success
required
boolean
error
required
string
code
required
string
details
timestamp
required
string format: date-time
requestId
string
Example
{
"success": false,
"error": "Forbidden",
"code": "FORBIDDEN",
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"
}

Not found

Media typeapplication/json
object
success
required
boolean
error
required
string
code
required
string
details
timestamp
required
string format: date-time
requestId
string
Example
{
"success": false,
"error": "Resource not found",
"code": "NOT_FOUND",
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"
}

Content-Length is required for a raw (non-multipart) body

Media typeapplication/json
object
success
required
boolean
error
required
string
code
required
string
details
timestamp
required
string format: date-time
requestId
string
Example
{
"success": false,
"error": "Content-Length is required for this upload",
"code": "LENGTH_REQUIRED",
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"
}

Upload exceeds API_UPLOAD_MAX_BYTES (details.maxBytes)

Media typeapplication/json
object
success
required
boolean
error
required
string
code
required
string
details
timestamp
required
string format: date-time
requestId
string
Example
{
"success": false,
"error": "Upload exceeds the maximum allowed size",
"code": "PAYLOAD_TOO_LARGE",
"details": {
"maxBytes": 262144000
},
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"
}

Rejected file type, unverifiable content, or checksum mismatch

Media typeapplication/json
object
success
required
boolean
error
required
string
code
required
string
details
timestamp
required
string format: date-time
requestId
string
Example
{
"success": false,
"error": "Validation failed",
"code": "VALIDATION_ERROR",
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"
}

Rate limit exceeded

Media typeapplication/json
object
success
required
boolean
error
required
string
code
required
string
details
timestamp
required
string format: date-time
requestId
string
Example
{
"success": false,
"error": "Too many requests",
"code": "TOO_MANY_REQUESTS",
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"
}

Object storage not configured

Media typeapplication/json
object
success
required
boolean
error
required
string
code
required
string
details
timestamp
required
string format: date-time
requestId
string
Example
{
"success": false,
"error": "Service unavailable",
"code": "SERVICE_UNAVAILABLE",
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J5X8ZC3K4T7Q9M2W6B0N1V4H"
}