Files
CRUD operations for folios — list, create, read, update, and delete.
Overview
Folios are the core resource in LiveFolio. Each folio contains HTML files, versions, comments, reactions, and metadata. All file endpoints require authentication.
List Folios
GET /api/files
Authorization: Bearer lf_live_xxxxxxxxxxxx
Returns all folios in the authenticated workspace, ordered by most recently updated.
Response: Array of folio objects:
[
{
"id": "a1b2c3d",
"title": "Q3 Investor Deck",
"description": "Quarterly earnings presentation",
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2025-06-20T14:22:00.000Z",
"isPrivate": false,
"allowComments": true,
"presentationModeOnly": false,
"status": "published",
"projectMode": "deck",
"versions": [...],
"comments": [...],
"reactions": { "👍": 5, "❤️": 3 },
"_storageBytes": 245760
}
]
Cache: Responses include Cache-Control: public, max-age=5, stale-while-revalidate=60.
Create a Folio
POST /api/files
Authorization: Bearer lf_live_xxxxxxxxxxxx
Content-Type: application/json
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Folio title (trimmed, non-empty) |
initialHtml | string | No* | Full HTML document for index.html |
defaultFiles | object | No* | Map of filename to content (e.g. {"index.html": "...", "styles.css": "..."}) |
description | string | No | One-line description (defaults to "Custom HTML Multipages") |
projectMode | string | No | One of: deck, document, spreadsheet, dashboard, infography (default: deck) |
isPrivate | boolean | No | Require access key to view (OSS: always false) |
accessKey | string | No | Password for private folios |
allowComments | boolean | No | Enable public comments (default: true) |
presentationModeOnly | boolean | No | Fullscreen presentation mode only (default: false) |
status | string | No | draft or published (default: draft) |
designPreferences | object | No | Theme, typography, palette, libraries, customColors, customGuidelines |
referenceFiles | array | No | Reference documents for AI context |
collaborators | array | No | Email addresses of collaborators (Cloud only) |
*At least one of initialHtml or defaultFiles must be provided.
Example Request:
curl -X POST https://livefolio.cloud/api/files \
-H "Content-Type: application/json" \
-H "Authorization: Bearer lf_live_xxxxxxxxxxxx" \
-d '{
"title": "Product Launch Page",
"initialHtml": "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><script src=\"https://cdn.tailwindcss.com\"></script></head><body class=\"bg-white\"><h1 class=\"text-4xl font-bold\">Coming Soon</h1></body></html>",
"projectMode": "deck",
"description": "Landing page for our new product",
"status": "draft"
}'
Response (201):
{
"success": true,
"project": {
"id": "a1b2c3d",
"title": "Product Launch Page",
"description": "Landing page for our new product",
"createdAt": "2025-06-20T14:22:00.000Z",
"updatedAt": "2025-06-20T14:22:00.000Z",
"isPrivate": false,
"allowComments": true,
"status": "draft",
"projectMode": "deck",
"versions": [
{
"versionId": "v1",
"commitMessage": "Genesis Initial Draft Commit",
"createdAt": "2025-06-20T14:22:00.000Z",
"author": "Workspace Founder",
"files": {
"index.html": "<!DOCTYPE html>..."
}
}
],
"comments": [],
"collaborators": []
}
}
Error Responses:
| Status | Error | Description |
|---|---|---|
| 400 | Title is required | Missing or empty title |
| 401 | Unauthorized | No valid auth context |
| 402 | STORAGE_EXCEEDED | Over storage quota (Cloud mode) |
Get a Folio
GET /api/files/{id}
Authorization: Bearer lf_live_xxxxxxxxxxxx
Returns the full folio object including all versions, files, comments, and metadata.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Folio ID (e.g., a1b2c3d or UUID in Cloud mode) |
Example Request:
curl https://livefolio.cloud/api/files/a1b2c3d \
-H "Authorization: Bearer lf_live_xxxxxxxxxxxx"
Response: Full folio object (same shape as the project field in create response).
Error Responses:
| Status | Error | Description |
|---|---|---|
| 401 | Unauthorized | No valid auth context (Cloud mode) |
| 404 | Project not found. | Folio does not exist |
Update a Folio
PUT /api/files/{id}
Authorization: Bearer lf_live_xxxxxxxxxxxx
Content-Type: application/json
Updates a folio's files, metadata, or both. Supports gzip-compressed payloads for large folios.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Folio ID |
Request Body:
| Field | Type | Description |
|---|---|---|
files | object | Map of filename to content (alias: updated_files) |
commitMessage | string | Version commit message (alias: change_message) |
title | string | Updated title |
description | string | Updated description |
isPrivate | boolean | Toggle private mode |
accessKey | string | Set/change access key |
allowComments | boolean | Toggle comments |
presentationModeOnly | boolean | Toggle presentation mode |
projectMode | string | Change project mode |
designPreferences | object | Update design system settings |
status | string | draft or published |
collaborators | array | Update collaborator list |
restoreVersionId | string | Restore to a specific version (creates a new version) |
reactions | object | Set reaction counts |
publicTunnelEnabled | boolean | Enable/disable public tunnel (OSS) |
referenceFiles | array | Update AI reference files |
_gz | boolean | Signal that _d field contains gzip-compressed JSON |
_d | string | Base64-encoded gzip-compressed payload |
Providing files creates a new version. Omitting files updates only metadata.
Example — Update metadata only:
curl -X PUT https://livefolio.cloud/api/files/a1b2c3d \
-H "Content-Type: application/json" \
-H "Authorization: Bearer lf_live_xxxxxxxxxxxx" \
-d '{
"title": "Q3 Investor Deck (Revised)",
"status": "published"
}'
Example — Add a new version:
curl -X PUT https://livefolio.cloud/api/files/a1b2c3d \
-H "Content-Type: application/json" \
-H "Authorization: Bearer lf_live_xxxxxxxxxxxx" \
-d '{
"files": {
"index.html": "<!DOCTYPE html>...updated...",
"styles.css": "body { margin: 0; }"
},
"commitMessage": "Updated hero section with new branding"
}'
Response:
{
"success": true,
"project": { ... }
}
Gzip Compression: For folios larger than ~1 MB, compress the payload:
const payload = { files: { "index.html": htmlContent }, commitMessage: "Update" };
const compressed = pako.gzip(JSON.stringify(payload));
const body = {
_gz: true,
_d: btoa(String.fromCharCode(...compressed))
};
Error Responses:
| Status | Error | Description |
|---|---|---|
| 400 | INVALID_JSON | Malformed request body |
| 400 | INVALID_BODY | Failed to decompress gzip payload |
| 401 | Unauthorized | No valid auth context |
| 404 | Project not found | Folio does not exist |
| 413 | FOLIO_TOO_LARGE | Request body exceeds 20 MB |
Delete a Folio
DELETE /api/files/{id}
Authorization: Bearer lf_live_xxxxxxxxxxxx
Permanently deletes a folio and all associated assets (storage files, versions, comments).
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Folio ID |
Example Request:
curl -X DELETE https://livefolio.cloud/api/files/a1b2c3d \
-H "Authorization: Bearer lf_live_xxxxxxxxxxxx"
Response:
{
"success": true
}
Error Responses:
| Status | Error | Description |
|---|---|---|
| 401 | Unauthorized | No valid auth context (Cloud mode) |
| 500 | Error message | Deletion failed |
Get Design Brief
GET /api/files/{id}/brief
Authorization: Bearer lf_live_xxxxxxxxxxxx
Returns a structured markdown design brief compiled from unresolved feedback pins and current file structure. Useful for feeding to AI agents for targeted revisions.
Example Request:
curl https://livefolio.cloud/api/files/a1b2c3d/brief \
-H "Authorization: Bearer lf_live_xxxxxxxxxxxx"
Response:
{
"title": "Product Launch Page",
"description": "Landing page for our new product",
"brief": "# LiveFolio Design Brief: Product Launch Page\n\n**Description**: Landing page...\n\n## 🎨 Current Open Feedback & Visual Annotations\n...",
"openComments": [...]
}