← Về kho file

API Docs — Kho file muse-vm

Tài liệu cho file-storage API chạy trên Muse VM (cổng 8790). Giao diện web ở trang chủ cũng dùng chính các endpoint này.

Xem bản Markdown (/api.md)

Dán bản Markdown vào bất kỳ AI agent nào (Muse, ChatGPT…) là agent đó hiểu và dùng được API ngay — chỉ cần bạn đưa thêm token cho nó.

1. Địa chỉ truy cập (Base URL)

Đường vàoĐịa chỉGhi chú
Domain (HAProxy TierHive)https://cloud.chungsuclq.skinĐịa chỉ chính thức — dùng được cả khi bật Cloudflare WARP, không giới hạn dung lượng upload
Tailscale Funnelhttps://muse-vm.tail588220.ts.netCó HTTPS; phải tắt WARP mới vào được
Nội bộ VMhttp://127.0.0.1:8790Chỉ gọi được từ bên trong Muse VM

Trong các ví dụ dưới đây, $BASE là một trong các địa chỉ trên và $TOKEN là token truy cập của kho.

2. Xác thực

Mọi endpoint (trừ GET /health, GET /, GET /hoc và trang này) đều yêu cầu token. Hai cách gửi:

Thiếu hoặc sai token, API trả 401 {"error":"unauthorized"}. Giao diện web lưu token trong localStorage của trình duyệt (khóa ftoken) sau lần nhập đầu tiên.

Token là lớp bảo vệ duy nhất của kho trên internet — giữ kín như mật khẩu, không gắn vào link chia sẻ cho người khác nếu không muốn họ mở được cả kho.

3. Endpoints

GET/healthkhông cần token

Kiểm tra server còn sống. Luôn trả:

curl $BASE/health
# {"status": "ok"}
GET/stats

Thống kê dung lượng đĩa và số file trong kho.

curl -H "Authorization: Bearer $TOKEN" $BASE/stats
# {"total": 161057947648, "free": 158..., "disk_used": ...,
#  "files": 15, "files_bytes": 2488776781}
TrườngÝ nghĩa
total / free / disk_usedDung lượng đĩa (byte): tổng / còn trống / đã dùng
files / files_bytesSố file trong kho và tổng kích thước của chúng
GET/files

Liệt kê toàn bộ file trong kho (mảng JSON, sắp xếp theo tên).

curl -H "Authorization: Bearer $TOKEN" $BASE/files
# [{"name": "phim.mp4", "size": 1512345678, "mtime": 1762345678}, ...]

size tính bằng byte; mtime là thời gian sửa cuối dạng Unix epoch (giây).

POST/upload

Tải file lên. Tên file gửi qua header X-Filename (URL-encode), nội dung file là body thô (raw). Giới hạn 16 GB/file.

curl -X POST --data-binary @phim.mp4 \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Filename: phim.mp4" \
  $BASE/upload
# 201 {"name": "phim.mp4", "size": 1512345678, "sha256": "…"}
File được ghi trực tiếp vào kho trong lúc upload — nếu đứt giữa chừng, file dở sẽ còn lại với dung lượng thiếu. Upload lại cùng tên để ghi đè hoàn chỉnh.
PUT/files/<name>

Tải lên / ghi đè một file theo tên (tương đương POST /upload nhưng tên nằm trên URL).

curl -T truyen.pdf -H "Authorization: Bearer $TOKEN" $BASE/files/truyen.pdf
# 201 {"name": "truyen.pdf", "size": ..., "sha256": "…"}
GET/files/<name>

Tải file về. Hỗ trợ Range request (trả 206 + Content-Range) nên trình duyệt xem phim/audio sẽ tua và phát theo đoạn được. Kèm header Content-Disposition: attachment.

curl -H "Authorization: Bearer $TOKEN" -O $BASE/files/phim.mp4
# hoặc mở thẳng trên trình duyệt (token qua query):
# $BASE/files/phim.mp4?token=$TOKEN
DELETE/files/<name>

Xóa một file khỏi kho. Thao tác không hoàn tác được.

curl -X DELETE -H "Authorization: Bearer $TOKEN" $BASE/files/phim.mp4
# {"deleted": "phim.mp4"}

4. Folder (namespace)

Kho chia được thành các folder — giống cơ chế folder/namespace của Cloudinary: mỗi web/app khi kết nối API chỉ cần khai đúng tên folder của mình là file tự tách riêng, web này không lẫn file của web kia. Ví dụ web luyện thuyết trình dùng folder hoc, kho phim dùng folder phim, truyện dùng truyen.

GET/folders

Liệt kê mọi folder kèm số file và tổng dung lượng. Phần tử đầu tiên luôn là thư mục gốc (name rỗng).

curl -H "Authorization: Bearer $TOKEN" $BASE/folders
# [{"name": "", "files": 16, "bytes": ...},
#  {"name": "phim", "files": 3, "bytes": ...}]
POST/folders

Tạo folder mới (body JSON).

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "phim"}' $BASE/folders
# 201 {"folder": "phim"}
POST/uploadvào folder

Upload thẳng vào một folder bằng header X-Folder:

curl -X POST --data-binary @tap1.mp4 \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Filename: tap1.mp4" -H "X-Folder: phim" \
  $BASE/upload
POST/move

Chuyển một file giữa các folder (body JSON: name, src, dst; để trống nghĩa là thư mục gốc). Folder đích chưa có sẽ tự tạo; nếu đích đã có file trùng tên, API trả 409.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "tap1.mp4", "src": "", "dst": "phim"}' $BASE/move
# {"moved": "tap1.mp4", "to": "phim"}
DELETE/folders/<name>

Xóa một folder và toàn bộ file trong đó. Không xóa được thư mục gốc.

curl -X DELETE -H "Authorization: Bearer $TOKEN" $BASE/folders/phim
# {"deleted_folder": "phim", "files": 3}

5. Trang web đi kèm

Đường dẫnNội dung
GET /Giao diện quản lý kho (upload, tìm kiếm, xem trước, tải, xóa)
GET /docsTrang tài liệu này
GET /api.mdToàn bộ tài liệu API dạng Markdown — cho AI agent đọc (không cần token)
GET /hocApp luyện thuyết trình CSoNet (không cần token)

6. Mã trạng thái thường gặp

MãÝ nghĩa
200Thành công (GET, DELETE)
201Đã lưu file (POST /upload, PUT)
206Trả một phần file theo Range
400Thiếu/sai tên file, hoặc body rỗng
401Thiếu hoặc sai token
404Không có file / đường dẫn này
409Trùng tên file ở folder đích khi chuyển file (/move)
413File vượt quá 16 GB

7. Lưu ý

← Về kho file