PlatformXeDocs
Get API Key

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.

SDKInstallNamespace
TypeScriptnpm install @caldera/platformxe-sdkclient.documents
Pythonpip install platformxeclient.documents
Gogo get github.com/calderax/platformxe-goclient.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.

MethodScope
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