Skip to content
Back to skills

076 Api F3f2999d

ASecurity

```typescript // Basic await env.MY_BUCKET.put(key, value)

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 31, 2026
securitytypescriptbashawsapi

Works with

  • cursor
  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned May 31, 2026

npx -y skills add tools-only/X-Skills --skill 076-api_f3f2999d --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 076 Api F3f2999d?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 076 Api F3f2999d
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-076-api-f3f2999d/badge)](https://www.skillsdirectory.com/skills/tools-only-076-api-f3f2999d)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# R2 API Reference

## PUT (Upload)

```typescript
// Basic
await env.MY_BUCKET.put(key, value)

// With metadata
await env.MY_BUCKET.put(key, value, {
  httpMetadata: {
    contentType: 'image/jpeg',
    contentDisposition: 'attachment; filename="photo.jpg"',
    cacheControl: 'max-age=3600',
  },
  customMetadata: { userId: '123', version: '2' },
  storageClass: 'Standard', // or 'InfrequentAccess'
  sha256: arrayBufferOrHex, // Integrity check
  ssecKey: [REDACTED], // SSE-C encryption
})

// Value types: ReadableStream | ArrayBuffer | string | Blob
```

## GET (Download)

```typescript
const object = await env.MY_BUCKET.get(key)
if (!object) return new Response('Not found', { status: 404 })

// Body: arrayBuffer(), text(), json(), blob(), body (ReadableStream)

// Ranged reads
const object = await env.MY_BUCKET.get(key, { range: { offset: 0, length: 1024 } })

// Conditional GET
const object = await env.MY_BUCKET.get(key, { onlyIf: { etagMatches: '"abc123"' } })
```

## HEAD (Metadata Only)

```typescript
const object = await env.MY_BUCKET.head(key) // Returns R2Object without body
```

## DELETE

```typescript
await env.MY_BUCKET.delete(key)
await env.MY_BUCKET.delete([key1, key2, key3]) // Batch (max 1000)
```

## LIST

```typescript
const listed = await env.MY_BUCKET.list({
  limit: 1000,
  prefix: 'photos/',
  cursor: cursorFromPrevious,
  delimiter: '/',
  include: ['httpMetadata', 'customMetadata'],
})

// Pagination (always use truncated flag)
while (listed.truncated) {
  const next = await env.MY_BUCKET.list({ cursor: listed.cursor })
  listed.objects.push(...next.objects)
  listed.truncated = next.truncated
  listed.cursor = next.cursor
}
```

## Multipart Uploads

```typescript
const multipart = await env.MY_BUCKET.createMultipartUpload(key, {
  httpMetadata: { contentType: 'video/mp4' },
})

const uploadedParts: R2UploadedPart[] = []
for (let i = 0; i < partCount; i++) {
  const part = await multipart.uploadPart(i + 1, partData)
  uploadedParts.push(part)
}

const object = await multipart.complete(uploadedParts)
// OR: await multipart.abort();

// Resume
const multipart = env.MY_BUCKET.resumeMultipartUpload(key, uploadId)
```

## Presigned URLs (S3 SDK)

```typescript
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'

const s3 = new S3Client({
  region: 'auto',
  endpoint: `https://${accountId}.r2.cloudflarestorage.com`,
  credentials: { accessKeyId: env.R2_ACCESS_KEY_ID, secretAccessKey: env.R2_SECRET_ACCESS_KEY },
})

const uploadUrl = await getSignedUrl(s3, new PutObjectCommand({ Bucket: 'my-bucket', Key: key }), { expiresIn: 3600 })
return Response.json({ uploadUrl })
```

## TypeScript Interfaces

```typescript
interface R2Bucket {
  head(key: string): Promise<R2Object | null>
  get(key: string, options?: R2GetOptions): Promise<R2ObjectBody | null>
  put(
    key: string,
    value: ReadableStream | ArrayBuffer | string | Blob,
    options?: R2PutOptions,
  ): Promise<R2Object | null>
  delete(keys: string | string[]): Promise<void>
  list(options?: R2ListOptions): Promise<R2Objects>
  createMultipartUpload(key: string, options?: R2MultipartOptions): Promise<R2MultipartUpload>
  resumeMultipartUpload(key: string, uploadId: string): R2MultipartUpload
}

interface R2Object {
  key: string
  version: string
  size: number
  etag: string
  httpEtag: string // httpEtag is quoted, use for headers
  uploaded: Date
  httpMetadata?: R2HTTPMetadata
  customMetadata?: Record<string, string>
  storageClass: 'Standard' | 'InfrequentAccess'
  checksums: R2Checksums
  writeHttpMetadata(headers: Headers): void
}

interface R2ObjectBody extends R2Object {
  body: ReadableStream
  bodyUsed: boolean
  arrayBuffer(): Promise<ArrayBuffer>
  text(): Promise<string>
  json<T>(): Promise<T>
  blob(): Promise<Blob>
}

interface R2HTTPMetadata {
  contentType?: string
  contentDisposition?: string
  contentEncoding?: string
  contentLanguage?: string
  cacheControl?: string
  cacheExpiry?: Date
}

interface R2PutOptions {
  httpMetadata?: R2HTTPMetadata | Headers
  customMetadata?: Record<string, string>
  sha256?: ArrayBuffer | string // Only ONE checksum allowed
  storageClass?: 'Standard' | 'InfrequentAccess'
  ssecKey?: ArrayBuffer
}

interface R2GetOptions {
  onlyIf?: R2Conditional | Headers
  range?: R2Range | Headers
  ssecKey?: ArrayBuffer
}

interface R2ListOptions {
  limit?: number
  prefix?: string
  cursor?: string
  delimiter?: string
  startAfter?: string
  include?: ('httpMetadata' | 'customMetadata')[]
}

interface R2Objects {
  objects: R2Object[]
  truncated: boolean
  cursor?: string
  delimitedPrefixes: string[]
}

interface R2Conditional {
  etagMatches?: string
  etagDoesNotMatch?: string
  uploadedBefore?: Date
  uploadedAfter?: Date
}

interface R2Range {
  offset?: number
  length?: number
  suffix?: number
}

interface R2Checksums {
  md5?: ArrayBuffer
  sha1?: ArrayBuffer
  sha256?: ArrayBuffer
  sha384?: ArrayBuffer
  sha512?: ArrayBuffer
}

interface R2MultipartUpload {
  key: string
  uploadId: string
  uploadPart(partNumber: number, value: ReadableStream | ArrayBuffer | string | Blob): Promise<R2UploadedPart>
  abort(): Promise<void>
  complete(uploadedParts: R2UploadedPart[]): Promise<R2Object>
}

interface R2UploadedPart {
  partNumber: number
  etag: string
}
```

## CLI Operations

```bash
wrangler r2 object put my-bucket/file.txt --file=./local.txt
wrangler r2 object get my-bucket/file.txt --file=./download.txt
wrangler r2 object delete my-bucket/file.txt
wrangler r2 object list my-bucket --prefix=photos/
```

Files in this skill

  • README.md957 B
  • skill.md5.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.