v2.
0
File Storage API
[Link]
Upload, organize, transform, and serve files globally through a CDN-backed object store. Supports
multipart uploads up to 5 TB, on-the-fly image transforms, and signed URLs.
On This Page
●
Authentication
●
Endpoints overview
●
Manage buckets
●
Upload, list, and delete objects
●
Multipart uploads
●
Signed URLs
●
Image Transforms
●
Rate Limits & Quotas
●
Error Codes
●
Versioning & Changelog
●
SDKs & Client Libraries
Authentication
All requests must include an Authorization: Bearer <token> header. Tokens can be scoped to
one or more buckets and restricted to read-only access from the dashboard under Settings → Access
Tokens.
Authorization: Bearer st_live_3kF7...wN2y
Endpoints
POST /v2/buckets
Create a new storage bucket
GET /v2/buckets
List all buckets
DELETE /v2/buckets/{bucket}
Delete an empty bucket
POST /v2/buckets/{bucket}/objects
Upload a new object (single-part)
GET /v2/buckets/{bucket}/objects
List objects in a bucket
GET /v2/buckets/{bucket}/objects/{key}
Download or get metadata for an object
DELETE /v2/buckets/{bucket}/objects/{key}
Delete an object permanently
POST /v2/uploads
Initiate a multipart upload session
PUT /v2/uploads/{upload_id}/parts/{n}
Upload a single part
POST /v2/uploads/{upload_id}/complete
Complete the multipart upload
POST /v2/signed-urls
Generate a pre-signed GET or PUT URL
POST /v2/buckets — Create Bucket
Creates a new storage bucket. Bucket names must be globally unique, 3-63 characters, and
DNS-compatible (lowercase letters, digits, and hyphens).
Request Body
Parameter Type Required Description
name string Yes Bucket name; must be globally unique and DNS-compatible
region string No Storage region, e.g. us-east-1, eu-west-1 (default: us-east-1)
visibility string No public or private (default: private)
Example Request
POST /v2/buckets
{
"name": "user-assets",
"region": "us-east-1",
"visibility": "private"
}
Code Samples
cURL
curl -X POST \
"[Link] \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "user-assets",
"region": "us-east-1",
"visibility": "private"
}'
Python
import requests
url = "[Link]
headers = {"Authorization": f"Bearer {API_KEY}"}
payload = {
"name": "user-assets",
"region": "us-east-1",
"visibility": "private"
}
resp = [Link](url, headers=headers, json=payload)
print([Link]())
[Link]
const res = await fetch("[Link] {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: [Link]({"name": "user-assets", "region": "us-east-1", "visibility":
"private"}),
});
const data = await [Link]();
Response Fields
Field Type Description
name string Bucket name
region string Storage region
visibility string public or private
created_at string ISO 8601 timestamp of when the bucket was created
Example Response
{
"name": "user-assets",
"region": "us-east-1",
"visibility": "private",
"created_at": "2026-06-10T09:00:00Z"
}
GET /v2/buckets — List Buckets
Returns a paginated list of buckets owned by your account.
Query Parameters
Parameter Type Required Description
page integer No Page number, starting at 1 (default: 1)
per_page integer No Results per page, max 100 (default: 20)
Code Samples
cURL
curl -X GET \
"[Link] \
-H "Authorization: Bearer $API_KEY"
Python
import requests
url = "[Link]
headers = {"Authorization": f"Bearer {API_KEY}"}
resp = [Link](url, headers=headers)
print([Link]())
[Link]
const res = await fetch("[Link] {
method: "GET",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const data = await [Link]();
Response Fields
Field Type Description
name string Bucket name
region string Storage region
visibility string public or private
object_count integer Number of objects currently stored in the bucket
created_at string ISO 8601 timestamp of when the bucket was created
Example Response
{
"data": [
{
"name": "user-assets",
"region": "us-east-1",
"visibility": "private",
"object_count": 18420,
"created_at": "2026-06-10T09:00:00Z"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20
}
}
DELETE /v2/buckets/{bucket} — Delete Bucket
Permanently deletes a bucket. The bucket must be empty — delete all objects first.
Path Parameters
Field Type Description
bucket string Name of the bucket to delete
Code Samples
cURL
curl -X DELETE \
"[Link] \
-H "Authorization: Bearer $API_KEY"
Python
import requests
url = "[Link]
headers = {"Authorization": f"Bearer {API_KEY}"}
resp = [Link](url, headers=headers)
print([Link]())
[Link]
const res = await fetch("[Link] {
method: "DELETE",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const data = await [Link]();
Response Fields
Field Type Description
bucket string Name of the deleted bucket
deleted boolean Whether the bucket was deleted
Example Response
{
"bucket": "user-assets",
"deleted": true
}
Note: Returns 409 conflict if the bucket still contains objects.
POST /v2/buckets/{bucket}/objects — Upload Object
Uploads a file as a single-part request, with the file contents as the raw request body. Use the multipart
upload endpoints for files larger than 100 MB.
Path Parameters
Field Type Description
bucket string Name of the destination bucket
Headers
Parameter Type Required Description
Content-Type string Yes MIME type of the file, e.g. image/png
Content-Length integer Yes Byte size of the request body
X-Object-Key string No Override the generated key; must be URL-safe
Query Parameters
Parameter Type Required Description
visibility string No public or private (default)
ttl integer No Seconds until the object expires and is deleted
Comma-separated image transforms, e.g.
transform string No w=800,h=600,fit=crop
Code Samples
cURL
curl -X POST \
"[Link]
\
-H "Authorization: Bearer $API_KEY"
Python
import requests
url =
"[Link]
headers = {"Authorization": f"Bearer {API_KEY}"}
resp = [Link](url, headers=headers)
print([Link]())
[Link]
const res = await fetch("[Link]
ts?visibility=private", {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const data = await [Link]();
Response Fields
Field Type Description
key string Object key (path) within the bucket
bucket string Bucket the object belongs to
size integer Size of the object in bytes
content_type string MIME type of the object
visibility string public or private
url string CDN URL for the object
etag string MD5 checksum of the object content
created_at string ISO 8601 timestamp of when the object was created
Example Response
{
"key": "uploads/2026/06/[Link]",
"bucket": "user-assets",
"size": 204800,
"content_type": "image/png",
"visibility": "private",
"url": "[Link]
"etag": "d41d8cd98f00b204e9800998ecf8427e",
"created_at": "2026-06-10T15:00:00Z"
}
GET /v2/buckets/{bucket}/objects — List Objects
Returns a paginated list of objects in a bucket, optionally filtered by key prefix.
Path Parameters
Field Type Description
bucket string Name of the bucket
Query Parameters
Parameter Type Required Description
prefix string No Only return objects whose key starts with this prefix
limit integer No Max number of results (default 100, max 1000)
cursor string No Pagination cursor from a previous response
Code Samples
cURL
curl -X GET \
"[Link]
/" \
-H "Authorization: Bearer $API_KEY"
Python
import requests
url =
"[Link]
headers = {"Authorization": f"Bearer {API_KEY}"}
resp = [Link](url, headers=headers)
print([Link]())
[Link]
const res = await fetch("[Link]
ts?prefix=uploads/2026/", {
method: "GET",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const data = await [Link]();
Response Fields
Field Type Description
key string Object key (path) within the bucket
size integer Size of the object in bytes
content_type string MIME type of the object
etag string MD5 checksum of the object content
updated_at string ISO 8601 timestamp of when the object was last modified
Example Response
{
"data": [
{
"key": "uploads/2026/06/[Link]",
"size": 204800,
"content_type": "image/png",
"etag": "d41d8cd98f00b204e9800998ecf8427e",
"updated_at": "2026-06-10T09:00:00Z"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20
}
}
GET /v2/buckets/{bucket}/objects/{key} — Get Object
Returns metadata for an object. Set the Accept header to the object's content type (or omit it) to
download the raw file content instead of metadata.
Path Parameters
Field Type Description
bucket string Name of the bucket
key string Object key (path) within the bucket
Code Samples
cURL
curl -X GET \
"[Link]
[Link]" \
-H "Authorization: Bearer $API_KEY"
Python
import requests
url = "[Link]
/[Link]"
headers = {"Authorization": f"Bearer {API_KEY}"}
resp = [Link](url, headers=headers)
print([Link]())
[Link]
const res = await fetch("[Link]
ts/uploads/2026/06/[Link]", {
method: "GET",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const data = await [Link]();
Response Fields
Field Type Description
key string Object key (path) within the bucket
bucket string Bucket the object belongs to
size integer Size of the object in bytes
content_type string MIME type of the object
visibility string public or private
url string CDN URL for the object
etag string MD5 checksum of the object content
created_at string ISO 8601 timestamp of when the object was created
Example Response
{
"key": "uploads/2026/06/[Link]",
"bucket": "user-assets",
"size": 204800,
"content_type": "image/png",
"visibility": "private",
"url": "[Link]
"etag": "d41d8cd98f00b204e9800998ecf8427e",
"created_at": "2026-06-10T15:00:00Z"
}
DELETE /v2/buckets/{bucket}/objects/{key} — Delete
Object
Permanently deletes an object. This action cannot be undone.
Path Parameters
Field Type Description
bucket string Name of the bucket
key string Object key (path) within the bucket
Code Samples
cURL
curl -X DELETE \
"[Link]
[Link]" \
-H "Authorization: Bearer $API_KEY"
Python
import requests
url = "[Link]
/[Link]"
headers = {"Authorization": f"Bearer {API_KEY}"}
resp = [Link](url, headers=headers)
print([Link]())
[Link]
const res = await fetch("[Link]
ts/uploads/2026/06/[Link]", {
method: "DELETE",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const data = await [Link]();
Response Fields
Field Type Description
key string Object key that was deleted
bucket string Bucket the object belonged to
deleted boolean Whether the object was deleted
Example Response
{
"key": "uploads/2026/06/[Link]",
"bucket": "user-assets",
"deleted": true
}
POST /v2/uploads — Initiate Multipart Upload
Starts a multipart upload session for a large file. Returns an upload_id used to upload individual parts
and complete the upload.
Request Body
Parameter Type Required Description
bucket string Yes Destination bucket name
key string Yes Object key (path) the completed upload will be stored at
content_type string No MIME type of the final object
Example Request
POST /v2/uploads
{
"bucket": "user-assets",
"key": "uploads/2026/06/[Link]",
"content_type": "application/zip"
}
Code Samples
cURL
curl -X POST \
"[Link] \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"bucket": "user-assets",
"key": "uploads/2026/06/[Link]",
"content_type": "application/zip"
}'
Python
import requests
url = "[Link]
headers = {"Authorization": f"Bearer {API_KEY}"}
payload = {
"bucket": "user-assets",
"key": "uploads/2026/06/[Link]",
"content_type": "application/zip"
}
resp = [Link](url, headers=headers, json=payload)
print([Link]())
[Link]
const res = await fetch("[Link] {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: [Link]({"bucket": "user-assets", "key":
"uploads/2026/06/[Link]", "content_type": "application/zip"}),
});
const data = await [Link]();
Response Fields
Field Type Description
upload_id string Identifier for this multipart upload session
bucket string Destination bucket name
key string Object key the completed upload will be stored at
part_size_recomme Recommended part size in bytes (parts except the last must be at least
nded integer this size)
Example Response
{
"upload_id": "ul_4Bz81pQaXr",
"bucket": "user-assets",
"key": "uploads/2026/06/[Link]",
"part_size_recommended": 8388608
}
PUT /v2/uploads/{upload_id}/parts/{n} — Upload Part
Uploads a single part of a multipart upload, with the part contents as the raw request body. All parts except
the last must be at least 5 MB.
Path Parameters
Field Type Description
upload_id string Identifier of the multipart upload session
n integer Part number, starting at 1
Headers
Parameter Type Required Description
Content-Length integer Yes Byte size of this part
Code Samples
cURL
curl -X PUT \
"[Link] \
-H "Authorization: Bearer $API_KEY"
Python
import requests
url = "[Link]
headers = {"Authorization": f"Bearer {API_KEY}"}
resp = [Link](url, headers=headers)
print([Link]())
[Link]
const res = await
fetch("[Link] {
method: "PUT",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const data = await [Link]();
Response Fields
Field Type Description
part_number integer Part number that was uploaded
etag string MD5 checksum of this part's content
Example Response
{
"part_number": 1,
"etag": "d41d8cd98f00b204e9800998ecf8427e"
}
POST /v2/uploads/{upload_id}/complete — Complete
Multipart Upload
Finalizes a multipart upload by assembling the uploaded parts into a single object, in the order given by
parts.
Path Parameters
Field Type Description
upload_id string Identifier of the multipart upload session
Request Body
Parameter Type Required Description
parts array Yes Ordered array of {part_number, etag} objects
Example Request
POST /v2/uploads/{upload_id}/complete
{
"parts": [
{
"part_number": 1,
"etag": "d41d8cd98f00b204e9800998ecf8427e"
},
{
"part_number": 2,
"etag": "098f6bcd4621d373cade4e832627b4f6"
}
]
}
Code Samples
cURL
curl -X POST \
"[Link] \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"parts": [
{
"part_number": 1,
"etag": "d41d8cd98f00b204e9800998ecf8427e"
},
{
"part_number": 2,
"etag": "098f6bcd4621d373cade4e832627b4f6"
}
]
}'
Python
import requests
url = "[Link]
headers = {"Authorization": f"Bearer {API_KEY}"}
payload = {
"parts": [
{
"part_number": 1,
"etag": "d41d8cd98f00b204e9800998ecf8427e"
},
{
"part_number": 2,
"etag": "098f6bcd4621d373cade4e832627b4f6"
}
]
}
resp = [Link](url, headers=headers, json=payload)
print([Link]())
[Link]
const res = await
fetch("[Link] {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: [Link]({"parts": [{"part_number": 1, "etag":
"d41d8cd98f00b204e9800998ecf8427e"}, {"part_number": 2, "etag":
"098f6bcd4621d373cade4e832627b4f6"}]}),
});
const data = await [Link]();
Response Fields
Field Type Description
key string Object key of the completed upload
bucket string Bucket the object was stored in
size integer Total size of the assembled object in bytes
etag string MD5 checksum of the assembled object
url string CDN URL for the assembled object
Example Response
{
"key": "uploads/2026/06/[Link]",
"bucket": "user-assets",
"size": 16777216,
"etag": "d41d8cd98f00b204e9800998ecf8427e",
"url": "[Link]
}
POST /v2/signed-urls — Generate Signed URL
Returns a time-limited URL that allows a third party to GET or PUT an object without requiring API
credentials. Useful for direct browser uploads and private downloads.
Request Body
Parameter Type Required Description
bucket string Yes Target bucket name
key string Yes Object key path
method string Yes HTTP method for the signed URL: GET or PUT
expires_in integer No Seconds until expiry (default: 3600, max: 604800)
content_type string No Restrict PUT to this MIME type (PUT only)
Example Request
POST /v2/signed-urls
{
"bucket": "user-assets",
"key": "uploads/2026/06/[Link]",
"method": "GET",
"expires_in": 3600,
"content_type": "image/png"
}
Code Samples
cURL
curl -X POST \
"[Link] \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"bucket": "user-assets",
"key": "uploads/2026/06/[Link]",
"method": "GET",
"expires_in": 3600,
"content_type": "image/png"
}'
Python
import requests
url = "[Link]
headers = {"Authorization": f"Bearer {API_KEY}"}
payload = {
"bucket": "user-assets",
"key": "uploads/2026/06/[Link]",
"method": "GET",
"expires_in": 3600,
"content_type": "image/png"
}
resp = [Link](url, headers=headers, json=payload)
print([Link]())
[Link]
const res = await fetch("[Link] {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: [Link]({"bucket": "user-assets", "key":
"uploads/2026/06/[Link]", "method": "GET", "expires_in": 3600,
"content_type": "image/png"}),
});
const data = await [Link]();
Response Fields
Field Type Description
url string The pre-signed URL
method string HTTP method the URL is valid for
expires_at string ISO 8601 timestamp of when the URL expires
Example Response
{
"url": "[Link]
"method": "GET",
"expires_at": "2026-06-10T09:00:00Z"
}
Image Transforms
Image objects can be transformed on the fly by appending a transform query parameter to the object's
CDN URL, or at upload time. Transforms are cached at the edge after the first request.
Parameter Description Example
w Resize to this width in pixels w=800
h Resize to this height in pixels h=600
fit crop, contain, or fill (default: contain) fit=crop
format Convert to webp, avif, png, or jpg format=webp
quality JPEG/WebP quality, 1-100 (default: 85) quality=70
Example
[Link]
h=400,fit=crop,format=webp
Rate Limits & Quotas
Plan Requests Storage
Standard 300 req/min 100 GB
Pro 1,500 req/min 5 TB
Enterprise Custom Custom
Error Codes
Code HTTP Status Description
invalid_request 400 Missing or malformed parameters
authentication_error 401 Invalid or missing API key
not_found 404 Bucket, object, or upload session does not exist
conflict 409 Bucket name already taken, or bucket is not empty
payload_too_large 413 Object exceeds the 5 TB maximum size
rate_limit_exceeded 429 Too many requests, retry after the Retry-After header
server_error 500 Internal server error — contact support
Versioning & Changelog
Version Date Changes
v2.0 2026-02-10 Added on-the-fly image transforms and webp/avif output
v1.2 2025-08-04 Added multipart upload endpoints for files over 100 MB
v1.1 2025-03-19 Added signed URLs for GET and PUT
v1.0 2024-07-01 Initial public release
SDKs & Client Libraries
Language Package Install
Python storage-python pip install storage-sdk
[Link] @storage/node npm install @storage/node
Go go-storage go get [Link]/storage/go-sdk
Java storage-java implementation '[Link]:sdk:2.0.0'