Skip to main content
Cloudflare R2 is an S3-compatible object storage service with zero egress fees. Use the API to manage buckets and configure storage settings.

Overview

Access the R2 API:
import Cloudflare from 'cloudflare';

const client = new Cloudflare({
  apiToken: process.env.CLOUDFLARE_API_TOKEN,
});

// Access R2 resources
const r2 = client.r2;

Buckets

Manage R2 storage buckets.

Create a bucket

Create a new R2 bucket.
const bucket = await client.r2.buckets.create({
  account_id: '023e105f4ecef8ad9ca31a8372d0c353',
  name: 'my-bucket',
});
account_id
string
required
Your Cloudflare account ID
name
string
required
Bucket name (3-63 characters, lowercase, alphanumeric, and hyphens)
jurisdiction
string
Data jurisdiction for the bucket (e.g., ‘eu’ for EU data residency)
storage_class
string
Storage class: ‘Standard’ or ‘InfrequentAccess’
name
string
The bucket name
creation_date
string
ISO 8601 timestamp when the bucket was created
location
string
The bucket’s location/jurisdiction

List buckets

Retrieve all R2 buckets in your account.
const buckets = await client.r2.buckets.list({
  account_id: '023e105f4ecef8ad9ca31a8372d0c353',
});
account_id
string
required
Your Cloudflare account ID
jurisdiction
string
Filter buckets by jurisdiction
cursor
string
Pagination cursor
per_page
number
Number of buckets per page (default: 1000, max: 1000)
buckets
array
Array of bucket objects

Get a bucket

Retrieve details about a specific bucket.
const bucket = await client.r2.buckets.get(
  'my-bucket',
  { account_id: '023e105f4ecef8ad9ca31a8372d0c353' }
);
bucket_name
string
required
The bucket name
account_id
string
required
Your Cloudflare account ID

Update a bucket

Update bucket configuration.
const bucket = await client.r2.buckets.edit(
  'my-bucket',
  {
    account_id: '023e105f4ecef8ad9ca31a8372d0c353',
    storage_class: 'InfrequentAccess',
  }
);
bucket_name
string
required
The bucket name
account_id
string
required
Your Cloudflare account ID
storage_class
string
Storage class: ‘Standard’ or ‘InfrequentAccess’

Delete a bucket

Delete an R2 bucket. The bucket must be empty.
await client.r2.buckets.delete(
  'my-bucket',
  { account_id: '023e105f4ecef8ad9ca31a8372d0c353' }
);
bucket_name
string
required
The bucket name to delete
account_id
string
required
Your Cloudflare account ID

CORS

Manage Cross-Origin Resource Sharing (CORS) policies.

Get CORS configuration

Retrieve the CORS configuration for a bucket.
const cors = await client.r2.buckets.cors.get(
  'my-bucket',
  { account_id: '023e105f4ecef8ad9ca31a8372d0c353' }
);

Update CORS configuration

Set CORS rules for a bucket.
const cors = await client.r2.buckets.cors.update(
  'my-bucket',
  {
    account_id: '023e105f4ecef8ad9ca31a8372d0c353',
    rules: [
      {
        allowed_origins: ['https://example.com'],
        allowed_methods: ['GET', 'PUT'],
        allowed_headers: ['*'],
        max_age_seconds: 3600,
      },
    ],
  }
);
rules
array
required
Array of CORS rule objects
rules.allowed_origins
array
required
Array of allowed origin URLs
rules.allowed_methods
array
required
Array of allowed HTTP methods
rules.allowed_headers
array
Array of allowed headers (use [’*’] for all headers)
rules.max_age_seconds
number
Cache duration for preflight requests in seconds

Delete CORS configuration

Remove CORS configuration from a bucket.
await client.r2.buckets.cors.delete(
  'my-bucket',
  { account_id: '023e105f4ecef8ad9ca31a8372d0c353' }
);

Lifecycle policies

Manage object lifecycle rules.

Get lifecycle configuration

const lifecycle = await client.r2.buckets.lifecycle.get(
  'my-bucket',
  { account_id: '023e105f4ecef8ad9ca31a8372d0c353' }
);

Update lifecycle configuration

Set lifecycle rules to automatically delete or transition objects.
const lifecycle = await client.r2.buckets.lifecycle.update(
  'my-bucket',
  {
    account_id: '023e105f4ecef8ad9ca31a8372d0c353',
    rules: [
      {
        id: 'delete-old-logs',
        status: 'Enabled',
        prefix: 'logs/',
        expiration: {
          days: 30,
        },
      },
    ],
  }
);
rules
array
required
Array of lifecycle rule objects
rules.id
string
required
Unique identifier for the rule
rules.status
string
required
Rule status: ‘Enabled’ or ‘Disabled’
rules.prefix
string
Object key prefix to match
rules.expiration
object
Expiration settings
rules.expiration.days
number
Number of days after which objects expire

Event notifications

Configure event notifications to trigger Workers or send to queues.

Get event notifications

const notifications = await client.r2.buckets.eventNotifications.get(
  'my-bucket',
  { account_id: '023e105f4ecef8ad9ca31a8372d0c353' }
);

Update event notifications

const notifications = await client.r2.buckets.eventNotifications.update(
  'my-bucket',
  {
    account_id: '023e105f4ecef8ad9ca31a8372d0c353',
    rules: [
      {
        prefix: 'uploads/',
        suffix: '.jpg',
        actions: ['PutObject'],
        queue_id: 'queue-id',
      },
    ],
  }
);
rules
array
required
Array of event notification rules
rules.actions
array
required
Array of S3 event types (e.g., ‘PutObject’, ‘DeleteObject’)
rules.queue_id
string
Cloudflare Queue ID to send notifications to
rules.prefix
string
Object key prefix filter
rules.suffix
string
Object key suffix filter

Temporary credentials

Generate temporary S3-compatible credentials for bucket access.

Create temporary credentials

const credentials = await client.r2.temporaryCredentials.create({
  account_id: '023e105f4ecef8ad9ca31a8372d0c353',
  bucket_name: 'my-bucket',
  permissions: ['read', 'write'],
  ttl_seconds: 3600,
});
account_id
string
required
Your Cloudflare account ID
bucket_name
string
required
The bucket name
permissions
array
required
Array of permissions: ‘read’, ‘write’, or ‘delete’
ttl_seconds
number
Time-to-live in seconds (default: 3600, max: 43200)
access_key_id
string
S3-compatible access key ID
secret_access_key
string
S3-compatible secret access key
session_token
string
Session token for temporary credentials
expiration
string
ISO 8601 timestamp when credentials expire

Using R2 in Workers

Bind an R2 bucket to your Worker:
const version = await client.workers.beta.workers.versions.create(
  workerId,
  {
    account_id: accountId,
    main_module: 'worker.mjs',
    compatibility_date: '2024-03-01',
    bindings: [
      {
        type: 'r2_bucket',
        name: 'BUCKET',
        bucket_name: 'my-bucket',
      },
    ],
    modules: [...],
  }
);
Then access R2 from your Worker:
export default {
  async fetch(request, env) {
    // Put an object
    await env.BUCKET.put('key', 'value');
    
    // Get an object
    const object = await env.BUCKET.get('key');
    const text = await object.text();
    
    // List objects
    const list = await env.BUCKET.list();
    
    return new Response(text);
  },
};

Super Slurper

Migrate data from other cloud providers to R2.

Get Super Slurper configuration

const config = await client.r2.superSlurper.get(
  'my-bucket',
  { account_id: '023e105f4ecef8ad9ca31a8372d0c353' }
);

Build docs developers (and LLMs) love