Storage API
REST API reference for uploading, downloading, and managing files.
Storage API
Storage routes use the bucket slug directly as the URL path prefix.
There is no /v1/ prefix for storage operations.
Base URL: https://superfiles-api.example.com
Auth: Authorization: Bearer sf_live_<key> on all storage endpoints.
Public-bucket reads require no auth.
PUT /{bucket}/{key}
Upload or replace a file. The key supports / separators (e.g. images/2026/photo.jpg).
Intermediate virtual folders are created automatically.
curl -X PUT https://superfiles-api.example.com/my-media/images/photo.jpg \
-H "Authorization: Bearer sf_live_xxxx" \
-H "Content-Type: image/jpeg" \
--data-binary @photo.jpg
Response 201:
{
"key": "images/photo.jpg",
"bucket": "my-media",
"size": 123456,
"etag": "sha256:abc...",
"contentType": "image/jpeg",
"format": "jpeg",
"width": 1920,
"height": 1080,
"hasAlpha": false,
"durationMs": null,
"createdAt": "2026-01-01T00:00:00Z"
}
GET /{bucket}/{key}
Download a file. Streams the raw blob.
curl https://superfiles-api.example.com/my-media/images/photo.jpg \
-H "Authorization: Bearer sf_live_xxxx" \
-o photo.jpg
Optional: ?versionId=<id> to download a specific past version.
Response 200: streaming body with headers:
Content-Type,Content-Length,ETag,Last-ModifiedX-SF-Width,X-SF-Height,X-SF-Format,X-SF-Has-Alpha(media files)
HEAD /{bucket}/{key}
Fetch metadata without downloading the body. Returns the same headers as GET, no body.
Response 200 | 404 { "error": { "code": "object_not_found", "message": "..." } }
DELETE /{bucket}/{key}
Delete a file. Use ?trash=true for a soft delete that can be recovered from the
trash.
# Hard delete (permanent)
curl -X DELETE https://superfiles-api.example.com/my-media/images/photo.jpg \
-H "Authorization: Bearer sf_live_xxxx"
# Soft delete (moves to trash)
curl -X DELETE "https://superfiles-api.example.com/my-media/images/photo.jpg?trash=true" \
-H "Authorization: Bearer sf_live_xxxx"
Response 204 (no body)
GET /{bucket}
List objects in a bucket with optional prefix filter.
Query params:
| Param | Type | Default | Description |
|---|---|---|---|
prefix |
string | — | Filter keys starting with this prefix |
cursor |
string | — | Pagination cursor from the previous response |
limit |
int | 100 |
Max objects to return (max: 1000) |
curl "https://superfiles-api.example.com/my-media?prefix=images/&limit=20" \
-H "Authorization: Bearer sf_live_xxxx"
Response 200:
{
"items": [
{
"key": "images/photo.jpg",
"size": 123456,
"contentType": "image/jpeg",
"lastModified": "2026-01-01T00:00:00Z",
"etag": "sha256:abc...",
"width": 1920,
"height": 1080
}
],
"nextCursor": "images/photo.jpg"
}
POST /{bucket}/{key}?copyFrom={srcKey}
Server-side copy within the same bucket. Returns 201 with the new object metadata.
POST /{bucket}/{key}?moveFrom={srcKey}
Server-side atomic move (copy + delete source). Returns 200 with the new object metadata.
CDN delivery
Public-bucket objects are served via the CDN endpoint with optional on-the-fly transforms. The transform segment is a comma-separated list of directives in alphabetical order.
GET /cdn/{bucket}/{key} serve original with CDN headers
GET /cdn/{bucket}/{transforms}/{key} serve transformed variant
Transform examples:
# 800×600 WebP, 85% quality
https://superfiles-api.example.com/cdn/my-media/f_webp,h_600,q_85,w_800/photo.jpg
# Square 300px avatar, auto-format, cover crop
https://superfiles-api.example.com/cdn/my-media/c_cover,f_auto,h_300,w_300/avatar.jpg
# Video thumbnail at 5 seconds
https://superfiles-api.example.com/cdn/my-media/f_jpg,t_5/video.mp4
See Core Concepts → CDN transforms for the full directive reference.
Transformed variants are cached immutably (Cache-Control: public, max-age=31536000, immutable).
S3-compatible endpoint
All storage operations are also available at /s3/{bucket}/{key} with AWS4-HMAC-SHA256
authentication. Use your SuperFiles API key as both the access key ID and the secret key.
export AWS_ACCESS_KEY_ID=sf_live_xxxx
export AWS_SECRET_ACCESS_KEY=sf_live_xxxx
export AWS_ENDPOINT_URL=https://superfiles-api.example.com/s3
aws s3 cp photo.jpg s3://my-media/images/photo.jpg
aws s3 ls s3://my-media/images/
S3 multipart upload (PUT ?partNumber=N&uploadId=X) is supported for files larger
than 5 MB, which is what the AWS SDK uses automatically for large files.
Presigned uploads
Generate a short-lived URL that allows a client to upload directly without exposing your API key:
curl -X POST https://superfiles-api.example.com/signed-upload \
-H "Authorization: Bearer sf_live_xxxx" \
-H "Content-Type: application/json" \
-d '{
"bucket": "my-media",
"key": "uploads/user-avatar.jpg",
"contentType": "image/jpeg",
"expiresIn": 3600
}'
Response:
{
"uploadUrl": "https://superfiles-api.example.com/my-media/uploads/user-avatar.jpg?sig=...&expires=...",
"expiresAt": "2026-01-01T01:00:00Z"
}
The client can then PUT directly to uploadUrl without any Authorization header.