Files & Upload API
Upload files, manage stored files, and search across all resources. File uploads support linking to submissions, include server-side security validation, and persist file binaries in the database-backed stored file layer.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /api/files | List uploaded files |
POST | /api/files | Upload a standalone file (files workspace) |
GET | /api/files/browse | Browse files with extraction status, quality scores, and entity filtering |
GET | /api/files/browse/structure | Get smart folder structure grouped by linked entities |
PUT | /api/files/:fileId/star | Toggle starred status on a file |
PUT | /api/files/:fileId/move | Move a file to a folder |
POST | /api/files/folders | Create a folder |
PUT | /api/files/folders | Rename a folder |
DELETE | /api/files/folders | Delete a folder |
POST | /api/upload | Upload a file and optionally link it to a submission |
GET | /api/search | Global search across forms, submissions, tables, matters, boards, documents, records, workflows, and pages |
List Files
Returns all uploaded files for your workspace.
GET /api/files?search=passport&type=documents
Query Parameters
| Parameter | Type | Description |
|---|---|---|
search | string | Filter by filename substring |
type | string | Type filter: images, documents, spreadsheets, archives |
Response
{
"files": [
{
"id": "cm_attachment_abc123",
"filename": "passport-scan.pdf",
"fileUrl": "/api/documents/5f9d6c13e2_mi2f6b_4sB...pdf",
"fileSize": 245760,
"mimeType": "application/pdf",
"createdAt": "2026-02-13T09:30:00.000Z",
"submission": {
"id": "SUB-8XQ2M7K9P1ZT",
"formTitle": "Client Onboarding",
"user": {
"id": "cm_user_123",
"name": "Jane Smith"
}
}
}
],
"stats": {
"totalFiles": 56,
"totalSize": 9830400,
"fileTypes": {
"pdf": 20,
"png": 11
}
}
}
Upload via Files Workspace
Uploads a standalone file and links it to the system File Uploads submission.
POST /api/files
Content-Type: multipart/form-data
------boundary
Content-Disposition: form-data; name="file"; filename="company-logo.png"
Content-Type: image/png
<binary data>
------boundary--
Response
{
"success": true,
"file": {
"id": "cm_attachment_def456",
"filename": "company-logo.png",
"fileUrl": "/api/documents/5f9d6c13e2_mi2f70_EJd...png",
"fileSize": 82944,
"mimeType": "image/png"
}
}
Browse Files
Returns files for your workspace with extraction status, quality scores, and entity link information. Supports filtering by entity, folder, and special views.
GET /api/files/browse?search=passport&entityId=cm_row_rec1&entityType=ROW
Query Parameters
| Parameter | Type | Description |
|---|---|---|
search | string | Filter by filename substring |
type | string | Type filter: images, documents, spreadsheets, archives |
entityId | string | Filter to files linked to a specific entity (e.g. a record row ID) |
entityType | string | Entity type filter, used with entityId: ROW, MATTER, SUBMISSION |
linkTableId | string | Filter to files linked to rows in a specific table |
recent | boolean | Set to true to show recently uploaded files |
starred | boolean | Set to true to show only starred files |
unlinked | boolean | Set to true to show only files not linked to any entity |
Response
Each file includes optional extraction and quality fields. The extraction object shows the document extraction pipeline status (PENDING, PROCESSING, COMPLETED, FAILED, or TIMED_OUT) and completion timestamp. The quality object includes a structureScore (0-1) and a passed boolean. Both fields are null when not yet available.
{
"files": [
{
"id": "cm_file_abc123",
"filename": "passport-scan.pdf",
"fileUrl": "/api/documents/5f9d6c13e2_mi2f6b_4sB...pdf",
"fileSize": 245760,
"mimeType": "application/pdf",
"starred": false,
"folderId": null,
"createdAt": "2026-02-13T09:30:00.000Z",
"extraction": {
"status": "COMPLETED",
"completedAt": "2026-02-13T09:31:12.000Z"
},
"quality": {
"structureScore": 0.92,
"passed": true
},
"links": [
{
"entityId": "cm_row_rec1",
"entityType": "ROW",
"tableId": "cm_table_456"
}
]
}
],
"total": 56
}
Browse Folder Structure
Returns a smart folder structure for the file browser sidebar. Files are grouped into sections by linked entity type (e.g. Individuals, Matters), with counts per entity. Also returns totals for the Recent, Starred, and Unlinked virtual folders.
GET /api/files/browse/structure
Response
{
"sections": [
{
"key": "clients",
"label": "Individuals",
"icon": "Users",
"totalFiles": 12,
"entities": [
{
"id": "cm_row_rec1",
"name": "Acme Corp",
"count": 4,
"tableId": "cm_table_456"
}
]
}
],
"recent": 8,
"starred": 3,
"unlinked": 5
}
Toggle Star
Toggles the starred status of a file. Starred files appear in the Starred virtual folder in the file browser.
PUT /api/files/:fileId/star
Response
{
"success": true,
"starred": true
}
Create Folder
Creates a new folder for organising files.
POST /api/files/folders
Content-Type: application/json
{
"name": "Client Documents"
}
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The folder name |
Response
{
"id": "cm_folder_abc123",
"name": "Client Documents",
"organizationId": "cm_org_123",
"createdAt": "2026-03-01T10:00:00.000Z"
}
Rename Folder
Renames an existing folder.
PUT /api/files/folders
Content-Type: application/json
{
"id": "cm_folder_abc123",
"name": "Renamed Folder"
}
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The folder ID |
name | string | Yes | The new folder name |
Delete Folder
Deletes a folder. Files inside the folder are moved to the root level (not deleted).
DELETE /api/files/folders
Content-Type: application/json
{
"id": "cm_folder_abc123"
}
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The folder ID to delete |
Move File to Folder
Moves a file into a folder, or back to the root level by passing null as the folder ID.
PUT /api/files/:fileId/move
Content-Type: application/json
{
"folderId": "cm_folder_abc123"
}
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
folderId | string | null | Yes | Target folder ID, or null to move to root |
Response
{
"success": true,
"file": {
"id": "cm_file_abc123",
"folderId": "cm_folder_abc123"
}
}
Upload a File
Uploads a file using multipart/form-data encoding. Files can optionally be linked to a submission by passing submissionId.
POST /api/upload
Content-Type: multipart/form-data
------boundary
Content-Disposition: form-data; name="file"; filename="passport-scan.pdf"
Content-Type: application/pdf
<binary data>
------boundary
Content-Disposition: form-data; name="submissionId"
SUB-8XQ2M7K9P1ZT
------boundary--
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
file | File | Yes | The file to upload |
submissionId | string | No | Links the uploaded file to a specific submission |
Response
{
"success": true,
"file": {
"key": "5f9d6c13e2_mi2f6b_4sB...pdf",
"filename": "passport-scan.pdf",
"size": 245760,
"mimeType": "application/pdf",
"url": "/api/documents/5f9d6c13e2_mi2f6b_4sB...pdf",
"attachmentId": "cm_attachment_abc123"
}
}
Upload Security
- Max file size: 10MB by default (configurable by the workspace administrator).
- MIME type validation: Dangerous executable/script MIME types are blocked (for example PE binaries, shell scripts, HTML, and JavaScript MIME types).
- Content inspection: Server-side validation ensures that the file's actual content matches its declared MIME type. Files masquerading as images (e.g. SVG with
image/pngheader) are rejected. - Content-Disposition: Markup-like MIME types such as
image/svg+xmlare forced to download viaContent-Disposition: attachment. - Security token: File uploads require authentication.
Blocked MIME Types
| MIME Type | Reason |
|---|---|
application/x-msdownload | Native executable binary |
application/x-sh | Shell script execution risk |
text/html | HTML can execute scripts when rendered inline |
application/javascript | Script execution risk |
Global Search
Searches across all resource types in your workspace. Results are grouped by type: forms, submissions, tables, matters, boards, documents, records, workflows, and navigation pages.
GET /api/search?q=onboarding
Query Parameters
| Parameter | Type | Description |
|---|---|---|
q | string | Search query string (required). Searches titles, names, descriptions, tags, and data content. |
entities | string | Comma-separated list of entity types to search. Defaults to all types. Values: forms, submissions, tables, workflows, templates, boards, matters, documents, records, pages |
limit | number | Maximum results to return (default: 20) |
sortBy | string | Sort order: relevance (default) or date |
sortOrder | string | Sort direction: desc (default) or asc |
Response
{
"results": {
"forms": [
{
"id": "cm_form_123",
"title": "Client Onboarding",
"description": "Collect client details for onboarding",
"status": "PUBLISHED"
}
],
"submissions": [
{
"id": "SUB-8XQ2M7K9P1ZT",
"formTitle": "Client Onboarding",
"status": "PENDING",
"createdAt": "2026-02-12T09:15:00.000Z"
}
],
"tables": [
{
"id": "cm_table_456",
"name": "Individuals",
"category": "SYSTEM"
}
],
"matters": [
{
"id": "cm_matter_789",
"number": "MAT-0012",
"title": "Acme Corp Onboarding",
"status": "IN_PROGRESS",
"priority": "HIGH",
"boardName": "Client Onboarding"
}
],
"boards": [
{
"id": "cm_template_abc",
"title": "Client Onboarding",
"status": "ACTIVE"
}
],
"documents": [
{
"id": "cm_row_doc1",
"title": "Onboarding Checklist",
"tableName": "Documents"
}
],
"records": [
{
"id": "cm_row_rec1",
"title": "Acme Corp",
"tableName": "Companies"
}
],
"pages": [
{
"id": "page-matters",
"title": "Matters",
"url": "/matters"
}
],
"workflows": []
},
"query": "onboarding",
"totalResults": 8,
"durationMs": 12
}
Search Result Groups
| Group | Searches |
|---|---|
forms | Form title and description |
submissions | Submission ID, form title, submitter name/email, and data content |
tables | Table name and description |
matters | Matter number, title, tags, and board name |
boards | Board (matter template) name and description |
documents | Document title from the system Documents table |
records | CRM and user table rows - searches all field data (Individuals, Companies, etc.) |
workflows | Workflow name and description |
pages | Navigation pages and settings (e.g. "dark mode" matches Appearance) |
Entity File Intelligence
Deep file aggregation endpoints for CSP entities and individuals. These endpoints traverse company rows, linked matters, and stakeholder relationships to provide a complete file picture for a given entity.
Entity Files (Company)
Deep file aggregation for a CSP entity (company). Returns files from direct company row links, all linked matters, and all stakeholders with roles in the entity.
GET /api/csp/entities/:entityId/files
Path Parameters
| Parameter | Type | Description |
|---|---|---|
entityId | string | The row ID of the company entity in the Companies system table |
Response
{
"entityId": "cm_row_ent1",
"entityName": "Acme Holdings Ltd",
"direct": [
{
"id": "cm_file_abc123",
"filename": "certificate-of-incorporation.pdf",
"fileSize": 245760,
"mimeType": "application/pdf",
"createdAt": "2026-01-15T10:00:00.000Z"
}
],
"fromMatters": [
{
"matterId": "cm_matter_789",
"matterTitle": "Acme Holdings - Annual Return 2026",
"files": [
{
"id": "cm_file_def456",
"filename": "annual-return-draft.pdf",
"fileSize": 184320,
"mimeType": "application/pdf",
"createdAt": "2026-02-20T14:30:00.000Z"
}
]
}
],
"fromStakeholders": [
{
"individualId": "cm_row_ind1",
"name": "John Smith",
"files": [
{
"id": "cm_file_ghi789",
"filename": "passport-scan.pdf",
"fileSize": 102400,
"mimeType": "application/pdf",
"createdAt": "2026-01-10T09:00:00.000Z"
}
]
}
],
"totalFiles": 3
}
Individual Files
Deep file aggregation for a CSP individual. Returns files from direct stakeholder row links, linked matters, and bridged KYC documents.
GET /api/csp/individuals/:individualId/files
Path Parameters
| Parameter | Type | Description |
|---|---|---|
individualId | string | The row ID of the individual in the Stakeholders system table |
Response
{
"individualId": "cm_row_ind1",
"individualName": "John Smith",
"direct": [
{
"id": "cm_file_ghi789",
"filename": "passport-scan.pdf",
"fileSize": 102400,
"mimeType": "application/pdf",
"createdAt": "2026-01-10T09:00:00.000Z"
}
],
"fromMatters": [
{
"matterId": "cm_matter_789",
"matterTitle": "Acme Holdings - Annual Return 2026",
"files": [
{
"id": "cm_file_jkl012",
"filename": "director-resolution.pdf",
"fileSize": 76800,
"mimeType": "application/pdf",
"createdAt": "2026-02-22T11:00:00.000Z"
}
]
}
],
"totalFiles": 2
}
Stakeholder File Timeline
Chronological view of every document associated with a stakeholder across all entities and matters.
GET /api/stakeholders/:id/files
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The stakeholder row ID |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
limit | number | Maximum entries to return (default: 100, max: 500) |
Response
{
"stakeholderId": "cm_row_ind1",
"entries": [
{
"file": {
"id": "cm_file_ghi789",
"filename": "passport-scan.pdf",
"fileSize": 102400,
"mimeType": "application/pdf"
},
"source": "ROW",
"sourceLabel": "Stakeholders - John Smith",
"date": "2026-01-10T09:00:00.000Z"
},
{
"file": {
"id": "cm_file_jkl012",
"filename": "director-resolution.pdf",
"fileSize": 76800,
"mimeType": "application/pdf"
},
"source": "MATTER",
"sourceLabel": "Acme Holdings - Annual Return 2026",
"date": "2026-02-22T11:00:00.000Z"
}
],
"totalEntries": 2
}