Bucket0 Developer Docs

Two ways to integrate: AgentBucket API for AI agents, and an S3-compatible API for standard tooling.

AgentBucket API

Bearer token auth for AI agents to upload, download, list, delete files, and create folders

S3-Compatible API

AWS Signature V4 auth — works with AWS CLI, SDKs, Cyberduck, rclone, and more

Introduction

What you can build with Bucket0

Bucket0 exposes two developer APIs for programmatic access to your storage:

AgentBucket API

Designed for AI agents. Create API keys from your dashboard, then use Bearer token auth to upload, download, list, delete files, and create folders. Keys are prefixed with b0ak_.

S3-Compatible API

A standard S3 endpoint with AWS Signature V4 authentication. Create access keys from your dashboard, then use any S3 client — AWS CLI, boto3, aws-sdk, Cyberduck, rclone, etc. Access key format: B0IAXXXXXXXXXXXXXXXX.

Authentication

How to get credentials from the dashboard

AgentBucket — Bearer Token

1. Go to Dashboard > AgentBucket > API Keys > New Key

2. Name your key (e.g., "my-coding-agent")

3. Choose destination: AgentBucket (files go to review tab) or My Drive (files go directly to your drive, optionally into a folder)

4. Copy the key — it's shown only once

5. Copy the API Guide (available in the same tab) and give it to your agent as a reference file — it includes endpoints, examples, error handling, and best practices for instant setup

Authorization: Bearer b0ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

S3 API — AWS Signature V4

1. Go to Dashboard > S3 API > Access Keys > Create Key

2. Name your key (e.g., "CLI Access")

3. Copy both the Access Key ID (B0IAXXXXXXXXXXXXXXXX) and Secret Access Key — shown only once

4. Copy the S3 API Integration Guide (available in the same tab) and give it to your agent — it covers all S3 operations, error handling, and best practices

aws configure --profile bucket0
AWS Access Key ID: B0IAXXXXXXXXXXXXXXXX
AWS Secret Access Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Default region name: auto

Endpoint: https://s3.bucket0.com

Important: Both API keys and S3 credentials are shown only once at creation. Store them securely. You can deactivate or delete keys anytime from the dashboard.

AgentBucket API

File storage for AI agents

AgentBucket lets AI agents save files directly to your storage using API keys. Files land in your Agent Storage tab by default (for review before moving to drive), or directly in your Drive if the key is configured with "My Drive" destination.

Endpoints

POST /api/agent-bucket/files/upload

Upload a file (multipart/form-data)

GET /api/agent-bucket/files

List files (paginated)

GET /api/agent-bucket/files/download

Download a file by key

DELETE /api/agent-bucket/files

Delete a file by key

POST /api/agent-bucket/files/folder

Create a folder

Upload a File

Send multipart/form-data with a file field and optional filename (defaults to file name). Files are encrypted with AES-128-GCM automatically.

const apiKey = 'b0ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

const formData = new FormData();
formData.append('file', fileBuffer);
formData.append('filename', 'research/results.json');

const response = await fetch('https://bucket0.com/api/agent-bucket/files/upload', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${apiKey}` },
  body: formData,
});

const data = await response.json();
// { success: true, key: "research/results.json", fileName: "results.json", size: 2048, destination: "agent" }

Response includes: success, key, fileName, size, destination("agent" or "drive").

List Files

const apiKey = 'b0ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

const response = await fetch('https://bucket0.com/api/agent-bucket/files?page=1&pageSize=50', {
  headers: { 'Authorization': `Bearer ${apiKey}` },
});

const { files, pagination } = await response.json();
// pagination: { total: 25, page: 1, pageSize: 50, hasMore: false }
files.forEach(file => {
  console.log(`${file.fileName} - ${file.size} bytes (via ${file.uploadedVia})`);
});

Params: page (default 1), pageSize (default 50, max 100). Each file includes: key, fileName, size, mimeType, isStarred, uploadedVia, createdAt, updatedAt.

Download a File

Returns the binary file stream. Files are automatically decrypted. Response headers include Content-Type, Content-Disposition, and Content-Length.

const apiKey = 'b0ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const key = 'research/results.json';

const response = await fetch(
  `https://bucket0.com/api/agent-bucket/files/download?key=${encodeURIComponent(key)}`,
  { headers: { 'Authorization': `Bearer ${apiKey}` } }
);

// Response is binary with headers:
// Content-Type, Content-Disposition, Content-Length
const blob = await response.blob();

Delete a File

Deletes the file and automatically releases storage quota.

DELETE /api/agent-bucket/files?key=research/results.json
Authorization: Bearer b0ak_xxx...

→ { "success": true }

Create a Folder

Creates a folder marker. Path cannot contain .. or //.

POST /api/agent-bucket/files/folder
Authorization: Bearer b0ak_xxx...
Content-Type: application/json

{ "path": "reports/daily" }

→ { "success": true, "path": "reports/daily/" }

Error Codes

400

Missing file, filename, or invalid path

401

Missing, invalid, or expired API key

402

Plan limit, storage quota, or file size exceeded

404

File not found

429

Rate limit exceeded (100/min)

S3-Compatible API

Use AWS SDKs, CLI, and S3 tools

Full S3-compatible API with AWS Signature V4. Use AWS CLI, SDKs, Cyberduck, WinSCP, rclone, and any other S3 client.

Endpoint

https://s3.bucket0.com

Supported Operations

GET /

ListBuckets

GET /{bucket}

ListObjectsV2

HEAD /{bucket}

HeadBucket

PUT /{bucket}

CreateBucket

DELETE /{bucket}

DeleteBucket (must be empty)

GET /{bucket}/{key}

GetObject (Range supported)

HEAD /{bucket}/{key}

HeadObject

PUT /{bucket}/{key}

PutObject (auto-creates bucket)

DELETE /{bucket}/{key}

DeleteObject (idempotent)

Behavior

  • Buckets auto-create on first PutObject — no need to CreateBucket first
  • DeleteObject returns 204 even if the object doesn't exist (idempotent)
  • GetObject supports Range requests (returns 206 Partial Content)
  • PutObject enforces plan storage and file size limits with atomic quota reservation
  • DeleteBucket requires the bucket to be empty first
  • ListObjectsV2 supports prefix, delimiter, max-keys, and continuation-token

List Buckets

import { S3Client, ListBucketsCommand } from '@aws-sdk/client-s3';

const client = new S3Client({
  endpoint: 'https://s3.bucket0.com',
  region: 'auto',
  credentials: {
    accessKeyId: 'YOUR_ACCESS_KEY_ID',
    secretAccessKey: 'YOUR_SECRET_ACCESS_KEY',
  },
});

const { Buckets } = await client.send(new ListBucketsCommand({}));
Buckets?.forEach(b => console.log(b.Name, b.CreationDate));

Upload a File

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

const client = new S3Client({
  endpoint: 'https://s3.bucket0.com',
  region: 'auto',
  credentials: {
    accessKeyId: 'YOUR_ACCESS_KEY_ID',
    secretAccessKey: 'YOUR_SECRET_ACCESS_KEY',
  },
});

await client.send(new PutObjectCommand({
  Bucket: 'my-bucket',
  Key: 'documents/report.pdf',
  Body: fileBuffer,
  ContentType: 'application/pdf',
}));
// Returns ETag header on success

Download a File

Response includes standard S3 headers: Content-Type, Content-Length, ETag, Last-Modified, Accept-Ranges.

import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';

const client = new S3Client({
  endpoint: 'https://s3.bucket0.com',
  region: 'auto',
  credentials: {
    accessKeyId: 'YOUR_ACCESS_KEY_ID',
    secretAccessKey: 'YOUR_SECRET_ACCESS_KEY',
  },
});

const response = await client.send(new GetObjectCommand({
  Bucket: 'my-bucket',
  Key: 'documents/report.pdf',
}));

// response includes: ContentType, ContentLength, ETag, LastModified
const chunks = [];
for await (const chunk of response.Body) {
  chunks.push(chunk);
}
const buffer = Buffer.concat(chunks);

AWS CLI

# Configure
aws configure --profile bucket0
AWS Access Key ID: B0IAXXXXXXXXXXXXXXXX
AWS Secret Access Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Default region name: auto
Default output format: json

# List buckets
aws s3 ls --endpoint-url https://s3.bucket0.com --profile bucket0

# Upload file
aws s3 cp report.pdf s3://my-bucket/documents/report.pdf \
  --endpoint-url https://s3.bucket0.com --profile bucket0

# Download file
aws s3 cp s3://my-bucket/documents/report.pdf ./report.pdf \
  --endpoint-url https://s3.bucket0.com --profile bucket0

S3 Error Codes

AccessDenied

Invalid signature or expired credentials

NoSuchBucket

Bucket does not exist

NoSuchKey

Object does not exist

BucketNotEmpty

Cannot delete non-empty bucket

QuotaExceeded

Storage limit reached

EntityTooLarge

File exceeds plan size limit

SDK Examples

Code examples in JavaScript, Python, Go, and Rust

AgentBucket

Upload File

const apiKey = 'b0ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

const formData = new FormData();
formData.append('file', fileBuffer);
formData.append('filename', 'research/results.json');

const response = await fetch('https://bucket0.com/api/agent-bucket/files/upload', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${apiKey}` },
  body: formData,
});

const data = await response.json();
// { success: true, key: "research/results.json", fileName: "results.json", size: 2048, destination: "agent" }

List Files

const apiKey = 'b0ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

const response = await fetch('https://bucket0.com/api/agent-bucket/files?page=1&pageSize=50', {
  headers: { 'Authorization': `Bearer ${apiKey}` },
});

const { files, pagination } = await response.json();
// pagination: { total: 25, page: 1, pageSize: 50, hasMore: false }
files.forEach(file => {
  console.log(`${file.fileName} - ${file.size} bytes (via ${file.uploadedVia})`);
});

Download File

const apiKey = 'b0ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const key = 'research/results.json';

const response = await fetch(
  `https://bucket0.com/api/agent-bucket/files/download?key=${encodeURIComponent(key)}`,
  { headers: { 'Authorization': `Bearer ${apiKey}` } }
);

// Response is binary with headers:
// Content-Type, Content-Disposition, Content-Length
const blob = await response.blob();

S3-Compatible API

List Buckets

import { S3Client, ListBucketsCommand } from '@aws-sdk/client-s3';

const client = new S3Client({
  endpoint: 'https://s3.bucket0.com',
  region: 'auto',
  credentials: {
    accessKeyId: 'YOUR_ACCESS_KEY_ID',
    secretAccessKey: 'YOUR_SECRET_ACCESS_KEY',
  },
});

const { Buckets } = await client.send(new ListBucketsCommand({}));
Buckets?.forEach(b => console.log(b.Name, b.CreationDate));

Upload

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

const client = new S3Client({
  endpoint: 'https://s3.bucket0.com',
  region: 'auto',
  credentials: {
    accessKeyId: 'YOUR_ACCESS_KEY_ID',
    secretAccessKey: 'YOUR_SECRET_ACCESS_KEY',
  },
});

await client.send(new PutObjectCommand({
  Bucket: 'my-bucket',
  Key: 'documents/report.pdf',
  Body: fileBuffer,
  ContentType: 'application/pdf',
}));
// Returns ETag header on success

Download

import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';

const client = new S3Client({
  endpoint: 'https://s3.bucket0.com',
  region: 'auto',
  credentials: {
    accessKeyId: 'YOUR_ACCESS_KEY_ID',
    secretAccessKey: 'YOUR_SECRET_ACCESS_KEY',
  },
});

const response = await client.send(new GetObjectCommand({
  Bucket: 'my-bucket',
  Key: 'documents/report.pdf',
}));

// response includes: ContentType, ContentLength, ETag, LastModified
const chunks = [];
for await (const chunk of response.Body) {
  chunks.push(chunk);
}
const buffer = Buffer.concat(chunks);

Rate Limits

API request limits per user

Request Limits

OperationLimitWindow
File Upload100per minute
General API200per minute
Share Links100per hour
S3 Connection Test15per minute

Handling 429 Responses

When rate limited, the response includes headers to help you retry:

X-RateLimit-Limit: 100        # max requests allowed
X-RateLimit-Remaining: 0      # requests remaining
X-RateLimit-Reset: 1713024060 # Unix timestamp when limit resets
  • Implement exponential backoff — wait for the reset timestamp before retrying
  • Cache file listings to reduce API calls
  • Store API keys server-side — never expose them in client code