Skip to main content
File upload is a three-step flow — the API never accepts a raw file body directly. All three steps require contract_view (view) and a bearer token.
1

Presign

POST /files/presign requests a signed upload URL and an upload token.
fileName
string
required
contentType
string
required
sizeBytes
integer
required
Minimum 0.
kind
string
required
Must be one of the tenant’s allowed file kinds (contract originals, invoices, receipts, acceptance reports, and other evidence types).
subjectId
string
contractId
string
paymentId
string
2

Upload

PUT the file bytes directly to the signed URL returned by the presign step. Alforse’s API is not in this request path — this goes straight to object storage.
3

Confirm

POST /files/confirm tells the API the upload finished, so it can verify the object, trigger scanning, and record file metadata.
bucket
string
objectKey
string
required
fileName
string
required
contentType
string
required
sizeBytes
integer
required
kind
string
required
subjectId
string
contractId
string
paymentId
string
uploadToken
string
required
The token returned by the presign step.

Download a file

GET /files/:id/download · requires contract_view (view)
contractId
string
paymentId
string
Every download is authorized server-side against the requesting user’s tenant and subject scope, and is subject to the file-scan policy configured by FILE_SCAN_MODE and FILE_DOWNLOAD_REQUIRES_CLEAN_SCAN — see Configuration. A file that hasn’t cleared scanning yet may not be downloadable depending on that policy. See Contract Intake for how this flow fits into creating a contract from a scanned PDF, and Evidence Trail for how uploaded files surface later.