Documents
API reference for creating, managing, and organizing fixed-storage documents.
The Documents service provides fixed storage for structured documents -- contracts, identity documents, policies, invoices, and other files that need access control, versioning, and retention management. Unlike media storage (for images and transient files), fixed storage is designed for documents with compliance and governance requirements.
Base URL
All document endpoints are under /api/v1/storage/fixed/documents.
Scope: storage:upload for every document route — reads, creates, updates and deletes alike (all /api/v1/storage/* paths map to it). Keys with no scopes have full access.
Create a document
POST /api/v1/storage/fixed/documents
Request body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Document title |
description | string | No | Document description |
category | string | Yes | Document category (see categories below) |
fileType | string | Yes | File type: MD, PDF, DOCX, XLSX, IMAGE, or OTHER |
space | string | Yes | PERSONAL or INTERNAL |
folderId | string | No | ID of the folder to place the document in |
content | string | No | Markdown content (for MD file type) |
fileUrl | string | No | URL of the uploaded file |
fileName | string | No | Original filename |
fileMimeType | string | No | MIME type of the file |
fileSize | number | No | File size in bytes |
entityType | string | No | Related entity type (e.g., BOOKING, PROPERTY) |
entityId | string | No | Related entity ID |
accessLevel | string | No | Access level: SUPER_ADMIN, MANAGEMENT, FINANCE, OPERATIONS, STAFF, STAKEHOLDER, or CUSTOM. Default: STAKEHOLDER |
visibility | string | No | Visibility: PRIVATE, SHARED, or PORTAL. Default: PRIVATE |
allowedGroups | string[] | No | Groups that can access this document |
allowedEntities | string[] | No | Specific entity IDs with access |
retentionType | string | No | NONE, STANDARD, EXTENDED, LEGAL, or PERMANENT. Default: STANDARD |
retentionUntil | string | No | ISO 8601 date for retention expiry |
deletableBy | string | No | Who can delete: OWNER, ADMIN, SUPER_ADMIN, or NONE |
Document categories
IDENTITY_DOCUMENT, CONTRACT, INVOICE, RECEIPT, POLICY, REPORT, CERTIFICATE, LICENSE, INSURANCE, TAX_DOCUMENT, BANK_DOCUMENT, PAYSLIP, OFFER_LETTER, NDA, MEMO, TRAINING_MATERIAL, SOP, MEETING_NOTES, LEGAL, COMPLIANCE, OTHER
Response
{
"success": true,
"data": {
"id": "doc_abc123",
"title": "Employment Contract - Ade Bakare",
"category": "CONTRACT",
"fileType": "PDF",
"space": "INTERNAL",
"accessLevel": "STAFF",
"visibility": "SHARED",
"version": 1,
"retentionType": "LEGAL",
"deletableBy": "SUPER_ADMIN",
"isLatest": true,
"canDelete": false,
"deletionRequiresOverride": true,
"createdAt": "2026-04-05T10:00:00.000Z",
"updatedAt": "2026-04-05T10:00:00.000Z"
}
}
List documents
GET /api/v1/storage/fixed/documents
Query parameters
| Parameter | Type | Description |
|---|---|---|
ownerType | string | Filter by owner type: ADMIN, AGENT, PARTNER, SYSTEM |
ownerId | string | Filter by owner ID |
space | string | Filter by space: PERSONAL or INTERNAL |
category | string | Filter by document category |
fileType | string | Filter by file type |
visibility | string | Filter by visibility |
folderId | string | Filter by folder |
search | string | Full-text search on title and description |
page | number | Page number (default: 1) |
limit | number | Results per page (default: 20, max: 100) |
Response
{
"success": true,
"data": {
"documents": [...],
"total": 42,
"page": 1,
"limit": 20,
"totalPages": 3
}
}
Get a document
GET /api/v1/storage/fixed/documents/:documentId
Returns the full document record including metadata, access counts, and retention information.
Update a document
PATCH /api/v1/storage/fixed/documents/:documentId
Request body
| Field | Type | Description |
|---|---|---|
title | string | Updated title |
description | string | Updated description |
category | string | Updated category |
content | string | Updated markdown content (MD files) |
accessLevel | string | Updated access level |
visibility | string | Updated visibility |
retentionType | string | Updated retention type |
retentionUntil | string | Updated retention expiry |
isArchived | boolean | Archive or unarchive the document |
All fields are optional. Only provided fields are updated.
Delete a document
DELETE /api/v1/storage/fixed/documents/:documentId
Performs a soft delete. Documents with deletableBy: "NONE" or restricted deletableBy settings may require a deletion override before deletion is permitted.
Examples
Create a contract document
curl
curl -X POST https://api.platformxe.com/api/v1/storage/fixed/documents \
-H "Content-Type: application/json" \
-H "x-api-key: pxk_live_your_api_key_here" \
-d '{
"title": "Employment Contract - Ade Bakare",
"category": "CONTRACT",
"fileType": "PDF",
"space": "INTERNAL",
"fileUrl": "https://cdn.platformxe.com/org_123/contracts/ade-bakare.pdf",
"fileName": "ade-bakare-contract.pdf",
"fileMimeType": "application/pdf",
"fileSize": 245760,
"accessLevel": "STAFF",
"visibility": "SHARED",
"retentionType": "LEGAL",
"deletableBy": "SUPER_ADMIN"
}'
TypeScript SDK
import { PlatformXeClient } from '@caldera/platformxe-sdk';
const px = new PlatformXeClient({ apiKey: 'pxk_live_your_api_key_here' });
const doc = await px.documents.create({
title: 'Employment Contract - Ade Bakare',
category: 'CONTRACT',
fileType: 'PDF',
space: 'INTERNAL',
fileUrl: 'https://cdn.platformxe.com/org_123/contracts/ade-bakare.pdf',
fileName: 'ade-bakare-contract.pdf',
fileMimeType: 'application/pdf',
fileSize: 245760,
accessLevel: 'STAFF',
visibility: 'SHARED',
retentionType: 'LEGAL',
deletableBy: 'SUPER_ADMIN',
});
console.log(doc.id);
// "doc_abc123"
Python SDK
from platformxe import PlatformXeClient
px = PlatformXeClient(api_key="pxk_live_your_api_key_here")
doc = px.documents.create({
"title": "Employment Contract - Ade Bakare",
"category": "CONTRACT",
"fileType": "PDF",
"space": "INTERNAL",
"fileUrl": "https://cdn.platformxe.com/org_123/contracts/ade-bakare.pdf",
"accessLevel": "STAFF",
"visibility": "SHARED",
"retentionType": "LEGAL",
"deletableBy": "SUPER_ADMIN"
})
List documents in a folder
const result = await px.documents.list({
folderId: 'fld_contracts',
category: 'CONTRACT',
page: 1,
limit: 50,
});
console.log(result.total);
// 12
Search documents
curl "https://api.platformxe.com/api/v1/storage/fixed/documents?search=employment&category=CONTRACT" \
-H "x-api-key: pxk_live_your_api_key_here"
Update access level
await px.documents.update('doc_abc123', {
accessLevel: 'MANAGEMENT',
visibility: 'PORTAL',
});
Error responses
| Code | Status | Description |
|---|---|---|
BAD_REQUEST | 400 | Missing required fields (title, category, fileType, space, ownerType, ownerId) |
VALIDATION_ERROR | 400 | fileType, space, ownerType, accessLevel, or visibility is not one of its allowed values — the response names the field and lists the allowed values |
INVALID_CATEGORY | 400 | category isn't registered for this caller (only when the tenant has opted into category enforcement) |
FORBIDDEN | 403 | API key lacks required scope, or the actor's access level/role is insufficient for this action (e.g. only Super Admins may set accessLevel: "SUPER_ADMIN" or change retention settings) |
NOT_FOUND | 404 | Document (or its folder, for folderId) does not exist or has been deleted |
DELETE_BLOCKED | 403 | Document cannot be deleted without an approved deletion override — the response names the reason (e.g. active legal retention) |
QUOTA_EXCEEDED | 422 | Uploading to folderId would exceed that folder's file-count or storage-byte limit |
RATE_LIMITED | 429 | Rate limit exceeded |