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 maxFileUploadBytes when applicable.
  • Presigned upload flows return maxFileUploadBytes in the response, and storage policies may include content-length-range so 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.

HTTP
POST /api/files/upload
Content-Type: multipart/form-data
Authorization: Bearer {token}
POST /api/files/upload
Content-Type: multipart/form-data
Authorization: Bearer {token}

Request Body (multipart/form-data):

  • file (required) - The file to upload
  • projectId (required) - Project ID
  • bucket (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:

JSON
{
  "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"
  }
}
{
  "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):

Shell
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"
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.

HTTP
GET /api/files/download/:fileId
Authorization: Bearer {token}
GET /api/files/download/:fileId
Authorization: Bearer {token}

Response:

  • Returns the file as a stream with the appropriate Content-Type header

Example:

Shell
curl -X GET https://cloud.mudbase.dev/api/files/download/file-id \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -o downloaded-file.pdf
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.

HTTP
GET /api/files?projectId={projectId}&bucket={bucket}
Authorization: Bearer {token}
GET /api/files?projectId={projectId}&bucket={bucket}
Authorization: Bearer {token}

Query Parameters:

  • projectId (required) - Project ID
  • bucket (optional) - Filter by bucket name
  • limit (optional) - Number of files to return (default: 50)
  • offset (optional) - Pagination offset (default: 0)

Response:

JSON
{
  "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
}
{
  "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

HTTP
GET /api/files/:fileId
Authorization: Bearer {token}
GET /api/files/:fileId
Authorization: Bearer {token}

Response:

JSON
{
  "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"
}
{
  "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

HTTP
DELETE /api/files/:fileId
Authorization: Bearer {token}
DELETE /api/files/:fileId
Authorization: Bearer {token}

Response:

JSON
{
  "message": "File deleted successfully"
}
{
  "message": "File deleted successfully"
}

File limits (summary)

  • Per-upload size: Plan maxFileUploadBytes and bucket maxFileSize (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

HTTP
POST /api/bucket
Authorization: Bearer {token}
POST /api/bucket
Authorization: Bearer {token}

Request Body:

JSON
{
  "projectId": "project-id",
  "name": "images",
  "isPublic": false
}
{
  "projectId": "project-id",
  "name": "images",
  "isPublic": false
}

List Buckets

HTTP
GET /api/bucket?projectId={projectId}
Authorization: Bearer {token}
GET /api/bucket?projectId={projectId}
Authorization: Bearer {token}

Access Control

Public files

  • Set isPublic: true on 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:

HTTP
GET /api/usage/projects/{projectId}
Authorization: Bearer {token}
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:

HTTP
POST /api/storage/projects/{projectId}/buckets/{bucketId}/files/{fileId}/signed-url
Authorization: Bearer {token}
Content-Type: application/json

{
  "expiresIn": 3600
}
POST /api/storage/projects/{projectId}/buckets/{bucketId}/files/{fileId}/signed-url
Authorization: Bearer {token}
Content-Type: application/json

{
  "expiresIn": 3600
}

Response:

JSON
{
  "success": true,
  "signedUrl": "https://storage.example.com/files/abc123?token=xyz789",
  "expiresAt": "2024-01-15T11:00:00.000Z"
}
{
  "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):

HTTP
GET /api/storage/projects/{projectId}/buckets/{bucketId}/files/{fileId}/transform?width=800&height=600&format=webp
GET /api/storage/projects/{projectId}/buckets/{bucketId}/files/{fileId}/transform?width=800&height=600&format=webp

Thumbnail shortcut:

HTTP
GET /api/storage/projects/{projectId}/buckets/{bucketId}/files/{fileId}/thumbnail?size=200&format=webp
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

  1. Use buckets to separate environments or media types.
  2. Prefer private defaults; expose isPublic only when you need anonymous reads.
  3. Watch usage against plan limits.
  4. Delete unused objects to free quota.
  5. Use consistent naming and metadata for support and analytics.

Error handling

CodeMeaning
400Invalid parameters or malformed multipart body
401Missing or invalid token
403Not allowed for this project or role
404File or project not found
413Payload larger than allowed maxFileUploadBytes
500Unexpected failure — retry; if it persists, the error body often indicates misconfiguration on the platform side

Examples

Upload (browser)

JavaScript
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);
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)

JavaScript
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);
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.