Documents
SDK methods for fixed-storage documents, folders, and deletion overrides.
The client.documents namespace provides typed methods for managing fixed-storage documents, organizing them into folders, and handling deletion override workflows. Available in TypeScript, Python, and Go SDKs.
| SDK | Install | Namespace |
|---|---|---|
| TypeScript | npm install @caldera/platformxe-sdk | client.documents |
| Python | pip install platformxe | client.documents |
| Go | go get github.com/calderax/platformxe-go | client.Documents |
Create a document
const doc = await client.documents.create({
name: 'Lease Agreement - Unit 4B',
folderId: 'fld_abc123',
fileUrl: 'https://storage.example.com/lease-4b.pdf',
mimeType: 'application/pdf',
metadata: { unitId: 'unit-4b', year: 2026 },
});
console.log(doc.id); // "doc_xyz789"
doc = client.documents.create_document(
name="Lease Agreement - Unit 4B",
folder_id="fld_abc123",
file_url="https://storage.example.com/lease-4b.pdf",
mime_type="application/pdf",
metadata={"unitId": "unit-4b", "year": 2026},
)
doc, err := client.Documents.CreateDocument(map[string]interface{}{
"name": "Lease Agreement - Unit 4B",
"folderId": "fld_abc123",
"fileUrl": "https://storage.example.com/lease-4b.pdf",
"mimeType": "application/pdf",
"metadata": map[string]interface{}{"unitId": "unit-4b", "year": 2026},
})
List documents
Retrieve documents with optional filters for folder and pagination.
const result = await client.documents.list({
folderId: 'fld_abc123',
page: 1,
limit: 25,
});
for (const doc of result.documents) {
console.log(`${doc.id}: ${doc.name}`);
}
result = client.documents.list_documents(folder_id="fld_abc123", page=1)
result, err := client.Documents.ListDocuments(map[string]string{
"folderId": "fld_abc123",
"page": "1",
})
Get a document
const doc = await client.documents.get('doc_xyz789');
doc = client.documents.get_document("doc_xyz789")
doc, err := client.Documents.GetDocument("doc_xyz789")
Update a document
const updated = await client.documents.update('doc_xyz789', {
name: 'Lease Agreement - Unit 4B (Renewed)',
metadata: { unitId: 'unit-4b', year: 2026, renewed: true },
});
updated = client.documents.update_document(
"doc_xyz789",
name="Lease Agreement - Unit 4B (Renewed)",
)
updated, err := client.Documents.UpdateDocument("doc_xyz789", map[string]interface{}{
"name": "Lease Agreement - Unit 4B (Renewed)",
})
Delete a document
Deleting a protected document returns an error indicating that an override is required. Use the deletion override workflow below.
await client.documents.delete('doc_xyz789');
client.documents.delete_document("doc_xyz789")
result, err := client.Documents.DeleteDocument("doc_xyz789")
Folders
A folder belongs to exactly one owner — an ownerType (ADMIN, AGENT, PARTNER, SYSTEM) plus your ownerId. There is no folder hierarchy and no list-all-folders endpoint. See Folders for the full response shape.
Create a folder
Creates the owner's folder, or returns the existing one. Responds with { folderId } only.
const { folderId } = await client.documents.createFolder({
ownerType: 'AGENT',
ownerId: 'agent_789',
});
result = client.documents.create_folder(owner_type="AGENT", owner_id="agent_789")
folder_id = result["folderId"]
// Typed form
result, err := client.Documents.CreateFolderForOwner("AGENT", "agent_789")
// Map form (v1 signature)
result, err = client.Documents.CreateFolder(map[string]interface{}{
"ownerType": "AGENT",
"ownerId": "agent_789",
})
fmt.Println(result.FolderID)
Get a folder by owner
const folder = await client.documents.getFolderByOwner('AGENT', 'agent_789');
console.log(folder.canUpload, folder.remainingBytes);
folder = client.documents.get_folder_by_owner(owner_type="AGENT", owner_id="agent_789")
folder, err := client.Documents.GetFolderByOwner("AGENT", "agent_789")
list_folders() (Python) and ListFolders() (Go) are deprecated and never call the API. Python raises NotImplementedError when called without an owner; given owner_type/owner_id it warns and delegates to get_folder_by_owner. Go always returns ErrListFoldersUnsupported.
Get a folder by ID
const folder = await client.documents.getFolder('fld_abc123');
folder = client.documents.get_folder("fld_abc123")
folder, err := client.Documents.GetFolder("fld_abc123")
Deletion overrides
Protected documents cannot be deleted directly. You request an override, a different operator approves it (a third one witnesses it for LEGAL/PERMANENT retention), and then you execute it. Executing is the step that deletes the document. See Access Overrides for the full workflow.
Request an override
overrideReason must be at least 500 characters. operatorId is optional: it identifies the human operator for four-eyes separation, and the server namespaces it under your caller service.
const override = await client.documents.requestOverride({
documentId: 'doc_xyz789',
overrideReason: 'Duplicate contract uploaded in error… (500+ characters)',
operatorId: 'admin_001',
});
console.log(override.id); // "ovr_abc123"
console.log(override.status); // "PENDING"
override = client.documents.request_override(
document_id="doc_xyz789",
override_reason="Duplicate contract uploaded in error… (500+ characters)",
operator_id="admin_001",
)
override, err := client.Documents.RequestOverride(map[string]interface{}{
"documentId": "doc_xyz789",
"overrideReason": "Duplicate contract uploaded in error… (500+ characters)",
"operatorId": "admin_001",
})
Approve, reject, or witness an override
action is approve, reject, or witness. rejectionReason is required for reject. The operator must differ from the requester (and, for witness, from the approver as well).
const approved = await client.documents.processOverride('ovr_abc123', {
action: 'approve',
operatorId: 'admin_002',
});
await client.documents.processOverride('ovr_def456', {
action: 'reject',
rejectionReason: 'This contract is still active',
});
approved = client.documents.process_override("ovr_abc123", action="approve", operator_id="admin_002")
client.documents.process_override(
"ovr_def456",
action="reject",
rejection_reason="This contract is still active",
)
approved, err := client.Documents.ProcessOverride("ovr_abc123", map[string]interface{}{
"action": "approve",
"operatorId": "admin_002",
})
Execute an override
Executing deletes the document and returns { success, documentId }, not the override record. Don't retry delete() afterwards.
const result = await client.documents.executeOverride('ovr_abc123', 'admin_003');
console.log(result.success, result.documentId); // true "doc_xyz789"
result = client.documents.process_override("ovr_abc123", action="execute", operator_id="admin_003")
result, err := client.Documents.ExecuteOverride("ovr_abc123", "admin_003")
Python's pre-1.6.0 keyword form (documentId=, overrideReason=, rejectionReason=, operatorId=) still works but emits a DeprecationWarning.
Scopes required
Every fixed-storage route (/api/v1/storage/*) requires storage:upload when the API key has scopes, including reads and deletes. Keys with no scopes have full access.
| Method | Scope |
|---|---|
documents.create() | storage:upload |
documents.list() | storage:upload |
documents.get() | storage:upload |
documents.update() | storage:upload |
documents.delete() | storage:upload |
documents.createFolder() | storage:upload |
documents.getFolderByOwner() | storage:upload |
documents.getFolder() | storage:upload |
documents.requestOverride() | storage:upload |
documents.processOverride() | storage:upload |
documents.executeOverride() | storage:upload |