Buckets
The buckets resource manages bucket lifecycle: provisioning new buckets,
reading their configuration and usage, updating settings, and deleting
buckets when they're no longer needed.
create
buckets.createPOST/v1/bucketsbuckets.create(opts: {
name: string;
customDomain: string;
region?: string;
cachePreset?: "no-cache" | "short" | "standard" | "aggressive" | "immutable";
corsOrigins?: string[];
lifecycleTtlDays?: number | null;
maxFileSizeBytes?: number | null;
allowedMimeTypes?: string[] | null;
optimizationMode?: "none" | "light" | "balanced" | "maximum";
awsAccountId?: string;
}): Promise<WriteResponse<"bucket">>Provisions a new bucket. The response includes only the id — fetch the
full bucket via buckets.get once provisioning completes (status
transitions from pending to active within a few minutes).
| Name | Type | Default | Description |
|---|---|---|---|
| namerequired | string | — | Display name for the bucket. 1–100 characters. |
| customDomainrequired | string | — | Custom domain to serve the bucket from (e.g. files.example.com). |
| region | string | "us-east-1" | AWS region where the underlying S3 bucket is provisioned. |
| cachePreset | "no-cache" | "short" | "standard" | "aggressive" | "immutable" | "standard" | CDN cache strategy applied to all objects. |
| corsOrigins | string[] | [] | Allow-listed origins for browser uploads. Up to 10 entries. |
| lifecycleTtlDays | number | null | null | Auto-delete objects this many days after upload. Range 1–3650. null disables expiry. |
| maxFileSizeBytes | number | null | null | Reject uploads larger than this size. null applies the default limit for your plan. |
| allowedMimeTypes | string[] | null | null | Allow-listed MIME patterns (e.g. "image/png", "image/*"). Up to 50 entries. null allows any type. |
| optimizationMode | "none" | "light" | "balanced" | "maximum" | "none" | Image optimization aggressiveness. Anything other than none requires a paid plan. |
| awsAccountId | string | — | Bring-your-own-account: provision the bucket in a connected AWS account. Requires a paid plan. |
const { id } = await client.buckets.create({
name: "Marketing assets",
customDomain: "files.example.com",
region: "us-east-1",
cachePreset: "standard",
});{
"object": "bucket",
"id": "bkt_01H8XYZABCDEFGHJKMNPQRSTVW"
}list
buckets.listGET/v1/bucketsbuckets.list(opts?: {
cursor?: string;
limit?: number;
status?: "pending" | "provisioning" | "active" | "failed" | "deleting";
}): Promise<{ data: Bucket[]; meta: CursorMeta }>Lists buckets in the organization. Cursor-paginated. See Pagination for the loop pattern.
| Name | Type | Default | Description |
|---|---|---|---|
| cursor | string | — | Opaque cursor returned from a previous call. Omit for the first page. |
| limit | number | 25 | Page size. Maximum 100. |
| status | "pending" | "provisioning" | "active" | "failed" | "deleting" | — | Restrict to buckets in a specific lifecycle state. |
const { data, meta } = await client.buckets.list({
status: "active",
limit: 50,
});
for (const bucket of data) {
console.log(bucket.id, bucket.name);
}{
"data": [
{
"object": "bucket",
"id": "bkt_01H8XYZABCDEFGHJKMNPQRSTVW",
"name": "Marketing assets",
"customDomain": "files.example.com",
"status": "active"
}
],
"meta": { "limit": 25, "nextCursor": null }
}get
buckets.getGET/v1/buckets/{id}buckets.get(id: string): Promise<Bucket>Fetches a single bucket by id, including configuration and usage counters.
Throws NotFoundError if the id is unknown or the key can't see the
bucket.
const bucket = await client.buckets.get(
"bkt_01H8XYZABCDEFGHJKMNPQRSTVW"
);
console.log(bucket.status, bucket.storageUsedBytes);{
"object": "bucket",
"id": "bkt_01H8XYZABCDEFGHJKMNPQRSTVW",
"name": "Marketing assets",
"customDomain": "files.example.com",
"status": "active",
"storageUsedBytes": 1048576,
"bandwidthUsedBytes": 524288
}update
buckets.updatePATCH/v1/buckets/{id}buckets.update(id: string, opts: {
name?: string;
cachePreset?: "no-cache" | "short" | "standard" | "aggressive" | "immutable";
cacheControlOverride?: string | null;
corsOrigins?: string[];
lifecycleTtlDays?: number | null;
maxFileSizeBytes?: number | null;
allowedMimeTypes?: string[] | null;
optimizationMode?: "none" | "light" | "balanced" | "maximum";
}): Promise<WriteResponse<"bucket">>Updates bucket settings. Pass only the fields you want to change — omitted
fields stay at their current value. To clear a nullable field (e.g.
lifecycleTtlDays), pass null explicitly.
| Name | Type | Default | Description |
|---|---|---|---|
| name | string | — | New display name. 1–100 characters. |
| cachePreset | "no-cache" | "short" | "standard" | "aggressive" | "immutable" | — | CDN cache strategy. |
| cacheControlOverride | string | null | — | Raw Cache-Control value applied to all objects. Set to null to clear and fall back to cachePreset. |
| corsOrigins | string[] | — | Allow-listed origins. Up to 10 entries. |
| lifecycleTtlDays | number | null | — | Auto-delete TTL. null disables expiry. |
| maxFileSizeBytes | number | null | — | Per-upload size cap. null falls back to plan default. |
| allowedMimeTypes | string[] | null | — | MIME allow-list. null allows any type. |
| optimizationMode | "none" | "light" | "balanced" | "maximum" | — | Image optimization aggressiveness. |
await client.buckets.update("bkt_01H8XYZABCDEFGHJKMNPQRSTVW", {
cachePreset: "aggressive",
});{
"object": "bucket",
"id": "bkt_01H8XYZABCDEFGHJKMNPQRSTVW"
}delete
buckets.deleteDELETE/v1/buckets/{id}buckets.delete(id: string): Promise<WriteResponse<"bucket"> & { status: "deleting" }>Marks the bucket for deletion. The response transitions the bucket into
deleting state; the underlying S3 bucket and DNS records are torn down
asynchronously. The bucket must be empty — ConflictError otherwise.
const { id, status } = await client.buckets.delete(
"bkt_01H8XYZABCDEFGHJKMNPQRSTVW"
);
console.log(status); // "deleting"{
"object": "bucket",
"id": "bkt_01H8XYZABCDEFGHJKMNPQRSTVW",
"status": "deleting"
}retry
buckets.retryPOST/v1/buckets/{id}/retrybuckets.retry(id: string): Promise<WriteResponse<"bucket">>Re-runs provisioning for a bucket stuck in failed state. Useful after
fixing the underlying cause (DNS, IAM, region availability). Throws
ConflictError if the bucket isn't in failed.
await client.buckets.retry("bkt_01H8XYZABCDEFGHJKMNPQRSTVW");{
"object": "bucket",
"id": "bkt_01H8XYZABCDEFGHJKMNPQRSTVW"
}