---
title: UploadThing
description: UploadThing via the uploadthing/server SDK. Auto-loads UPLOADTHING_TOKEN and maps your keys onto UploadThing's customId so operations route by your key.
peerDeps:
  - "uploadthing"
---

## Installation

`uploadthing` is an optional peer dependency of `files-sdk` - install alongside the SDK so the adapter's imports resolve at runtime.

```package-install
files-sdk uploadthing
```

## Usage

UploadThing via the official `uploadthing/server` SDK. UploadThing generates its own internal file keys, so the adapter maps the user-supplied key onto UploadThing's `customId` with `defaultKeyType: "customId"` - every subsequent operation routes by your key, not the auto-generated one.

```ts lineNumbers
import { Files } from "files-sdk";
import { uploadthing } from "files-sdk/uploadthing";

// UPLOADTHING_TOKEN is auto-loaded from env. The token is a base64
// JSON of { apiKey, appId, regions[] } - the adapter decodes it at
// construction so url() can synthesize the public CDN URL and
// signedUploadUrl() can sign a UFS PUT URL without an API round trip.
const files = new Files({
  adapter: uploadthing({
    // acl: "public-read",       // default; switch to "private" to mint
    //                            // signed URLs through generateSignedURL
    // slug: "mediaUploader",    // required only for signedUploadUrl()
  }),
});
```

## Options

<AutoTypeTable
  path="../../packages/files-sdk/src/uploadthing/index.ts"
  name="UploadThingAdapterOptions"
/>

## Compatibility

| Method            | Status | Notes                                                                                                                                                                                                                                                                                                                                                                                            |
| ----------------- | :----: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `upload`          |   ⚠️   | User `metadata` and `cacheControl` aren't supported by the UFS API, so passing either throws rather than silently dropping it. Resumable uploads (`control`) are not supported — UploadThing manages chunking server-side and exposes no resumable session.                                                                                                                                      |
| `download`        |   ✅   |                                                                                                                                                                                                                                                                                                                                                                                                  |
| `delete`          |   ✅   |                                                                                                                                                                                                                                                                                                                                                                                                  |
| `list`            |   ⚠️   | UploadThing's listFiles is offset/limit, not cursor-based - the adapter encodes the next offset as a numeric cursor. `prefix` is unsupported server-side; the adapter filters the returned page client-side, which under-returns when the prefix isn't satisfied within a single page.                                                                                                           |
| `search`          |   ⚠️   | Built on `listAll` — inherits this adapter's `list` behavior above. Client-side key match (glob, regex, substring, exact).                                                                                                                                                                                                                                                                       |
| `head`            |   ⚠️   | UploadThing has no metadata endpoint, so `head()` issues a HEAD request against the resolved file URL (signed for private, CDN for public) and parses size/content-type/etag/last-modified from the response headers. User `metadata` isn't supported.                                                                                                                                           |
| `exists`          |   ⚠️   | UploadThing has no metadata endpoint, so `exists()` issues a HEAD request against the resolved file URL (signed for private, CDN for public) and treats `404` as `false`.                                                                                                                                                                                                                        |
| `copy`            |   ⚠️   | Read-then-write - UploadThing has no server-side copy primitive, so the source is downloaded and re-uploaded. Costs an egress + an ingest; not atomic.                                                                                                                                                                                                                                           |
| `url`             |   ⚠️   | Public adapters return the permanent CDN URL `https://{appId}.ufs.sh/f/{key}` and silently ignore `expiresIn`. Private adapters mint a signed read URL via `generateSignedURL` (1-hour default). `responseContentDisposition` throws either way - UploadThing has no Content-Disposition override on signed or CDN URLs. Use a private adapter for buckets with untrusted user-uploaded content. |
| `signedUploadUrl` |   ⚠️   | PUT URL only - built against UploadThing's UFS ingest endpoint with an HMAC-SHA256 signature over the URL. `maxSize` is advisory: UploadThing enforces upload caps via the file-router config tied to the adapter's `slug`, not via the URL signature. `minSize` is ignored (no equivalent on UFS). The user-supplied key is bound as `x-ut-custom-id` so subsequent ops can route by it.        |
