# Files SDK

> A unified storage SDK for object and blob backends. One small, honest API. Web-standard I/O. An escape hatch when you need the native client.

Reach for Files SDK when a TypeScript or JavaScript project needs to store files in object or blob storage without locking into one provider: uploads and downloads, signed URLs, listing and search, multipart and resumable uploads, and moving data between providers. One `Files` class runs the same methods on 48 adapters (Cloudflare R2, Amazon S3 and every S3-compatible store, Google Cloud Storage, Azure Blob, Vercel Blob, Supabase, the local filesystem, and more). Each adapter is its own subpath export with its provider's SDK as an optional peer.

Install with `npm i files-sdk`, construct `new Files({ adapter: r2({ bucket }) })`, and call `upload`, `download`, `list`, `url`, and the rest. Plugins such as `files-sdk/encryption` and `files-sdk/validation` wrap the same API. `files-sdk/api` with a framework binding (`files-sdk/next`, `files-sdk/hono`, …) serves browser uploads behind an `authorize` hook, and the `files` CLI and its MCP server expose the same operations to scripts and agents. The `files-sdk` agent skill below covers setup and usage, and the guides under /guides walk through complete workflows end to end: browser uploads, private downloads, AI attachments and storage tools, provider setup, and migrations.

## Changelog

- [files-sdk@3.1.1](https://files-sdk.dev/changelog/files-sdk-3-1-1): Interrupting a buffered DownloadedFile read in files-sdk/effect (text, arrayBuffer, or blob) now cancels the body read underneath, instead of leaving it…
- [files-sdk@3.1.0](https://files-sdk.dev/changelog/files-sdk-3-1-0): Add an Effect v4 bridge (files-sdk/effect). Files is a Context.Service provided by Files.layer(), from a Files instance or the options to build one. Its…
- [files-sdk@3.0.0](https://files-sdk.dev/changelog/files-sdk-3-0-0): files-sdk/cache no longer shares entries between instances. Store keys now include the instance prefix, and a custom store requires a namespace naming the…
- [files-sdk@2.6.2](https://files-sdk.dev/changelog/files-sdk-2-6-2): files-sdk/client download() now reports a failure at the storage host, after the gateway redirected to a signed URL, with the code its HTTP status implies…
- [files-sdk@2.6.1](https://files-sdk.dev/changelog/files-sdk-2-6-1): The downloadFile tool in files-sdk/ai-sdk, files-sdk/openai, and files-sdk/claude now enforces maxBytes on the bytes it actually reads. It used to check only…
- [files-sdk@2.6.0](https://files-sdk.dev/changelog/files-sdk-2-6-0): Add a RustFS adapter (files-sdk/rustfs). RustFS is the Apache-2.0 Rust object store that runs as a MinIO drop-in, and rustfs() mirrors the minio() adapter…
- [files-sdk@2.5.0](https://files-sdk.dev/changelog/files-sdk-2-5-0): Support Vercel Blob Signed URLs in the vercelBlob() adapter. In access: "private" mode, url() now mints a presigned GET scoped to the key that honors…
- [files-sdk@2.4.1](https://files-sdk.dev/changelog/files-sdk-2-4-1): softDelete() and versioning() can now be composed on one instance. Both plugins contributed a restore extension, so createFiles({ plugins: [softDelete()…
- [files-sdk@2.4.0](https://files-sdk.dev/changelog/files-sdk-2-4-0): minio: add the client: "fetch" engine (#155). minio({ client: "fetch" }) runs on the same SigV4-signed aws4fetch core as r2({ client: "fetch" }) and s3Fetch()…
- [files-sdk@2.3.1](https://files-sdk.dev/changelog/files-sdk-2-3-1): Fix the files-sdk/api proxy download returning a 500 for a suffix Range request (bytes=-N) against an empty object. The header resolved to an inverted byte…
- [files-sdk@2.3.0](https://files-sdk.dev/changelog/files-sdk-2-3-0): Add provider-native conditional create, replace, exact-read, delete, and copy operations to the existing plugin, hook, retry, prefix, read-only, and receipt…
- [files-sdk@2.2.5](https://files-sdk.dev/changelog/files-sdk-2-2-5): Content-type inference from file names (Dropbox, FTP, SFTP, WebDAV, Box, unzip, CLI directory uploads) now uses the mime package's full table instead of a…
- [files-sdk@2.2.4](https://files-sdk.dev/changelog/files-sdk-2-2-4): Request httpMetadata and customMetadata when listing through the R2 Workers binding, so list() reports the stored content type and metadata instead of…
- [files-sdk@2.2.3](https://files-sdk.dev/changelog/files-sdk-2-2-3): Preserve the caller's query string on gateway-minted proxy upload targets, so a per-request files factory selected via the endpoint query (e.g. useFiles({…
- [files-sdk@2.2.2](https://files-sdk.dev/changelog/files-sdk-2-2-2): Avoid loading Firebase Admin when the Firebase Storage adapter receives an initialized bucket.Refresh environment-provided Vercel Blob credentials for every…
- [files-sdk@2.2.1](https://files-sdk.dev/changelog/files-sdk-2-2-1): Expose the lazy provider-aware loadFiles runtime loader through files-sdk/loader.Keep @aws-sdk/* out of the static module graph reachable from files-sdk/r2 so…
- [files-sdk@2.2.0](https://files-sdk.dev/changelog/files-sdk-2-2-0): Add first-class NestJS support (#95). New files-sdk/nestjs subpath exports a dynamic FilesModule (forRoot() / forRootAsync()) that configures the gateway…
- [files-sdk@2.1.0](https://files-sdk.dev/changelog/files-sdk-2-1-0): Add files-sdk/tanstack-start server adapter — createRouteHandler mounts the Files gateway in a TanStack Start server route (server.handlers).Add a WebDAV…
- [files-sdk@2.0.0](https://files-sdk.dev/changelog/files-sdk-2-0-0): Release files-sdk 2.0 — the full-stack release. Alongside the core Files API, the SDK now reaches the browser with framework client bindings (files-sdk/react…
- [files-sdk@1.9.0](https://files-sdk.dev/changelog/files-sdk-1-9-0): Add an audit() plugin at files-sdk/audit that writes a structured who/what/when record of every mutation to an awaited sink — the durable, awaitable…
- [files-sdk@1.8.0](https://files-sdk.dev/changelog/files-sdk-1-8-0): Add a compression() plugin at files-sdk/compression for transparent, at-rest compression. Bodies are gzipped (or deflate / deflate-raw) on upload with the…
- [files-sdk@1.7.0](https://files-sdk.dev/changelog/files-sdk-1-7-0): Add sync() — an incremental, optionally-pruning mirror between two providers. It skips objects already identical at the destination (compare by size + etag…
- [files-sdk@1.6.0](https://files-sdk.dev/changelog/files-sdk-1-6-0): Bring the CLI (and MCP server) to full parity with the SDK surface.Every Files capability is now reachable from the files binary:Global --key-prefix scopes…
- [files-sdk@1.5.0](https://files-sdk.dev/changelog/files-sdk-1-5-0): upload, download, head, and exists now accept an array for bulk operations, mirroring delete. Pass the usual single argument for the original behavior…
- [files-sdk@1.4.0](https://files-sdk.dev/changelog/files-sdk-1-4-0): Add Alibaba Cloud Object Storage Service (OSS) adapter (files-sdk/alibaba). Thin wrapper around the S3 adapter — endpoint derived from the region code…
- [files-sdk@1.3.0](https://files-sdk.dev/changelog/files-sdk-1-3-0): Add Appwrite adapter at files-sdk/appwrite exporting appwrite(), a wrapper around the official node-appwrite SDK's Storage API. Auto-loads endpoint…
- [files-sdk@1.2.0](https://files-sdk.dev/changelog/files-sdk-1-2-0): Add AI SDK tools subpath (files-sdk/ai-sdk) exporting createFileTools(...) — wraps a configured Files instance as a set of Vercel AI SDK tools (listFiles…
- [files-sdk@1.1.2](https://files-sdk.dev/changelog/files-sdk-1-1-2): googleDrive and onedrive adapters now auto-load credentials from process.env when not passed explicitly, matching the convention already in place for the…
- [files-sdk@1.1.1](https://files-sdk.dev/changelog/files-sdk-1-1-1): Fix release workflow referencing a non-existent VERCEL_PROJECT_ID_WEB secret; now reads VERCEL_PROJECT_ID to match the configured repository secret so the…
- [files-sdk@1.1.0](https://files-sdk.dev/changelog/files-sdk-1-1-0): Add Akamai Cloud Object Storage adapter (files-sdk/akamai), formerly Linode Object Storage. Thin wrapper over the S3 adapter with Akamai defaults: endpoint…
- [files-sdk@1.0.0](https://files-sdk.dev/changelog/files-sdk-1-0-0): Initial release

## Docs

- [Introduction](https://files-sdk.dev/docs): Files SDK is a unified storage API with 48 adapters - one class, eleven methods, a typed escape hatch, and an agent-friendly CLI.
- [FAQ](https://files-sdk.dev/docs/faq): Common questions about supported providers, bundling and peer dependencies, switching backends, browser uploads, error handling, and the CLI.
- [Installation](https://files-sdk.dev/docs/installation): Install files-sdk and the optional peer dependencies for the adapter you're using - anything you don't import is never bundled. ESM only, Node 22+ and Bun.
- [Migrating to v3](https://files-sdk.dev/docs/migrating-to-v3): What changed in files-sdk 3.0 - body-less head and list results, two new error codes, one bulk result shape, expiring URLs that never silently stay permanent, a capabilities object for adapters, and Node 22.
- [Providers](https://files-sdk.dev/docs/providers): A zero-dependency catalog of every provider the SDK ships and the env vars each one reads - for building config UIs, sync engines, and onboarding flows.
- [Troubleshooting](https://files-sdk.dev/docs/troubleshooting): Common errors, the normalized FilesError code model, adapter-specific gotchas, and debugging tips for resolving issues across every Files SDK backend.
- [Usage](https://files-sdk.dev/docs/usage): Construct a Files instance with an adapter, then call the same eleven methods on it - swap the adapter to switch backends.

### Adapters

- [Adapters](https://files-sdk.dev/docs/adapters): Compare the 48 storage backends Files SDK supports, from Cloudflare R2 and S3 to Vercel Blob and the local filesystem, by what each one can do.

#### System Adapters

- [Filesystem](https://files-sdk.dev/docs/adapters/fs): Local filesystem - the dev/test adapter. Uses node:fs/promises with a sidecar .meta.json per file. Not for production.
- [FTP](https://files-sdk.dev/docs/adapters/ftp): FTP / FTPS via basic-ftp. Node-only. Connect-per-operation with an injectable client for batch work; url() needs an HTTP front.
- [In-Memory](https://files-sdk.dev/docs/adapters/memory): In-memory store backed by a Map - the test/reference adapter. Zero dependencies, isomorphic, and non-persistent. Ideal for unit tests; not for production.
- [SFTP](https://files-sdk.dev/docs/adapters/sftp): SFTP (SSH File Transfer Protocol) via ssh2-sftp-client. Node-only. Connect-per-operation with an injectable client for batch work; url() needs an HTTP front.
- [WebDAV](https://files-sdk.dev/docs/adapters/webdav): WebDAV (Nextcloud, ownCloud, Apache mod_dav, …) via the webdav client. HTTP-based, with native server-side copy/move; url() needs an HTTP front.

#### Vendor Adapters

- [Akamai Cloud Object Storage](https://files-sdk.dev/docs/adapters/akamai): Akamai Cloud Object Storage (formerly Linode) via the S3-compatible API. Endpoint derived from the region/cluster code.
- [Alibaba Cloud OSS](https://files-sdk.dev/docs/adapters/alibaba): Alibaba Cloud Object Storage Service (OSS) via the S3-compatible API. Endpoint derived from the region code (cn-hangzhou, ap-southeast-1, ...).
- [Amazon S3](https://files-sdk.dev/docs/adapters/s3): AWS S3 (and any S3-compatible bucket). Uses the standard AWS credential chain - environment, IAM role, shared profile.
- [Appwrite](https://files-sdk.dev/docs/adapters/appwrite): Appwrite Storage via the official node-appwrite SDK. Auto-loads APPWRITE_ENDPOINT, APPWRITE_PROJECT_ID, and APPWRITE_API_KEY, or pass an existing client.
- [Archil](https://files-sdk.dev/docs/adapters/archil): Archil disks via the S3-compatible API. The disk id is the bucket and the endpoint is derived from the Archil region. Supports branch-scoped access.
- [Azure Blob Storage](https://files-sdk.dev/docs/adapters/azure): Azure Blob Storage via @azure/storage-blob. Five credential modes - connection string, account key, token credential, SAS token, or anonymous.
- [Backblaze B2](https://files-sdk.dev/docs/adapters/backblaze-b2): Backblaze B2 via the S3-compatible API. Endpoint derived from the cluster code (us-west-002, us-east-005, eu-central-003, ...).
- [Box](https://files-sdk.dev/docs/adapters/box): Box via the official typed SDK. Translates virtual keys into nested folders under a configurable rootFolderId.
- [Bun S3](https://files-sdk.dev/docs/adapters/bun-s3): Upload, download, list, and presign files with Bun's native Bun.S3Client on AWS S3, Cloudflare R2, MinIO, or any S3-compatible bucket, with no AWS SDK.
- [Bunny Storage](https://files-sdk.dev/docs/adapters/bunny-storage): Bunny Storage via @bunny.net/storage-sdk. Connects to a Storage Zone with its zone password / access key, auto-loading the BUNNY_STORAGE_* env vars.
- [Cloudflare R2](https://files-sdk.dev/docs/adapters/r2): Cloudflare R2 over the S3-compatible HTTP API. Auto-loads R2_* env vars or accepts an R2Bucket binding inside Workers.
- [Cloudinary](https://files-sdk.dev/docs/adapters/cloudinary): Cloudinary asset CDN via the official Node SDK. Defaults to resource_type: raw for arbitrary-bytes storage; switch to image/video for transforms.
- [Convex](https://files-sdk.dev/docs/adapters/convex): Convex file storage via the function context (ctx.storage). Runs inside Convex actions/mutations/queries; the Convex-assigned storage id is the key.
- [DigitalOcean Spaces](https://files-sdk.dev/docs/adapters/digitalocean-spaces): DigitalOcean Spaces via the S3-compatible API. Endpoint derived from the region, virtual-hosted addressing, keys auto-loaded from DO_SPACES_KEY/SECRET.
- [Dropbox](https://files-sdk.dev/docs/adapters/dropbox): Dropbox via the official SDK. Path-addressable, so virtual keys map directly to Dropbox paths - no cache, with OAuth refresh-token and access-token auth.
- [Exoscale Object Storage](https://files-sdk.dev/docs/adapters/exoscale): Exoscale Object Storage (SOS) via the S3-compatible API. Endpoint derived from the zone code (ch-gva-2, de-fra-1, ...).
- [Filebase](https://files-sdk.dev/docs/adapters/filebase): Filebase via the S3-compatible API. Fronts decentralized storage networks (IPFS, Sia, Storj) chosen per-bucket in the dashboard, not per-request.
- [Firebase Storage](https://files-sdk.dev/docs/adapters/firebase-storage): Firebase Cloud Storage via the official firebase-admin SDK. Underlying client is @google-cloud/storage, so V4 signed URLs and POST policy uploads come for free.
- [Google Cloud Storage](https://files-sdk.dev/docs/adapters/gcs): Google Cloud Storage via the official @google-cloud/storage SDK. Application Default Credentials by default, resumable uploads when onProgress is passed.
- [Google Drive](https://files-sdk.dev/docs/adapters/google-drive): Google Drive via the official Drive v3 client. Maps unified string keys onto Drive's appProperties with a per-instance LRU cache.
- [Hetzner Object Storage](https://files-sdk.dev/docs/adapters/hetzner): Use Hetzner Object Storage from Node.js - endpoint from the fsn1, nbg1, or hel1 location, HCLOUD_* keys, uploads, listing, and presigned URLs.
- [IBM Cloud Object Storage](https://files-sdk.dev/docs/adapters/ibm-cos): IBM Cloud Object Storage via the S3-compatible API. Endpoint derived from the region code, auth uses IBM Cloud HMAC credentials, not IAM API keys.
- [iDrive e2](https://files-sdk.dev/docs/adapters/idrive-e2): iDrive e2 via the S3-compatible API. Endpoint required (iDrive hostnames are tied to the cluster your bucket lives in).
- [MinIO](https://files-sdk.dev/docs/adapters/minio): MinIO and other self-hosted S3-compatible servers. Path-style addressing on by default; region defaulted; errors relabelled; optional @aws-sdk-free fetch client for Workers.
- [Neon](https://files-sdk.dev/docs/adapters/neon): Neon branchable object storage via the S3-compatible API. neon dev / neon env pull inject the AWS_* env vars; path-style addressing is required.
- [Netlify Blobs](https://files-sdk.dev/docs/adapters/netlify-blobs): Netlify Blobs via @netlify/blobs. Auto-detects siteID and token on Netlify runtimes; falls back to env vars elsewhere.
- [OneDrive](https://files-sdk.dev/docs/adapters/onedrive): OneDrive and SharePoint document libraries via Microsoft Graph. Path-addressable with no virtual-key bookkeeping, chunked upload sessions past 250 MB.
- [Oracle Cloud Object Storage](https://files-sdk.dev/docs/adapters/oracle-cloud): Oracle Cloud Infrastructure Object Storage via the S3 compatibility layer. Auth uses HMAC Customer Secret Keys, not regular API keys.
- [OVHcloud Object Storage](https://files-sdk.dev/docs/adapters/ovhcloud): OVHcloud Object Storage via the S3-compatible API. Endpoint derived from the region code.
- [PocketBase](https://files-sdk.dev/docs/adapters/pocketbase): PocketBase via the official JS SDK. Maps the unified key/blob API onto a dedicated collection with a unique key field and a single-file body field.
- [RustFS](https://files-sdk.dev/docs/adapters/rustfs): RustFS, the Apache-2.0 Rust object store that runs as a MinIO drop-in. Path-style addressing on by default; region defaulted; errors relabelled; optional @aws-sdk-free fetch client for Workers.
- [S3 (fetch)](https://files-sdk.dev/docs/adapters/s3-fetch): AWS S3 and any S3-compatible bucket over a SigV4-signed fetch engine - no @aws-sdk/* packages, built for Cloudflare Workers and other edge runtimes.
- [Scaleway Object Storage](https://files-sdk.dev/docs/adapters/scaleway): Scaleway Object Storage via the S3-compatible API. Endpoint derived from the region code (fr-par, nl-ams, pl-waw).
- [SharePoint](https://files-sdk.dev/docs/adapters/sharepoint): SharePoint document libraries via Microsoft Graph. Resolves siteUrl and library names; delegates to the OneDrive adapter for the file operations.
- [Storj](https://files-sdk.dev/docs/adapters/storj): Storj DCS via the S3-compatible Gateway. Defaults to the hosted Gateway MT with path-style addressing, keys auto-loaded from STORJ_* env vars.
- [Supabase Storage](https://files-sdk.dev/docs/adapters/supabase): Supabase Storage via @supabase/storage-js. Pass an existing SupabaseClient to share auth/postgrest with the rest of your app.
- [Tencent Cloud Object Storage](https://files-sdk.dev/docs/adapters/tencent): Tencent Cloud Object Storage (COS) via the S3-compatible API. Endpoint derived from the region code; bucket name must include the -<appid> suffix.
- [Tigris](https://files-sdk.dev/docs/adapters/tigris): Tigris globally-distributed object storage via the S3-compatible API. Fixed global endpoint, region defaults to auto.
- [UploadThing](https://files-sdk.dev/docs/adapters/uploadthing): UploadThing via the uploadthing/server SDK. Auto-loads UPLOADTHING_TOKEN and maps your keys onto UploadThing's customId so operations route by your key.
- [Vercel Blob](https://files-sdk.dev/docs/adapters/vercel-blob): Store files in Vercel Blob with files-sdk, using OIDC on Vercel (BLOB_STORE_ID, no secret) or a BLOB_READ_WRITE_TOKEN anywhere, public or private.
- [Vultr Object Storage](https://files-sdk.dev/docs/adapters/vultr): Vultr Object Storage via the S3-compatible API. Endpoint derived from the cluster code (ewr1, sjc1, ams1, blr1, ...).
- [Wasabi](https://files-sdk.dev/docs/adapters/wasabi): Wasabi Hot Cloud Storage via its S3-compatible API - a thin wrapper around the S3 adapter with AWS-style region names mapped to Wasabi's own endpoints.
- [Yandex Object Storage](https://files-sdk.dev/docs/adapters/yandex): Yandex Object Storage via the S3-compatible API. Fixed global endpoint, region defaults to ru-central1, keys auto-loaded from YANDEX_* env vars.

### AI

- [Claude Agent SDK](https://files-sdk.dev/docs/ai/claude): Expose a configured Files instance to the Claude Agent SDK as an in-process MCP server with allowedTools and canUseTool wired up.
- [OpenAI](https://files-sdk.dev/docs/ai/openai): Factories for the OpenAI Responses API and the OpenAI Agents SDK - same eight operations, Zod-validated, approval-gated by default.
- [Vercel AI SDK](https://files-sdk.dev/docs/ai/vercel): Give Vercel AI SDK agents tools to list, read, upload, and share files in S3, R2, or any bucket, with generateText, streamText, or ToolLoopAgent.

### API

- [API reference](https://files-sdk.dev/docs/api): The full Files SDK API - eleven unified methods plus abortUpload and a key-bound handle, the shared per-operation options, and the FileInfo and StoredFile result types.
- [Errors](https://files-sdk.dev/docs/api/errors): Every method throws a single FilesError with a normalized code, the original provider error on cause, and an aborted flag for timeouts and cancellations.
- [FileInfo and StoredFile](https://files-sdk.dev/docs/api/stored-file): FileInfo is an object's metadata, returned by head, list, search, and upload. StoredFile is a download - the same metadata plus File's name/type and the body accessors.

#### Global Methods

- [sync](https://files-sdk.dev/docs/api/sync): Mirror one Files instance onto another - skip unchanged keys, prune extraneous ones, and dry-run the plan first. The incremental sibling of transfer.
- [transfer](https://files-sdk.dev/docs/api/transfer): Stream every object under a prefix from one Files instance to another - the cross-provider migration built entirely on listAll, download, and upload.

#### Hooks

- [onAction](https://files-sdk.dev/docs/api/onaction): Runs once when a public call settles, on success and on failure - the constructor hook for audit logs, activity feeds, and per-action metrics.
- [onError](https://files-sdk.dev/docs/api/onerror): Runs only when a public call rejects - the constructor hook to wire to Sentry or Datadog when you want only true call failures.
- [onProgress](https://files-sdk.dev/docs/api/onprogress): A per-call upload callback, modeled on the constructor hooks - called as bytes go out so you can drive a progress bar.
- [onRetry](https://files-sdk.dev/docs/api/onretry): Runs each time the SDK schedules a retry for a single-operation call, with the upcoming attempt, its delay, and the triggering error.

#### Instance Methods

- [copy](https://files-sdk.dev/docs/api/copy): Copy an object from one key to another - server-side where the provider supports it, with a streaming read + write fallback otherwise.
- [delete](https://files-sdk.dev/docs/api/delete): Remove an object - a single key resolving to void, or an array returning a structured result that never throws on partial failure.
- [download](https://files-sdk.dev/docs/api/download): Read an object - a buffered StoredFile by default, or a streamed one for large objects - one key or many.
- [exists](https://files-sdk.dev/docs/api/exists): Check whether an object exists without fetching its body - one key returns a boolean, an array splits into existing and missing.
- [file](https://files-sdk.dev/docs/api/file): A FileHandle bound to one key - upload, download, head, exists, delete, url, signedUploadUrl, copyTo, copyFrom, moveTo, and moveFrom without re-passing the key.
- [head](https://files-sdk.dev/docs/api/head): Fetch an object's metadata without its body - one key or many. Returns FileInfo; call download for the bytes.
- [list](https://files-sdk.dev/docs/api/list): Cursor-paginated listing with a prefix filter; each item is a FileInfo. listAll walks every page; a delimiter returns folders.
- [move](https://files-sdk.dev/docs/api/move): Rename a key - a native, atomic rename where the provider has one, with a copy + delete fallback everywhere else.
- [search](https://files-sdk.dev/docs/api/search): Find objects whose key matches a glob (default), regex, substring, or exact pattern - a streaming async iterable that walks every page like listAll.
- [signedUploadUrl](https://files-sdk.dev/docs/api/signed-upload-url): A presigned PUT-or-POST contract so a browser can upload straight to the bucket - bandwidth and CPU stay off your server.
- [upload](https://files-sdk.dev/docs/api/upload): Write a body to a key - a single object or many in one call, with optional progress tracking and multipart uploads.
- [url](https://files-sdk.dev/docs/api/url): Return a URL to fetch a key - a signed GetObject where the adapter can sign, or a direct CDN/public URL where one is configured.

### CLI

- [CLI overview](https://files-sdk.dev/docs/cli): Agent-friendly CLI for files-sdk. One binary, every provider, JSON-by-default output, stdin/stdout streaming, and a built-in MCP server.
- [Commands](https://files-sdk.dev/docs/cli/commands): Each CLI command maps to an SDK method - upload, download, head, exists, delete, copy, move, list, search, url, sign-upload, transfer, sync, and capabilities.
- [JSON output](https://files-sdk.dev/docs/cli/output): JSON-by-default output on stdout, a stable error envelope on stderr, and meaningful exit codes for scripting - pipe straight to jq.
- [Streaming & dry-run](https://files-sdk.dev/docs/cli/streaming): Stream bodies through stdin/stdout with no temp files, and use --dry-run to preview an operation before it runs.
- [MCP server](https://files-sdk.dev/docs/cli/mcp): Boot a built-in read-only MCP server on stdio, with provider and credentials bound at startup so the agent passes only operation arguments, never secrets.
- [Wiring agents](https://files-sdk.dev/docs/cli/agents): Three patterns for handing storage access to an agent - CLI exploration, programmatic JSON loops, and env-based provider selection - plus when to reach for the MCP server.

### Concepts

- [Bulk actions](https://files-sdk.dev/docs/bulk): Pass an array instead of a key to act on many objects at once - a bounded fan-out that keeps successes and failures separate, never failing the whole batch.
- [Cancellation](https://files-sdk.dev/docs/cancellations): An AbortSignal always fails the call fast at the Files layer; whether the underlying provider request is also cancelled depends on the adapter.
- [Capabilities](https://files-sdk.dev/docs/capabilities): Query what an adapter can do up front with files.capabilities - including range reads, signed URLs, server-side copy, and native conditional operations.
- [Conditional operations](https://files-sdk.dev/docs/conditional-operations): Use provider-native create, replace, exact-read, delete, and copy predicates without bypassing plugins, hooks, receipts, or client policy.
- [Escape hatch](https://files-sdk.dev/docs/escape-hatch): Drop down to the native, per-adapter client for any feature outside the unified surface — versioning, lifecycle rules, ACLs, object tags, and more.
- [Multipart uploads](https://files-sdk.dev/docs/multipart): Upload a large body in parallel parts instead of one request - the robust path past the single-request size limit and for streams of unknown length.
- [Prefixes](https://files-sdk.dev/docs/prefixes): Pass a prefix to the constructor and every key resolves relative to it - prepended going in, stripped coming out - so your code stays in its own namespace.
- [Provider gaps](https://files-sdk.dev/docs/provider-gaps): A register of per-adapter quirks that don't fit the capability matrix - signed-URL caps, ignored expiries, copy costs, Content-Disposition support.
- [Read-only](https://files-sdk.dev/docs/readonly): Lock a Files instance to reads only with the readonly option or files.readonly(), so every write surface fails consistently with a ReadOnly FilesError.
- [Receipts](https://files-sdk.dev/docs/receipts): Opt into a provenance Receipt for every mutating call - op, provider, key, bytes, etag, timing, optional SHA-256 - delivered on the onAction hook.
- [Resumable uploads](https://files-sdk.dev/docs/resumable): Pause, resume, and abort a large upload via a control handle, or resume it in a later process from a serializable session token. A per-call option on upload.
- [Retries](https://files-sdk.dev/docs/retries): Automatic retries for transient provider failures, with a configurable backoff curve and clear rules for what is and isn't retried.
- [Timeouts](https://files-sdk.dev/docs/timeouts): A per-attempt timeout that aborts the call when it fires — it ends the operation rather than triggering another attempt.

### Events

- [Events overview](https://files-sdk.dev/docs/events): React when a file is created or deleted, however it got there. files-sdk/events turns each provider's bucket notifications into one event shape and routes them to your handlers.
- [Delivery and idempotency](https://files-sdk.dev/docs/events/delivery): Providers deliver at least once (Supabase at most once) and out of order. Write handlers that can run twice, keyed on event.id.
- [Webhooks](https://files-sdk.dev/docs/events/webhooks): files.events.webhook() is an HTTP endpoint for providers that push. It answers their handshakes, authenticates every delivery, and tells the provider when to retry.
- [Testing locally](https://files-sdk.dev/docs/events/testing): The memory adapter emits storage events natively, so you can run event handlers in tests and local development without a provider.

#### Providers

- [Amazon S3](https://files-sdk.dev/docs/events/s3): Send S3 bucket notifications to SQS, Lambda, SNS or EventBridge, and hand them to files.events.dispatch() or a webhook.
- [MinIO](https://files-sdk.dev/docs/events/minio): Point MinIO's webhook notification target at files.events.webhook(), authenticated with its auth_token.
- [Cloudflare R2](https://files-sdk.dev/docs/events/r2): Send R2 event notifications to a Queue and dispatch them from a Worker consumer.
- [Google Cloud Storage](https://files-sdk.dev/docs/events/gcs): Publish GCS notifications to Pub/Sub, then pull them, or push them to files.events.webhook() with Google-signed OIDC tokens.
- [Azure Blob Storage](https://files-sdk.dev/docs/events/azure): Subscribe files.events.webhook() to a storage account's Event Grid events, in either schema.
- [Backblaze B2](https://files-sdk.dev/docs/events/b2): Receive B2 Event Notifications at files.events.webhook(), verified with the rule's HMAC-SHA256 signing secret.
- [Tigris](https://files-sdk.dev/docs/events/tigris): Receive Tigris object notifications at files.events.webhook(), authenticated by the header you configure.
- [Supabase](https://files-sdk.dev/docs/events/supabase): Use a Database Webhook on storage.objects to deliver Supabase Storage changes to files.events.webhook().
- [Cloudinary](https://files-sdk.dev/docs/events/cloudinary): Receive Cloudinary upload, delete and rename notifications at files.events.webhook(), verified with your API secret.
- [Appwrite](https://files-sdk.dev/docs/events/appwrite): Receive Appwrite storage file webhooks at files.events.webhook(), verified with the webhook's signature key.
- [Box](https://files-sdk.dev/docs/events/box): Receive Box webhooks (v2) at files.events.webhook(), verified with the app's primary and secondary signature keys.

### Integrations

- [Effect](https://files-sdk.dev/docs/integrations/effect): Use Files SDK from Effect v4 - a Files service and Layer, typed FilesError reasons, fiber interruption that cancels the provider call, and Streams for listings, downloads, and storage events.

### Plugins

- [Plugins overview](https://files-sdk.dev/docs/plugins): Wrap every operation on a Files instance in an ordered pipeline - transform, veto, or observe - and contribute new namespaced methods.
- [API](https://files-sdk.dev/docs/plugins/api): The plugin contract types and helpers - FilesPlugin, FilesOperation, handlers, and createFiles. See the overview for how they compose.
- [audit](https://files-sdk.dev/docs/plugins/audit): Write a structured who/what/when record of every mutation to an awaited sink - the durable, awaitable counterpart to the fire-and-forget onAction hook.
- [cache](https://files-sdk.dev/docs/plugins/cache): An LRU or KV cache in front of head(), url(), and small download()s - repeat reads of an unchanged key are served from memory, writes invalidate the key.
- [compression](https://files-sdk.dev/docs/plugins/compression): Transparently compress object bodies at rest with gzip, deflate, or deflate-raw - reads decompress automatically, no native dependencies.
- [content-type](https://files-sdk.dev/docs/plugins/content-type): Decide each upload's Content-Type from its bytes, not the client's claim - magic-byte sniffing stops mislabeled HTML or SVG being stored as an image.
- [dedup](https://files-sdk.dev/docs/plugins/dedup): Content-address object bodies by SHA-256 hash so identical content is stored only once - re-uploads skip the byte upload and copies share one blob.
- [encryption](https://files-sdk.dev/docs/plugins/encryption): Envelope-encrypt object bodies at rest with AES-256-GCM - your master key wraps a per-object data key into metadata, decrypted transparently on download.
- [events](https://files-sdk.dev/docs/plugins/events): Normalize provider bucket notifications (S3, MinIO, R2, GCS, Azure, B2, Tigris, Supabase, Cloudinary, Appwrite, Box, Storj) into one FileEvent and route them to handlers by type and key glob.
- [failover](https://files-sdk.dev/docs/plugins/failover): Read and write the primary adapter and fall back to one or more secondary adapters when a backend is down - a live, per-operation failover chain.
- [signed-url-policy](https://files-sdk.dev/docs/plugins/signed-url-policy): A fail-safe guard that enforces safe defaults on url() and signedUploadUrl() - force a download disposition, cap expiry, and cap the signed upload size.
- [soft-delete](https://files-sdk.dev/docs/plugins/soft-delete): Turn delete into a recoverable move into a hidden trash prefix, with trashed(), restoreTrashed(), and purge() - body-transparent, works on any adapter.
- [tiering](https://files-sdk.dev/docs/plugins/tiering): Route operations between a hot and a cold adapter by size, prefix, or age - reads transparently find objects and tier() moves them between stores.
- [tracing](https://files-sdk.dev/docs/plugins/tracing): Open an OpenTelemetry span named files.<verb> around every operation, with key, size, and outcome attributes - optional @opentelemetry/api peer dependency.
- [usage](https://files-sdk.dev/docs/plugins/usage): Meter operation counts and bytes up/down across a Files instance, with lazy stream-level download counting - read totals back with files.usage().
- [validation](https://files-sdk.dev/docs/plugins/validation): A fail-closed guard that vets every upload before any bytes move - enforce a max/min size, an allowed-MIME-type list, and a key-naming rule.
- [versioning](https://files-sdk.dev/docs/plugins/versioning): Snapshot an object's prior bytes before every overwrite or delete and roll a key back with versions() and restoreVersion() - server-side, body-transparent.
- [zip](https://files-sdk.dev/docs/plugins/zip): Stream many stored objects as one ZIP archive, store archives back as objects, and extract archives into individual keys - no native dependencies.

### UI

- [UI overview](https://files-sdk.dev/docs/ui): The whole Files API in the browser, over one endpoint — a React hook, a Vue composable, or Svelte stores, backed by a server gateway you mount in minutes.

#### Client

- [React](https://files-sdk.dev/docs/ui/client/react): One hook, every Files verb. Imperative methods with upload progress and ambient error state, plus optional reactive useList / useFile / useSearch.
- [React Native](https://files-sdk.dev/docs/ui/client/react-native): The same useFiles hook in React Native / Expo — absolute endpoint, picker-descriptor uploads with real progress, buffered downloads.
- [Svelte](https://files-sdk.dev/docs/ui/client/svelte): The full Files API in the browser, idiomatic Svelte - useFiles returns the verbs plus Svelte stores for ambient state, with useList / useFile / useSearch.
- [Vue](https://files-sdk.dev/docs/ui/client/vue): The full Files API in the browser as a Vue 3 composable - useFiles returns the verbs plus refs for ambient state, with reactive useList / useFile / useSearch.

#### Components

- [Capabilities Badges](https://files-sdk.dev/docs/ui/components/capabilities-badges): Renders each adapter capability from capabilities() as a supported or unsupported badge - driven by useFiles, with a supportedOnly filter.
- [Dropzone](https://files-sdk.dev/docs/ui/components/dropzone): A drag-and-drop (or click) upload area wired to useFiles - uploads through your gateway, with composable success, prompt and error states.
- [File Actions](https://files-sdk.dev/docs/ui/components/file-actions): A per-file actions menu - download, copy, rename, move and delete - driven by useFiles, with destination prompts and delete confirmation.
- [File Browser](https://files-sdk.dev/docs/ui/components/file-browser): A folder-aware browser that descends into common prefixes via list({ delimiter }), with a breadcrumb trail and cursor-based load more - driven by useFiles.
- [File List](https://files-sdk.dev/docs/ui/components/file-list): A list of stored files with thumbnails, size and type, plus download and delete — driven by useFiles.
- [File Preview](https://files-sdk.dev/docs/ui/components/file-preview): A lazy preview of a single stored file — image, PDF or text — with metadata, resolving bytes only when it mounts.
- [File Search](https://files-sdk.dev/docs/ui/components/file-search): A search box that lists matching keys with substring, glob, regex and exact match modes plus a case-sensitivity toggle - driven by useFiles.
- [Multipart Uploader](https://files-sdk.dev/docs/ui/components/multipart-uploader): A multi-file queue uploader with bounded concurrency, live per-file progress and cancel — with a prefix, large files stream through your gateway into a multipart upload on S3-family storage.
- [Share Dialog](https://files-sdk.dev/docs/ui/components/share-dialog): A dialog that mints a shareable download or upload link with expiry presets clamped to the adapter's signed URL cap - driven by useFiles.
- [Trash Bin](https://files-sdk.dev/docs/ui/components/trash-bin): A recycle bin that lists, restores and permanently purges soft-deleted files — driven by useFiles and the softDelete plugin.
- [Upload Progress](https://files-sdk.dev/docs/ui/components/upload-progress): Per-file and aggregate progress bars for in-flight uploads, reading the ambient uploads and progress state a useFiles instance exposes.
- [Version History](https://files-sdk.dev/docs/ui/components/version-history): A version timeline for one key with one-click restore - driven by useFiles and the versioning plugin; restore snapshots the current bytes first.

#### Server

- [Astro](https://files-sdk.dev/docs/ui/server/astro): Mount the Files gateway in an Astro endpoint. createRouteHandler returns { GET, POST, PUT } over the Web Request - runs on Node and edge adapters.
- [Authorization](https://files-sdk.dev/docs/ui/server/authorization): The gateway is deny-by-default. One authorize hook decides who can do what, and scopes every key - the single most important thing to get right.
- [Bun](https://files-sdk.dev/docs/ui/server/bun): Serve the Files gateway from Bun.serve. The gateway's handle(req) is already a Web fetch handler, so it drops straight into a route - no adapter needed.
- [Deno](https://files-sdk.dev/docs/ui/server/deno): Serve the Files gateway from Deno.serve. The gateway is a Web fetch handler, so it drops in with no adapter - import the SDK with the npm specifier.
- [Elysia](https://files-sdk.dev/docs/ui/server/elysia): Mount the Files gateway in an Elysia app. Web-native on Bun - forward the raw Request with parse:'none' so the gateway reads the body itself.
- [Express](https://files-sdk.dev/docs/ui/server/express): Mount the Files gateway on a Node server. Bridges IncomingMessage/ServerResponse to Web Request/Response - also serves Connect and a raw http server.
- [Fastify](https://files-sdk.dev/docs/ui/server/fastify): Mount the Files gateway on a Fastify server. Hijacks the reply and bridges IncomingMessage/ServerResponse to the Web Request/Response the gateway speaks.
- [Gateway](https://files-sdk.dev/docs/ui/server/gateway): createFilesRouter exposes the whole Files API over one HTTP endpoint. Mount it in Next (or any Web-Request runtime) and the browser bindings talk to it.
- [Hono](https://files-sdk.dev/docs/ui/server/hono): Mount the Files gateway in a Hono app. Web-native, so it runs anywhere Hono does - Cloudflare Workers, Bun, Deno, and Node.
- [Koa](https://files-sdk.dev/docs/ui/server/koa): Mount the Files gateway on a Koa app. Sets ctx.respond = false and bridges ctx.req/ctx.res to the Web Request/Response the gateway speaks.
- [Multiple buckets](https://files-sdk.dev/docs/ui/server/multiple-buckets): Serve more than one bucket — a public images bucket and a private files bucket, say — through the gateway and the UI components.
- [NestJS](https://files-sdk.dev/docs/ui/server/nestjs): First-class NestJS integration - a dynamic FilesModule that mounts the gateway, plus InjectFiles() for sharing the Files instance through DI.
- [Next.js](https://files-sdk.dev/docs/ui/server/next): Mount the Files gateway in the Next.js App Router. createRouteHandler returns { GET, POST, PUT }, and the same handler runs on Node and the Edge runtime.
- [Nitro](https://files-sdk.dev/docs/ui/server/nitro): Mount the Files gateway in a Nitro (or Nuxt server) route, on Nitro 2 (h3 1) or Nitro 3 (h3 2). Hands the gateway a Web Request and returns the Response for Nitro to flush.
- [SvelteKit](https://files-sdk.dev/docs/ui/server/sveltekit): Mount the Files gateway in a SvelteKit +server.ts endpoint. createRouteHandler returns { GET, POST, PUT } over the Web Request, on Node and edge alike.
- [TanStack Start](https://files-sdk.dev/docs/ui/server/tanstack-start): Mount the Files gateway in a TanStack Start server route. createRouteHandler returns { GET, POST, PUT } over the Web Request - runs on every deploy target.
- [Upload lifecycle](https://files-sdk.dev/docs/ui/server/upload-lifecycle): onUploadComplete runs on the server once per verified upload, so you can record it, hand data back to the browser, or reject it, without a second endpoint.

## Guides

### Uploads

- [Build a Next.js file uploader with Cloudflare R2](https://files-sdk.dev/guides/nextjs-r2-file-upload): Signed-in users upload from a Next.js app straight to a private R2 bucket with progress, then download only their own files through short-lived signed URLs.
- [Upload files in TanStack Start with server routes and streaming](https://files-sdk.dev/guides/tanstack-start-file-upload): A TanStack Start server route that sends uploads straight from the browser to S3 under a size-capped POST policy, or streams them through your server.
- [Upload files in Nuxt to a private Backblaze B2 bucket](https://files-sdk.dev/guides/nuxt-file-upload): A Nuxt server route signs browser uploads straight to a private B2 bucket, checks each file once it lands, and serves downloads through short-lived signed URLs, behind nginx or not.
- [Upload files in SvelteKit to Google Cloud Storage with progress](https://files-sdk.dev/guides/sveltekit-file-upload): A SvelteKit endpoint signs browser uploads straight to a private GCS bucket, a load function lists each user's files, and adapter-node's CSRF, origin, and body-size checks stay out of the way.
- [Upload files to S3 from Express without buffering them in memory](https://files-sdk.dev/guides/express-s3-file-upload): An Express server where browsers upload straight to S3 under a size-capped POST policy, and server-side uploads stream into S3 a few parts at a time, with no multer.
- [Enforce file-size and content-type limits on presigned uploads](https://files-sdk.dev/guides/presigned-upload-validation): What S3, R2, Vercel Blob, GCS, and Azure check when the browser uploads to a signed URL, and how to verify the actual bytes when the signature can't.
- [Resume an S3 multipart upload after a process restart](https://files-sdk.dev/guides/resume-s3-multipart-upload): A Node or Bun uploader that saves its S3 multipart session to disk, survives a crash or Ctrl-C, and finishes from the parts S3 already holds.
- [Build a shadcn file manager with uploads, folders, previews, and progress](https://files-sdk.dev/guides/shadcn-file-manager): One page of Files SDK shadcn components that browses folders, uploads into them with progress, previews files, pages long folders, and retries failures.

### Downloads and access

- [Share private Vercel Blob files with authenticated, expiring downloads](https://files-sdk.dev/guides/vercel-blob-private-downloads): Invoice PDFs in a private Vercel Blob store that each customer can download only for themselves, and when to redirect to signed URLs or proxy instead.
- [Stream private video from S3 or R2 with HTTP Range requests](https://files-sdk.dev/guides/private-video-range-streaming): A Next.js video player for private S3 or R2 objects that seeks with 206 range responses, using signed URLs or a session-checked proxy route.
- [Stream S3 or R2 files as a ZIP download without buffering them](https://files-sdk.dev/guides/s3-r2-zip-download): A Next.js route that zips a user's selected files or folder from S3 or R2 while it streams, checks the selection before the first byte, and hands larger exports to a background job.
- [Isolate each tenant's files in a multi-tenant application](https://files-sdk.dev/guides/multi-tenant-file-storage): Keep two tenants in one bucket apart with server-derived key prefixes, and see exactly what the gateway returns when one tenant reaches for the other's files.
- [Let users restore deleted files and earlier versions in S3 or R2](https://files-sdk.dev/guides/restore-deleted-files-s3-r2): Add a trash bin and per-file version history to an S3 or R2 app with softDelete() and versioning(), authorize restore and permanent deletion separately, and run a retention job that actually frees the space.

### AI

- [Add persistent, private file attachments to an AI SDK chat app](https://files-sdk.dev/guides/ai-sdk-file-attachments): Users attach images and PDFs to an AI SDK 7 chat. Files stay in a private bucket, and each message stores only a key that is re-authorized on every read.
- [Give an AI SDK agent access to S3 or R2 with approval-gated storage tools](https://files-sdk.dev/guides/ai-sdk-storage-tools): An AI SDK 7 agent lists, reads, and proposes changes to one user's files in S3 or R2, and every write waits until the user approves it in the chat.
- [Run a read-only MCP server for S3 or R2 and connect Claude Code](https://files-sdk.dev/guides/s3-r2-mcp-server): Start the files-sdk MCP server against one S3 or R2 bucket so Claude Code, Cursor, Claude Desktop, or Codex can list, search, and read objects with keys that can't change anything.

### Providers and runtimes

- [Set up Vercel Blob authentication: OIDC, local development, and token fallback](https://files-sdk.dev/guides/vercel-blob-authentication): Which credential the files-sdk Vercel Blob adapter uses on Vercel Functions, in local development, and on other hosts, and how to fix each setup error.
- [Private Supabase Storage uploads with working RLS policies](https://files-sdk.dev/guides/supabase-private-uploads-rls): Per-user Row Level Security policies for a private Supabase bucket, a Next.js gateway that runs every Storage call as the signed-in user, and what each caller gets back.
- [Firebase Storage uploads with Firebase Auth and private downloads](https://files-sdk.dev/guides/firebase-storage-authenticated-uploads): Verify Firebase ID tokens in a Next.js route, keep each user's files under their uid, and serve downloads through short-lived signed URLs instead of permanent token links.
- [Upload files to S3 with Bun: native S3Client, presigned URLs, and SDK tradeoffs](https://files-sdk.dev/guides/bun-s3-upload): One Bun file server written twice, with Bun's own S3Client and with Files SDK, covering browser uploads and when to move to the s3() adapter instead.
- [Use R2 in Cloudflare Workers: bindings, the S3 API, and presigned uploads](https://files-sdk.dev/guides/cloudflare-workers-r2-storage): A Worker that reads and writes R2 through its binding, signs presigned URLs with an R2 API token, and lets browsers upload straight to the bucket.
- [Generate GCS signed URLs without a service account key](https://files-sdk.dev/guides/gcs-signed-urls-without-service-account-key): Sign Cloud Storage download and upload URLs on Cloud Run, GKE, or your own machine with no JSON key file, and fix the setup where reads work but signing fails.
- [Upload to Azure Blob Storage with managed identity and user delegation SAS](https://files-sdk.dev/guides/azure-blob-managed-identity-upload): Let browsers upload to a private Azure Blob container with no account key anywhere, using DefaultAzureCredential on the server and user delegation SAS URLs, with the roles each step needs.
- [Use Hetzner Object Storage from TypeScript: endpoints, uploads, and signed URLs](https://files-sdk.dev/guides/hetzner-object-storage-typescript): Connect TypeScript to a Hetzner bucket in fsn1, nbg1, or hel1, upload files, share private ones through signed URLs, and set the CORS rule browser uploads need.
- [Upload and privately share files on Wasabi with TypeScript](https://files-sdk.dev/guides/wasabi-file-upload-typescript): Store documents in a private Wasabi bucket, verify each upload, and share them through expiring links you can revoke, with the endpoint for every region.
- [Upload files to Bunny Storage and serve them through a Pull Zone](https://files-sdk.dev/guides/bunny-storage-cdn-upload): Stream browser uploads through your server into a Bunny Storage zone, serve them from your Pull Zone hostname, and purge the edge cache when a file changes.
- [Upload, serve, and delete private Cloudinary files correctly](https://files-sdk.dev/guides/cloudinary-private-file-lifecycle): Sign browser uploads into authenticated Cloudinary assets, check each file before it goes live, serve it through short-lived signed URLs, and delete it with the settings it was stored under.

### Architecture and migration

- [Build one TypeScript storage API for S3, GCS, Azure, and Dropbox](https://files-sdk.dev/guides/unified-storage-api-typescript): One storage module that picks S3, Google Cloud Storage, Azure Blob, or Dropbox from config, runs the same code on each, and branches on what each can do.
- [Test S3 storage code without AWS](https://files-sdk.dev/guides/test-s3-code-without-aws): Run an Express upload route and its storage calls against an in-memory adapter in Vitest, inject S3 failures and retries, and know which S3 behaviors still need MinIO or aws-sdk-client-mock.
- [Encrypt files before they reach S3 or R2](https://files-sdk.dev/guides/client-side-encryption-s3-r2): Encrypt every upload with AES-256-GCM in your own process so the bucket only ever holds ciphertext, then decrypt on download, behind a gateway, and across a key rotation.
- [Prevent concurrent S3 uploads from overwriting each other](https://files-sdk.dev/guides/s3-conditional-upload-conflicts): Use S3's native If-None-Match and If-Match writes to create an object only once and update it only from the version you read, then recover from conflicts and lost responses.
- [Process R2 uploads with Queues and idempotent handlers](https://files-sdk.dev/guides/r2-upload-events-queues): A Queue consumer Worker that runs work for every file R2 stores, survives duplicate and out-of-order notifications, and replays what failed from a dead-letter queue.
- [Import SFTP files into S3 with retries and a durable checkpoint](https://files-sdk.dev/guides/sftp-to-s3-import-pipeline): A scheduled Node job that pulls a partner's files from SFTP into S3, pins the server's host key, imports each file version once, and picks up from a manifest after a crash.
- [Migrate S3 files to R2 and verify the result](https://files-sdk.dev/guides/migrate-s3-to-r2): Copy an S3 bucket to Cloudflare R2 with a script that records failures, retries only those keys, checks every object by checksum, and plans a rollback.
- [Test storage failover and recover writes after an outage](https://files-sdk.dev/guides/storage-failover-recovery-drill): Run an outage drill with failover() and two local MinIO servers, see which backend answers each read, write, and delete, then copy the missed writes back and verify both sides match.

### Troubleshooting

- [Fix Vercel's 413 upload error with direct-to-storage uploads](https://files-sdk.dev/guides/vercel-large-file-upload): Stop FUNCTION_PAYLOAD_TOO_LARGE by signing uploads in a small Vercel Function request and sending the file from the browser straight to Vercel Blob or R2.
- [Fix Cloudflare R2 CORS and presigned URL 403 errors](https://files-sdk.dev/guides/r2-cors-presigned-url-errors): Tell a CORS rule problem from a rejected signature when browser uploads to R2 fail, and fix each cause, from origin mismatches to expired presigned URLs.

## RSS Feeds

- [Files SDK — Changelog](https://files-sdk.dev/changelog/rss.xml)

## Agent resources

- [llms-full.txt](https://files-sdk.dev/llms-full.txt): The full Markdown of every page in one file.
- [Page Markdown](https://files-sdk.dev/index.md): Append `.md` to any page URL to fetch that page as raw Markdown.
- [JSON API](https://files-sdk.dev/api/docs/pages.json): Page index of the JSON docs API; each entry links the page's JSON and Markdown forms. Described by the OpenAPI document at https://files-sdk.dev/openapi.json.
- [MCP server](https://files-sdk.dev/mcp): Streamable HTTP Model Context Protocol server with search_docs, get_page, list_pages, and get_navigation tools, plus every page as a resource. Discovery document: https://files-sdk.dev/.well-known/mcp.json
- [Agent skills](https://files-sdk.dev/.well-known/agent-skills/index.json): Agent Skills discovery index of the skills this site publishes.
- [API catalog](https://files-sdk.dev/.well-known/api-catalog): RFC 9727 linkset of the APIs documented here.
- [AI catalog](https://files-sdk.dev/.well-known/ai-catalog.json): ARD manifest of the agent-facing resources on this site (MCP server, skills, APIs).
- [agent-readability.json](https://files-sdk.dev/agent-readability.json): Manifest of every agent-facing artifact on this site.
- [Sitemap](https://files-sdk.dev/sitemap.xml): Every indexable page URL with its last-modified date.
