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

Buckets

Buckets are logical containers per project. Create a bucket before uploading files to it.

Create Bucket

HTTP
POST /api/bucket/projects/{projectId}/buckets
X-API-Key: ak_live_...
Content-Type: application/json

Request Body:

JSON
{
  "name": "images",
  "isPublic": false
}

List Buckets

HTTP
GET /api/bucket/projects/{projectId}/buckets
X-API-Key: ak_live_...

API Endpoints

Upload File

Upload one or more files to a project bucket using multipart form data.

HTTP
POST /api/bucket/projects/{projectId}/buckets/{bucketId}/files
X-API-Key: ak_live_...
Content-Type: multipart/form-data

Request Body (multipart/form-data):

  • files (required) - One or more files (field name files or file)
  • isPublic (optional) - Make files publicly accessible (default: false)

If the file exceeds the effective limit, the API returns 413 with error and maxFileUploadBytes where provided.

Response:

JSON
{
  "files": [
    {
      "_id": "file-id",
      "originalName": "document.pdf",
      "mimeType": "application/pdf",
      "size": 1024000,
      "isPublic": false,
      "uploadedAt": "2024-12-01T10:00:00Z"
    }
  ]
}

Example (cURL):

Shell
curl -X POST https://cloud.mudbase.dev/api/bucket/projects/{projectId}/buckets/{bucketId}/files \
  -H "X-API-Key: ak_live_..." \
  -F "files=@document.pdf"

Use your SDK's multipart or upload helper where available (SDKs).

Download / Get File

Retrieve a file's content by its ID. Requires authentication or an API key with storage:read permission.

HTTP
GET /api/bucket/projects/{projectId}/buckets/{bucketId}/files/{fileId}
X-API-Key: ak_live_...

Response:

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

Public files (where isPublic: true) can also be downloaded without authentication using a signed or direct URL. Use the signed-URL endpoint below to generate a time-limited link for private files.

Example:

Shell
curl -X GET \
  "https://cloud.mudbase.dev/api/bucket/projects/{projectId}/buckets/{bucketId}/files/{fileId}" \
  -H "X-API-Key: ak_live_..." \
  -o downloaded-file.pdf

List Files

List files in a bucket.

HTTP
GET /api/bucket/projects/{projectId}/buckets/{bucketId}/files
X-API-Key: ak_live_...

Query Parameters:

  • search (optional) - Filter by file name
  • type (optional) - Filter by MIME type

Response:

JSON
{
  "files": [
    {
      "_id": "file-id",
      "originalName": "document.pdf",
      "mimeType": "application/pdf",
      "size": 1024000,
      "isPublic": false
    }
  ]
}

Delete File

HTTP
DELETE /api/bucket/projects/{projectId}/buckets/{bucketId}/files/{fileId}
X-API-Key: ak_live_...

Response:

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

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}

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/bucket/projects/{projectId}/buckets/{bucketId}/files/{fileId}/signed-url
X-API-Key: ak_live_...
Content-Type: application/json

{
  "expiresIn": 3600
}

Response:

JSON
{
  "success": true,
  "signedUrl": "https://...",
  "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/bucket/projects/{projectId}/buckets/{bucketId}/files/{fileId}/transform?width=800&height=600&format=webp

Thumbnail shortcut:

HTTP
GET /api/bucket/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('files', fileInput.files[0]);

const response = await fetch(
  `https://cloud.mudbase.dev/api/bucket/projects/${projectId}/buckets/${bucketId}/files`,
  {
    method: 'POST',
    headers: { 'X-API-Key': apiKey },
    body: formData,
  }
);

const { files } = await response.json();
console.log('Uploaded file id:', files[0]._id);

Download (browser)

JavaScript
const response = await fetch(
  `https://cloud.mudbase.dev/api/bucket/projects/${projectId}/buckets/${bucketId}/files/${fileId}`,
  { headers: { 'X-API-Key': apiKey } }
);
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);

For schema-accurate request bodies, prefer the OpenAPI spec or a generated SDK.

Chat with us