Cách gọi các endpoint TMS File — method, path, mẫu request/response và curl copy được. Đặt BASE_URL là origin dịch vụ (ví dụ http://localhost:3000).
Placeholder: $BASE_URL
/api/v1/health-checksKiểm tra dịch vụ TMS File đang phản hồi.
Response
{
"message": "TMS-FILE is running"
}cURL
curl -sS "$BASE_URL/api/v1/health-checks"/api/v1/files/uploadmultipart/form-dataUpload một file: tạo metadata và ghi bytes theo binding lưu trữ đang hoạt động của tổ chức.
Request
Các field multipart/form-data bên dưới.
file (binary, required)
organization_id (string, required)
sub_system (string, required)
original_name (string, optional — defaults to file name)
mime_type (string, optional)
upload_temp (boolean, optional — TEMP local-only file)Response
{
"file_id": "01HZX…",
"original_name": "sample.pdf",
"mime_type": "application/pdf",
"file_size": 12345,
"ext": "pdf",
"file_path": "1/oms/2026/09/26/…",
"sync_status": "PENDING",
"updated_at": "2026-09-26T10:00:00.000Z"
}cURL
curl -sS -X POST "$BASE_URL/api/v1/files/upload" \
-F "file=@./sample.pdf" \
-F "organization_id=1" \
-F "sub_system=oms" \
-F "original_name=sample.pdf" \
-F "mime_type=application/pdf"/api/v1/files/uploadmultipart/form-dataThay đổi vòng đời theo file_id có sẵn: TEMP → THUMBNAIL, promote sẵn sàng, hoặc thay binary.
Request
multipart/form-data. make_as_thumbnail và make_as_ready loại trừ lẫn nhau.
file_id (string, required)
make_as_thumbnail (boolean — TEMP → THUMBNAIL; no binary)
make_as_ready (boolean — promote without or with binary)
file (binary — replace blob when status allows)
original_name / mime_type (optional with file)
Flags make_as_thumbnail and make_as_ready are mutually exclusive.Response
{
"file_id": "01HZX…",
"sync_status": "NONE",
"updated_at": "2026-09-26T10:05:00.000Z"
}cURL
curl -sS -X PUT "$BASE_URL/api/v1/files/upload" \
-F "file_id=01HZX…" \
-F "make_as_ready=true"/api/v1/files/batchmultipart/form-dataUpload hàng loạt (multipart items[]). All-or-nothing: ghi DB trong transaction rồi ghi disk tuần tự.
Request
Field gốc kèm items[N].*.
organization_id (string, required)
sub_system (string, required)
items[N].file (binary, required)
items[N].original_name / mime_type (optional)
All-or-nothing: DB transaction then sequential disk writes.Response
[
{ "file_id": "…", "original_name": "a.pdf", "…": "…" },
{ "file_id": "…", "original_name": "b.png", "…": "…" }
]cURL
curl -sS -X POST "$BASE_URL/api/v1/files/batch" \
-F "organization_id=1" \
-F "sub_system=oms" \
-F "items[0].file=@./a.pdf" \
-F "items[0].original_name=a.pdf" \
-F "items[0].mime_type=application/pdf" \
-F "items[1].file=@./b.png" \
-F "items[1].original_name=b.png" \
-F "items[1].mime_type=image/png"/api/v1/files/{fileId}Đọc file: LOCAL stream bytes; CLOUD redirect tới presigned URL. Dùng disposition=attachment để tải xuống.
Request
Path và query tùy chọn bên dưới.
Path: fileId (ULID)
Query: disposition=attachment (optional)Response
LOCAL → 200 stream (file bytes)
CLOUD → 302 redirect to presigned URLcURL
curl -sS -L -o out.bin "$BASE_URL/api/v1/files/{fileId}"
# Download as attachment:
curl -sS -L -o out.bin "$BASE_URL/api/v1/files/{fileId}?disposition=attachment"/api/v1/files/{fileId}/{width}/{height}Gallery variant vuông: width === height và thuộc whitelist. Stream WebP từ cache hoặc resize on-the-fly.
Request
Quy tắc path bên dưới. Không vuông hoặc ngoài whitelist → 400.
Path: fileId, width, height
Rules: width === height; size in whitelist: 200, 250, 300, 400, 500, 700, 1000
Outside whitelist or non-square → 400
Always streamed via tms-file (no R2 redirect)Response
200 image/webp (cached or resized on the fly)
Passthrough original when max edge ≤ requested sizecURL
curl -sS -o thumb.webp "$BASE_URL/api/v1/files/{fileId}/500/500"/api/v1/files/{fileId}Soft purge: đặt purge_status = SYSTEM_PURGE. Job nền xóa bytes trên storage rồi xóa bản ghi DB.
Request
Chỉ path parameter.
Path: fileId (ULID)Response
{
"fileId": "01HZX…",
"deleted": true,
"storageLocation": "LOCAL",
"purgePending": true
}cURL
curl -sS -X DELETE "$BASE_URL/api/v1/files/{fileId}"/api/v1/storage-providersDanh sách storage provider đang hoạt động — mảng { providerCode, providerName }.
Response
[
{ "providerCode": "R2", "providerName": "Cloudflare R2" }
]cURL
curl -sS "$BASE_URL/api/v1/storage-providers"/api/v1/organization-storage-bindings/createapplication/jsonTạo binding lưu trữ file cho tổ chức (một binding hoạt động cho mỗi tổ chức).
Request
JSON body.
{
"organizationId": 1,
"organizationName": "Demo Org",
"storageProvider": "R2",
"syncEnabled": true
}Response
{
"id": 10,
"organizationId": 1,
"organizationName": "Demo Org",
"isActive": true,
"syncEnabled": true,
"storageProvider": "R2",
"effectiveFrom": "2026-09-26T10:00:00.000Z",
"effectiveTo": null
}cURL
curl -sS -X POST "$BASE_URL/api/v1/organization-storage-bindings/create" \
-H "Content-Type: application/json" \
-d '{
"organizationId": 1,
"organizationName": "Demo Org",
"storageProvider": "R2",
"syncEnabled": true
}'/api/v1/organization-storage-bindings/updateapplication/jsonCập nhật binding đang hoạt động của tổ chức (kể cả isActive để ngưng hoặc mở lại).
Request
JSON body.
{
"organizationId": 1,
"organizationName": "Demo Org",
"storageProvider": "R2",
"syncEnabled": true,
"isActive": true
}Response
{
"id": 10,
"organizationId": 1,
"isActive": true,
"syncEnabled": true,
"storageProvider": "R2"
}cURL
curl -sS -X PUT "$BASE_URL/api/v1/organization-storage-bindings/update" \
-H "Content-Type: application/json" \
-d '{
"organizationId": 1,
"organizationName": "Demo Org",
"storageProvider": "R2",
"syncEnabled": true,
"isActive": true
}'