Documentation
API Reference
Storage

Storage API

Upload and manage files.

Base URL

https://api.moontraze.com

Upload File

POST /api/storage/:projectId/upload
Authorization: Bearer <token>
Content-Type: multipart/form-data
 
file: <binary>
folderId: <optional>
customPath: <optional>

Fields

FieldTypeRequiredDescription
filebinaryYesFile to upload
folderIdstringNoUpload into this folder (folder-based)
customPathstringNoUpload to this exact path (path-based)

Priority: customPath > folderId > root level

customPath example: users/{uid}/profile/avatar.jpg

Example — Folder-based

curl -X POST https://api.moontraze.com/api/storage/PROJECT_ID/upload \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Project-Id: PROJECT_ID" \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@photo.jpg" \
  -F "folderId=folder_abc"

Result: projects/{projectId}/{folderName}/{uuid}.jpg

Example — Path-based (customPath)

curl -X POST https://api.moontraze.com/api/storage/PROJECT_ID/upload \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Project-Id: PROJECT_ID" \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@avatar.jpg" \
  -F "customPath=users/uid_123/profile/avatar.jpg"

Result: projects/{projectId}/users/uid_123/profile/avatar.jpg

Response

{
  "id": "file_abc123",
  "name": "avatar.jpg",
  "path": "/PROJECT_ID/users/uid_123/profile/avatar.jpg",
  "url": "/PROJECT_ID/users/uid_123/profile/avatar.jpg",
  "publicUrl": "https://api.moontraze.com/storage/PROJECT_ID/users/uid_123/profile/avatar.jpg",
  "size": 45230,
  "mimeType": "image/jpeg",
  "folderId": null,
  "customPath": "users/uid_123/profile/avatar.jpg",
  "downloadUrl": "https://api.moontraze.com/storage/PROJECT_ID/users/uid_123/profile/avatar.jpg?download=true",
  "previewUrl": "https://api.moontraze.com/storage/PROJECT_ID/users/uid_123/profile/avatar.jpg?preview=true",
  "folderPath": "root",
  "quota": {
    "usedBytes": 45230,
    "limitBytes": 5368709120,
    "remainingBytes": 5368663890
  }
}

Safety

  • customPath is sanitized — path traversal (../), backslashes, and special characters are removed
  • Max length: 500 characters
  • Leading/trailing slashes are stripped automatically
  • {projectId} is prepended automatically — do not include it in customPath

List Files

GET /api/storage/:projectId/files
Authorization: Bearer <token>
X-Project-Id: YOUR_PROJECT_ID
X-API-Key: YOUR_API_KEY

List Files in Folder

GET /api/storage/:projectId/files?folderId=FOLDER_ID
Authorization: Bearer <token>
X-Project-Id: YOUR_PROJECT_ID
X-API-Key: YOUR_API_KEY

Get Presigned URL

GET /api/storage/:projectId/files/:fileId/presign?download=true
Authorization: Bearer <token>
X-Project-Id: YOUR_PROJECT_ID
X-API-Key: YOUR_API_KEY

Presigned URLs work the same for folderId and customPath uploads — both are stored in the same table and served identically.

Delete File

DELETE /api/storage/:projectId/files/:fileId
Authorization: Bearer <token>
X-Project-Id: YOUR_PROJECT_ID
X-API-Key: YOUR_API_KEY

Create Folder

POST /api/storage/:projectId/folders
Authorization: Bearer <token>
Content-Type: application/json
X-Project-Id: YOUR_PROJECT_ID
X-API-Key: YOUR_API_KEY
 
{
  "name": "My Folder",
  "parentId": null
}

List Folders

GET /api/storage/:projectId/folders
Authorization: Bearer <token>
X-Project-Id: YOUR_PROJECT_ID
X-API-Key: YOUR_API_KEY

Delete Folder

DELETE /api/storage/:projectId/folders/:folderId
Authorization: Bearer <token>
X-Project-Id: YOUR_PROJECT_ID
X-API-Key: YOUR_API_KEY

Get Storage Quota

GET /api/storage/:projectId/quota
Authorization: Bearer <token>
X-Project-Id: YOUR_PROJECT_ID
X-API-Key: YOUR_API_KEY

Public File URL

https://api.moontraze.com/storage/:projectId/path/to/file.webp
https://api.moontraze.com/storage/:projectId/path/to/file.webp?download=true

Custom paths work the same — the URL reflects the stored path:

https://api.moontraze.com/storage/PROJECT_ID/users/uid_123/profile/avatar.jpg

SDK Example

const file = document.getElementById('file').files[0];
 
// Folder-based
const result = await moon.storage.upload(file, {
  folderId: 'folder_abc',
});
console.log(result.publicUrl);
 
// Path-based (custom path)
const avatar = await moon.storage.upload(file, {
  customPath: `users/${uid}/profile/avatar.jpg`,
});
console.log(avatar.publicUrl);
 
const files = await moon.storage.list();
const folders = await moon.storage.listFolders();
await moon.storage.createFolder('My Folder');
const url = await moon.storage.getDownloadUrl(fileId);
await moon.storage.delete(fileId);
await moon.storage.deleteFolder(folderId);
const quota = await moon.storage.getQuota();