Guides
Files & storage
Upload and manage files with the REST API, official SDKs, buckets, signed URLs, and optional image transforms. For a full list of paths and schemas, use the API reference or OpenAPI.
Upload limits and quotas
Your organization plan defines a maximum upload size (maxFileUploadBytes). Individual buckets may also set maxFileSize in their settings — the stricter of the two applies.
- Oversized uploads return 413 with details such as
maxFileUploadByteswhen applicable. - Presigned upload flows return
maxFileUploadBytesin the response, and storage policies may includecontent-length-rangeso oversize objects are rejected at the store.
Exact byte limits depend on your subscription tier (from smaller caps on free tiers up to multi‑gigabyte uploads on higher tiers).
Overview
The storage APIs let you:
- Upload files to projects
- Organize files in buckets
- Control access (public or private)
- Track storage usage
- Download files securely
- Delete files
API Endpoints
Upload File
Upload a file to a project bucket.
POST /api/files/upload
Content-Type: multipart/form-data
Authorization: Bearer {token}
Request Body (multipart/form-data):
file(required) - The file to uploadprojectId(required) - Project IDbucket(optional) - Bucket name (default: "default")isPublic(optional) - Make file publicly accessible (default: false)
If the file exceeds the effective limit, the API returns 413 with error and maxFileUploadBytes where provided.
Response:
{
"message": "File uploaded successfully",
"file": {
"id": "file-id",
"originalName": "document.pdf",
"mimeType": "application/pdf",
"size": 1024000,
"url": "/api/files/download/file-id",
"bucket": "default",
"isPublic": false,
"uploadedBy": "user-id",
"uploadedAt": "2024-12-01T10:00:00Z"
}
}
Example (cURL):
curl -X POST https://cloud.mudbase.dev/api/files/upload \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@document.pdf" \
-F "projectId=project-id" \
-F "bucket=documents" \
-F "isPublic=false"
Use your SDK’s multipart or upload helper where available (SDKs).
Download File
Download a file by ID.
GET /api/files/download/:fileId
Authorization: Bearer {token}
Response:
- Returns the file as a stream with the appropriate
Content-Typeheader
Example:
curl -X GET https://cloud.mudbase.dev/api/files/download/file-id \
-H "Authorization: Bearer YOUR_TOKEN" \
-o downloaded-file.pdf
List Files
List files in a project or bucket.
GET /api/files?projectId={projectId}&bucket={bucket}
Authorization: Bearer {token}
Query Parameters:
projectId(required) - Project IDbucket(optional) - Filter by bucket namelimit(optional) - Number of files to return (default: 50)offset(optional) - Pagination offset (default: 0)
Response:
{
"files": [
{
"id": "file-id",
"originalName": "document.pdf",
"mimeType": "application/pdf",
"size": 1024000,
"bucket": "default",
"isPublic": false,
"uploadedBy": "user-id",
"uploadedAt": "2024-12-01T10:00:00Z"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
Get File Metadata
GET /api/files/:fileId
Authorization: Bearer {token}
Response:
{
"id": "file-id",
"originalName": "document.pdf",
"mimeType": "application/pdf",
"size": 1024000,
"bucket": "default",
"isPublic": false,
"uploadedBy": {
"id": "user-id",
"email": "user@example.com"
},
"uploadedAt": "2024-12-01T10:00:00Z"
}
Delete File
DELETE /api/files/:fileId
Authorization: Bearer {token}
Response:
{
"message": "File deleted successfully"
}
File limits (summary)
- Per-upload size: Plan
maxFileUploadBytesand bucketmaxFileSize(see Upload limits and quotas). - File types: Any MIME type unless you add your own validation in app code.
- Storage quota: Depends on your plan; monitor via usage APIs or the dashboard.
Buckets
Buckets are logical containers per project.
Create Bucket
POST /api/bucket
Authorization: Bearer {token}
Request Body:
{
"projectId": "project-id",
"name": "images",
"isPublic": false
}
List Buckets
GET /api/bucket?projectId={projectId}
Authorization: Bearer {token}
Access Control
Public files
- Set
isPublic: trueon upload when you want a URL that does not require a user session. - Public URLs are suitable for avatars, marketing assets, and CDN caching.
Private files
- Require authentication to download.
- Only principals with access to the project (and the right permissions) can read private objects.
Storage usage
Check usage per project:
GET /api/usage/projects/{projectId}
Authorization: Bearer {token}
Typical response fields include total bytes used, file counts, and breakdowns by bucket.
CDN and delivery
Public assets are served with CDN-friendly URLs when your project uses a configured public origin (for example a custom domain on object storage). Exact URL shape appears in upload and metadata responses.
Signed URLs
Generate time-limited signed URLs for private access:
POST /api/storage/projects/{projectId}/buckets/{bucketId}/files/{fileId}/signed-url
Authorization: Bearer {token}
Content-Type: application/json
{
"expiresIn": 3600
}
Response:
{
"success": true,
"signedUrl": "https://storage.example.com/files/abc123?token=xyz789",
"expiresAt": "2024-01-15T11:00:00.000Z"
}
Use cases: time-boxed downloads, email links, partner handoffs without sharing long-lived API keys.
Image transformation
On-the-fly transforms (resize, format, thumbnail):
GET /api/storage/projects/{projectId}/buckets/{bucketId}/files/{fileId}/transform?width=800&height=600&format=webp
Thumbnail shortcut:
GET /api/storage/projects/{projectId}/buckets/{bucketId}/files/{fileId}/thumbnail?size=200&format=webp
For parameters and limits, see the storage operations in the API reference.
Best practices
- Use buckets to separate environments or media types.
- Prefer private defaults; expose
isPubliconly when you need anonymous reads. - Watch usage against plan limits.
- Delete unused objects to free quota.
- Use consistent naming and metadata for support and analytics.
Error handling
| Code | Meaning |
|---|---|
| 400 | Invalid parameters or malformed multipart body |
| 401 | Missing or invalid token |
| 403 | Not allowed for this project or role |
| 404 | File or project not found |
| 413 | Payload larger than allowed maxFileUploadBytes |
| 500 | Unexpected failure — retry; if it persists, the error body often indicates misconfiguration on the platform side |
Examples
Upload (browser)
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('projectId', 'project-id');
formData.append('bucket', 'images');
formData.append('isPublic', 'true');
const response = await fetch('https://cloud.mudbase.dev/api/files/upload', {
method: 'POST',
headers: { Authorization: `Bearer ${token}` },
body: formData,
});
const data = await response.json();
console.log('File uploaded:', data.file);
Download (browser)
const response = await fetch(`https://cloud.mudbase.dev/api/files/download/${fileId}`, {
headers: { Authorization: `Bearer ${token}` },
});
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
For schema-accurate request bodies, prefer the OpenAPI spec or a generated SDK.