Files
Upload, download, and manage files via presigned URLs. Bytes never proxy through our app.
Files are stored in S3-compatible storage with server-side encryption at rest. Uploads and downloads use presigned URLs — bytes go directly between the client and S3, never through our app server.
Object shape
{
"id": "01HW…",
"object": "file",
"name": "Acme Co MSA.pdf",
"content_type": "application/pdf",
"size_bytes": "1228800",
"folder": "01HW…",
"uploaded_by": "user_01HW…",
"created_at": "…",
"updated_at": "…"
}size_bytes is a string (BigInt-friendly).
Endpoints
GET /v1/files ?folder=:id list files in folder (omit for root)
POST /v1/files initiate upload — returns file row + `upload` block
GET /v1/files/:id
POST /v1/files/:id { name?, folder? } rename or move
POST /v1/files/:id/finalize confirm upload completed
POST /v1/files/:id/download_url { attachment?: bool } fresh presigned GET
DELETE /v1/files/:idThe upload flow
Three steps:
1. Initiate — POST /v1/files with the metadata. The response
includes an upload block with a presigned PUT URL valid for 5
minutes.
2. Upload bytes — PUT the file contents directly to the URL using
the headers from the response (Content-Type + the SSE header).
3. Finalize — POST /v1/files/:id/finalize so we can HeadObject
the upload, verify size, and write the audit log row.
Full example
# Step 1 — initiate
RESPONSE=$(curl -s -X POST https://axerity.com/api/v1/files \
-H "Authorization: Bearer $AX_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "report.pdf",
"content_type": "application/pdf",
"size_bytes": "1228800"
}')
FILE_ID=$(echo $RESPONSE | jq -r .id)
UPLOAD_URL=$(echo $RESPONSE | jq -r .upload.url)
# Step 2 — PUT the bytes to S3
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/pdf" \
-H "x-amz-server-side-encryption: AES256" \
--data-binary @./report.pdf
# Step 3 — finalize
curl -X POST "https://axerity.com/api/v1/files/$FILE_ID/finalize" \
-H "Authorization: Bearer $AX_KEY"Downloading
curl -X POST https://axerity.com/api/v1/files/$FILE_ID/download_url \
-H "Authorization: Bearer $AX_KEY" \
-H "Content-Type: application/json" \
-d '{ "attachment": true }'Returns:
{
"object": "file_download",
"url": "https://s3.…?X-Amz-Signature=…",
"expires_in": 300,
"file": "01HW…"
}attachment: true forces Content-Disposition: attachment so the
browser saves; default is inline. URLs expire after 5 minutes —
always request fresh, never cache.