Storage API
REST API reference for uploading, downloading, and managing files.
Storage API
The Storage API handles all file operations: upload, download, list, copy, move, delete, and presigned URLs.
Base URL: https://api.superfiles.montr.online/v1/storage
All requests require an Authorization: Bearer sf_live_... header (or ?token= for presigned URLs).
Upload an object
PUT /v1/storage/:bucket/:key
Upload a file to a bucket. The :key is the object path within the bucket (e.g. images/avatar.jpg).
Headers:
| Header | Required | Description |
|---|---|---|
Content-Type |
Yes | MIME type of the file |
Content-Length |
Recommended | File size in bytes |
Response 200:
{
"key": "images/avatar.jpg",
"bucket": "my-media",
"size": 45231,
"contentType": "image/jpeg",
"hash": "sha256:abc123...",
"url": "https://cdn.superfiles.montr.online/my-media/images/avatar.jpg",
"createdAt": "2025-08-07T12:34:56.000Z",
"updatedAt": "2025-08-07T12:34:56.000Z"
}
url is null for private buckets. Use a presigned download URL for private access.
Download an object
GET /v1/storage/:bucket/:key
Stream the object contents. Returns the raw file with appropriate Content-Type and Content-Length headers.
Private bucket objects require the Authorization header or a ?token= presigned token.
Get object metadata
HEAD /v1/storage/:bucket/:key
Returns the same headers as GET without the body. Use to check ETag, Content-Type, and Content-Length without downloading.
Delete an object
DELETE /v1/storage/:bucket/:key
Soft-deletes the object (moves to trash). The blob is not immediately removed; its reference count is decremented and the blob is garbage-collected when it reaches zero.
Response 204: No content.
List objects
GET /v1/storage/:bucket
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
prefix |
string | — | Return only objects whose key starts with this prefix |
delimiter |
string | — | Group keys by delimiter (use / for folder-like listing) |
limit |
number | 100 |
Max objects to return (max: 1000) |
cursor |
string | — | Pagination cursor from previous response |
Response 200:
{
"items": [
{
"key": "images/avatar.jpg",
"size": 45231,
"contentType": "image/jpeg",
"url": "https://cdn.superfiles.montr.online/...",
"updatedAt": "2025-08-07T12:34:56.000Z"
}
],
"prefixes": ["images/avatars/", "images/banners/"],
"nextCursor": "eyJrZXkiOiJpbWFnZXMvYXZhdGFyLmpwZyJ9"
}
prefixes is populated when delimiter is set — these are the “virtual folders” under the given prefix.
Copy an object
POST /v1/storage/:bucket/:key/copy
Body:
{
"destBucket": "my-backups",
"destKey": "2025-08/avatar.jpg"
}
Response 200: The new object record.
Move an object
POST /v1/storage/:bucket/:key/move
Body:
{
"destBucket": "my-media",
"destKey": "images/profile.jpg"
}
Renames or moves the object. The source key is deleted after the move.
Presigned upload URL
POST /v1/storage/:bucket/:key/presign-upload
Generate a URL that a client can PUT to directly, without exposing the API key.
Body:
{
"contentType": "image/jpeg",
"expiresIn": 300
}
Response 200:
{
"url": "https://api.superfiles.montr.online/v1/storage/my-media/images/avatar.jpg?token=..."
}
The presigned URL expires after expiresIn seconds (max: 86400).
Presigned download URL
POST /v1/storage/:bucket/:key/presign
Body:
{
"expiresIn": 3600
}
Response 200:
{
"url": "https://api.superfiles.montr.online/v1/storage/my-media/images/avatar.jpg?token=..."
}
Error codes
| Code | HTTP | Description |
|---|---|---|
storage.bucket_not_found |
404 | Bucket slug does not exist |
storage.object_not_found |
404 | Key does not exist in the bucket |
storage.bucket_not_public |
403 | Bucket is private and no auth token was provided |
storage.upload_failed |
500 | Write to blob store failed |
storage.quota_exceeded |
402 | Team storage quota is exhausted |