# llms.txt for ByteFlask Last generated 2026-07-21 02:13:30 UTC # About ByteFlask ByteFlask is a free personal cloud storage tool. Upload, organize, and share files without the bloat that most storage services pile on. 50GB free storage, no ads, no tracking, and files stay encrypted. It works from any device via PWA (installable on iOS and Android through the browser), supports folder customization and tagging, and has team sharing features for collaborative work. ByteFlask is currently in invite-only beta. You must be invited by someone who already has access to ByteFlask, or by contacting cmds.media at https://cmds.media/contact. A developer API is available for integrating ByteFlask into other apps (as seen below, also available at https://drive.cmds.media/docs) # ByteFlask API Documentation Welcome to the ByteFlask API docs. This document should help you be able to integrate ByteFlask features into your own apps. ## Conventions - Authentication is cookie-based. ByteFlask uses the `bf_session` cookie set by the login endpoints. - Most JSON endpoints return either: - `{"success": true, ...}` on success, or - `{"success": false, "error": "..."}` on failure. - Most routes are under `/api`, excluding media-serving endpoints. For notes on how IDs and timestamps in ByteFlask work, see [Notes](https://drive.cmds.media/docs#notes). --- ## Authentication Authentication is handled by the `bf_session` cookie. You can have one set using one of the endpoints below, or find it in your [settings](https://drive.cmds.media/settings#developers) if logged in. ### `POST /api/login` Authenticates a user with either a username or an email address. Request body: ```json { "username": "user", "password": "secret123" } ``` Response `200`: ```json { "success": true, "message": "Login successful", "redirect_url": "/drive/123" } ``` Possible failures: - `400` for missing/invalid JSON or missing fields - `401` for bad credentials or accounts that have not finalized registration The session cookie `bf_session` is set on success. ### `POST /api/logout` Clears the current session. Response `200`: ```json { "success": true, "message": "Logout successful", "redirect_url": "/login" } ``` ### `GET /api/me` Returns the current authenticated user. Response `200`: ```json { "success": true, "user": { "id": 123, "username": "user", "email": "user@example.com", "plan": 0, "plan_info": { "name": "default", "size": 53687091200, "shared_drive": false }, "avatar_url": null, "created_at": "2026-07-10T12:00:00Z", "user_color": "#2f6fed" } } ``` --- ## Storage ### `GET /api/storage` Returns storage usage for the current user. Response `200`: ```json { "success": true, "used_bytes": 104857600, "total_bytes": 53687091200, "breakdown": { "by_type": { "image": 0, "video": 0, "audio": 0, "document": 0, "compressed": 0, "other": 0, "application": 0 }, "by_location": { "my-drive": 104857600 } } } ``` --- ## Drive and folder browsing The main listing endpoint is `/api/drive/:user_id/:drive_id`. The drive identifier is a drive slug such as: - `my-drive` - `trash` - any custom slug created for a drive ### `GET /api/drive/:user_id/:drive_id` Lists the contents of a drive. You can also target a folder by appending a folder ID segment: - `/api/drive/:user_id/:drive_id/folders/:folder_id` Optional query parameters: - `with_social=true` to enrich each file item with reaction and comment metadata - `with_children=true` to add a `child_count` value to each folder item Response `200`: ```json { "success": true, "path": [ { "id": null, "name": "My Drive" } ], "items": [ { "id": "f1a2b3c4", "name": "Projects", "type": "folder", "ext": null, "mime_type": null, "color": null, "modified_at": "2026-07-10T12:00:00Z", "size_bytes": null, "permission": "private", "is_public": false, "child_count": 12 }, { "id": "d9e8f7a6", "name": "notes.txt", "type": "file", "ext": "txt", "mime_type": "text/plain", "color": null, "modified_at": "2026-07-10T12:00:00Z", "size_bytes": 45056, "permission": "private", "is_public": false, "reactions": [ { "emoji": "👍", "count": 2 }, { "emoji": "🎉", "count": 3 } ], "comment_count": 4 } ] } ``` Notes: - Items are sorted with folders first, then by name. - The `path` array is breadcrumb data. The root entry always has `id: null`. - Public items are only returned to the owner or to viewers who can resolve the item as public. - When `with_social=true`, file items gain a `reactions` array containing only emoji counts and a `comment_count` value. - When `with_children=true`, folder items gain a `child_count` value representing the total number of descendant items inside that folder. ### `GET /api/drive/:user_id/:drive_id/search` Searches the contents of a single drive tree for matching files. Query string: - `query`: required search expression - `with_social=true`: optionally adds reaction and comment metadata to each result Supported search syntax: - plain terms are required substrings and are matched against the file name and its folder path - quoted phrases such as `"design review"` - `name:report` to match the file name only - `ext:pdf` to match the extension - `mime:text/plain` to match the MIME type - `parent:images` or `folder:images` to match the parent folder name or any folder in the path - `path:work/reports` to match the folder path - `-draft` to exclude terms Response `200`: ```json { "success": true, "query": "name:report ext:pdf", "items": [ { "id": "f1a2b3c4", "name": "report.pdf", "type": "file", "ext": "pdf", "mime_type": "application/pdf", "color": null, "modified_at": "2026-07-10T12:00:00Z", "size_bytes": 123456, "permission": "private", "is_public": false, "parent_folder_id": null, "reactions": [ { "emoji": "👍", "count": 2 } ], "comment_count": 3 } ] } ``` Notes: - The endpoint returns matching file items only. - `parent_folder_id` is the original folder that contains the file; it is `null` when the file is at the drive root. - `reactions` only includes emoji counts greater than `1` when `with_social=true`. ### `GET /api/folders/search` Searches the authenticated user’s folders. Query string: - `q`: search term Response `200`: ```json { "success": true, "drive_roots": [ { "id": null, "drive_id": 12, "drive_slug": "my-drive", "drive_name": "My Drive", "tree": [] } ], "folders": [ { "id": "abc123", "drive_id": 12, "drive_slug": "my-drive", "drive_name": "My Drive", "name": "Projects", "tree": ["Projects"] } ] } ``` --- ## Creating and updating folders ### `POST /api/drive/:user_id/:drive_id/folders` Creates a folder at the root of a drive. Alternative route for creating a subfolder: - `POST /api/drive/:user_id/folders/:folder_id/folders` Request body: ```json { "name": "Frontend" } ``` Response `201`: ```json { "success": true, "id": "42tcf234", "name": "Frontend", "color": null, "type": "folder", "permission": "private" } ``` If the folder already exists at the same location, the endpoint returns `200` with the existing folder instead of making a second copy. ### `PATCH /api/drive/:user_id/folders/:folder_id` Updates a folder’s name or color. Request body: ```json { "name": "Renamed Folder", "color": "#ef4444" } ``` Response `200`: ```json { "success": true, "id": "42tcf234", "name": "Renamed Folder", "color": "#ef4444", "type": "folder" } ``` --- ## Moving items ### `POST /api/items/move` Moves one or more items to a new folder or drive root. Request body: ```json { "item_ids": ["f1a2b3c4", "d9e8f7a6"], "target_folder_id": "abc123", "target_drive_slug": null } ``` Rules: - Use `target_folder_id` to move into a folder. - Use `target_drive_slug` without `target_folder_id` to move to the root of a drive. - Moving a folder into itself or one of its descendants is rejected. Response `200`: ```json { "success": true } ``` --- ## Uploading Uploading is not a simple `multipart/form-data` with one file per request. The current implementation expects a manifest describing the upload set, plus the file parts keyed by the manifest IDs. ### `POST /api/drive/:user_id/:drive_id/upload` Also available via: - `POST /api/drive/:user_id/folders/:folder_id/upload` - `POST /api/drive/:user_id/drive/:drive_id/folders/:folder_id/upload` Form fields: - `manifest`: required JSON array - `batch_id`: optional, generated automatically if omitted - one or more file parts whose field names match the manifest `id` values Manifest entry shape: ```json [ { "id": "file-1", "relative_path": "photos/one.jpg", "size": 12345, "modified_at": "2026-07-10T12:00:00Z" } ] ``` Response: - `201` when all files were uploaded successfully - `207` when some files failed - `400` when the manifest is missing or invalid - `507` when the upload would exceed plan storage Example success payload: ```json { "batch_id": "abc123", "results": [ { "success": true, "id": "file-1", "relative_path": "photos/one.jpg", "status": "done", "item_id": "x1y2z3" } ] } ``` ### `GET /api/upload/:batch_id/events` Streams upload progress as Server-Sent Events. Each event is a JSON object with the current file state, for example: ```json {"id":"file-1","status":"uploading","bytes_written":1024,"size":4096} ``` --- ## Downloading ### `POST /api/items/download` Creates one or more zip archives and returns temporary archive URLs. Request body: ```json { "item_ids": ["f1a2b3c4"] } ``` Response `200`: ```json { "success": true, "archives": [ { "name": "drive-export-20260710120000-1.zip", "url": "/archive/abc123" } ] } ``` The archive download endpoint is: - `GET /archive/:token` --- ## Trash Operations ### `POST /api/items/trash` Moves items into the user’s trash drive. Request body: ```json { "item_ids": ["f1a2b3c4"] } ``` Response `200`: ```json { "success": true, "message": "Items moved to trash" } ``` ### `POST /api/items/restore` Restores trashed items to their original location when possible. Request body: ```json { "item_ids": ["f1a2b3c4"] } ``` Response `200`: ```json { "success": true, "message": "Items restored" } ``` ### `POST /api/items/permanent-delete` Permanently deletes items that are already in trash. Request body: ```json { "item_ids": ["f1a2b3c4"] } ``` Response `200`: ```json { "success": true, "deleted": 1 } ``` ### `POST /api/items/empty-trash` Deletes every item currently in the user’s trash drive. Response `200`: ```json { "success": true, "deleted": 7 } ``` --- ## File and folder metadata updates ### `PATCH /api/files/:file_id` Updates a file’s name or permission. Request body: ```json { "name": "new-name.txt", "permission": "public" } ``` Response `200`: ```json { "success": true, "id": "f1a2b3c4", "name": "new-name.txt", "type": "file", "permission": "public" } ``` ### `PATCH /api/folders/:folder_id` Updates a folder’s name, color, or permission. Request body: ```json { "name": "Renamed", "color": "#00ff00", "permission": "public" } ``` Response `200`: ```json { "success": true, "id": "abc123", "name": "Renamed", "color": "#00ff00", "type": "folder", "permission": "public" } ``` ### `PATCH /api/items/permissions` Updates permissions for multiple items at once. Request body: ```json { "item_ids": ["f1a2b3c4"], "permission": "public" } ``` Response `200`: ```json { "success": true, "updated": 1 } ``` --- ## Comments and reactions These endpoints are not under `/api`. ### `GET /files/:file_id/comments` Returns comments for a file. Response `200`: ```json { "success": true, "comments": [ { "id": "c123", "item_id": "f1a2b3c4", "user_id": 123, "reply_to_comment_id": null, "message": "Looks good", "created_at": "2026-07-10T12:00:00Z", "updated_at": "2026-07-10T12:00:00Z", "profile": { "id": 123, "username": "user", "avatar_url": null, "created_at": "2026-07-10T12:00:00Z", "user_color": "#2f6fed" }, "can_delete": true } ] } ``` ### `POST /files/:file_id/comments` Creates a comment. Request body: ```json { "message": "Looks good", "reply_to_comment_id": "c456" } ``` ### `PATCH /files/:file_id/comments/:comment_id` Edits a comment the current user owns. ### `DELETE /files/:file_id/comments/:comment_id` Deletes a comment the current user owns, or deletes one as the file owner. ### `GET /files/:file_id/reactions` Returns current reaction totals and the current user’s own reactions. ### `POST /files/:file_id/reactions` ### `DELETE /files/:file_id/reactions` Adds or removes a single emoji reaction for the current user. Request body: ```json { "emoji": "👍" } ``` --- ## File serving ### `GET /files/:file_id` Streams a file for inline or attachment download. Query params: - `download=true` to force attachment mode ### `GET /thumb/:file_id` Streams a thumbnail for a file if the file is small enough. The endpoint returns the file as a media response. Thumbnails are currently only supported for --- ## Notes ### Item IDs Item IDs are random ASCII letters and digits. - Folder IDs are 12 characters long. - File IDs are 16 characters long. ### Parent IDs A `parent_id` of `null` means “root of the current drive”. ### Timestamps Timestamps are emitted as ISO 8601 UTC values such as `2026-07-10T12:00:00Z`.