API Reference
UTApi (Server SDK)

UTApi

The UploadThing API Helper, for use ON YOUR SERVER. It's basically just a REST API but better.

To get started, initialize an instance of UTApi.

Prior to v5.7, this was exported as a regular object called utapi without any custom intialization support.

~/server/uploadthing.ts
import { UTApi } from "uploadthing/server";
 
export const utapi = new UTApi();

The constructor takes some optional arguments that you can pass to override the defaults. Below are shown the available options, the default values, and the types of the values.

export interface UTApiOptions {
  /**
   * Provide a custom fetch function.
   * @default globalThis.fetch
   */
  fetch?: FetchEsque;
  /**
   * Provide a custom UploadThing API key.
   * @default process.env.UPLOADTHING_SECRET
   */
  apiKey?: string;
  /**
   * @default "info"
   */
  logLevel?: LogLevel;
  /**
   * Set the default key type for file operations. Allows you to set your preferred filter
   * for file keys or custom identifiers without needing to specify it on every call.
   * @default "fileKey"
   */
  defaultKeyType?: "fileKey" | "customId";
}

uploadFiles

Added in v5.3

Upload files directly from your server without using the file router. Useful for server-side file processing, uploading from a server action, and much more.

import { utapi } from "~/server/uploadthing.ts";
 
async function uploadFiles(formData: FormData) {
  "use server";
  const files = formData.getAll("files");
  const response = await utapi.uploadFiles(files);
  //    ^? UploadedFileResponse[]
}
 
function MyForm() {
  return (
    <form action={uploadFiles}>
      <input name="files" type="file" multiple />
      <button type="submit">Upload</button>
    </form>
  );
}

When uploading files using uploadFiles, the files must be present on your server. Then presigned URLs are generated on our servers before the files can be uploaded to the storage provider.

ArgumentsTypeRequiredDescription
filesFileEsque || FileEsque[]YesThe file(s) you want to upload
opts.metadataJsonNoMetadata to attach to the file(s)
opts.contentDisposition"inline" | "attachment"NoWhat content disposition (opens in a new tab) should be set on the storage provider. Defaults to inline
opts.acl"public-read" | "private"NoWhat ACL should be set on the storage provider. Defaults to whatever is configured on your app settings and can only be used if the app allows per-request overrides.
// Edge / Node < 20 friendly File interface
interface FileEsque extends Blob {
  name: string;
  customId?: string;
}

The returned UploadedFileResponse is an object with the following shape. If the files argument is an array, the returned value will be of type UploadedFileResponse[].

type UploadFileResponse =
  | { data: UploadData; error: null }
  | { data: null; error: UploadError };
 
type UploadData = {
  key: string;
  url: string;
  name: string;
  size: number;
};
 
type UploadError = {
  code: string;
  message: string;
  data: any;
};

uploadFilesFromUrl

Added in v5.3

Have a file hosted somewhere else you want to upload on UploadThing? This is the function you're looking for.

⚠️

When uploading files from URL, the file is first downloaded on your server, before presigned URLs are created and the file is uploaded to the storage provider.

import { utapi } from "~/server/uploadthing.ts";
 
const fileUrl = "https://test.com/some.png";
const uploadedFile = await utapi.uploadFilesFromUrl(fileUrl);
//    ^? UploadedFileResponse
 
const fileUrls = ["https://test.com/some.png", "https://test.com/some2.png"];
const uploadedFiles = await utapi.uploadFilesFromUrl(fileUrls);
//    ^? UploadedFileResponse[]
ArgumentsTypeRequiredDescription
urlsMaybeUrl | UrlWithOverrides | (MaybeUrl | UrlWithOverrides)[]YesThe URL(s) of the file(s) you wish to upload. Pass a UrlWithOverrides object if you wanna set the filename yourself, set a customId for the file. If no override is provided, the filename will be inferred from the URL pathname.
opts.metadataJsonNoMetadata to attach to the file(s)
opts.contentDisposition"inline" | "attachment"NoWhat content disposition (opens in a new tab) should be set on the storage provider. Defaults to inline
opts.acl"public-read" | "private"NoWhat ACL should be set on the storage provider. Defaults to whatever is configured on your app settings and can only be used if the app allows per-request overrides.
type MaybeUrl = string | URL;
type UrlWithOverrides = { url: MaybeUrl; name?: string; customId?: string };

deleteFiles

Added in v4.0

deleteFiles takes in a fileKey or an array of fileKeys and deletes them from the server.

import { utapi } from "~/server/uploadthing.ts";
 
await utapi.deleteFiles("2e0fdb64-9957-4262-8e45-f372ba903ac8_image.jpg");
await utapi.deleteFiles([
  "2e0fdb64-9957-4262-8e45-f372ba903ac8_image.jpg",
  "1649353b-04ea-48a2-9db7-31de7f562c8d_image2.jpg",
]);
await deleteFiles("myCustomIdentifier", { keyType: "customId" });
ArgumentsTypeRequiredNotesDescription
inputstring || string[]YesAdded in v5.0The fileKey or fileKeys you want to delete
opts.keyType"fileKey" | "customId"NoAdded in v6.4The type of key you are passing in. Defaults to fileKey

getFileUrls

Added in v4.0

getFileUrls takes in a fileKey or an array of fileKeys and returns the URLs to access them.

import { utapi } from "~/server/uploadthing.ts";
 
const oneUrl = await utapi.getFileUrls(
  "2e0fdb64-9957-4262-8e45-f372ba903ac8_image.jpg",
);
const multipleUrls = await utapi.getFileUrls([
  "2e0fdb64-9957-4262-8e45-f372ba903ac8_image.jpg",
  "1649353b-04ea-48a2-9db7-31de7f562c8d_image2.jpg",
]);
ArgumentsTypeRequiredNotesDescription
inputstring || string[]YesAdded in v5.0The fileKey or fileKeys you want to get URLs for
opts.keyType"fileKey" | "customId"NoAdded in v6.4The type of key you are passing in. Defaults to fileKey

listFiles

Added in v5.3

listFiles returns an array of objects containing file ids and keys for all files that have been uploaded to the application your API key corresponds to. As of 6.0.5, you can optionally pass an options object to paginate the results

type ListFilesOptions = {
  /**
   * The maximum number of files to return
   * @default 500
   */
  limit?: number;
  /**
   * The number of files to skip
   * @default 0
   */
  offset?: number;
};
ArgumentsTypeRequiredNotesDescription
optsListFilesOptionsNoAdded in v6.0.5Options for pagination.
import { utapi } from "~/server/uploadthing.ts";
 
const files = await utapi.listFiles();
 
console.log(files);
/*
 * [
 *  {
 *    id: "7099d109-39ec-43fe-a887-4a4fd87cad88 ,
 *    customId: null, // whatever you set it to when uploading
 *    key: "2e0fdb64-9957-4262-8e45-f372ba903ac8_image.jpg",
 *    name: "image.jpg",
 *    status: "uploaded",
 *  }
 * ]
 */

renameFiles

Added in v5.3

renameFiles takes in a Rename or an array of Renames and renames the appropriate files on the server.

import { utapi } from "~/server/uploadthing.ts";
 
await utapi.renameFiles({
  key: "2e0fdb64-9957-4262-8e45-f372ba903ac8_image.jpg",
  newName: "myImage.jpg",
});
 
await utapi.renameFiles([
  {
    key: "2e0fdb64-9957-4262-8e45-f372ba903ac8_image.jpg",
    newName: "myImage.jpg",
  },
  {
    key: "1649353b-04ea-48a2-9db7-31de7f562c8d_image2.jpg",
    newName: "myOtherImage.jpg",
  },
]);

Rename type definition

type Rename =
  | {
      key: string;
      newName: string; // should include file extension
    }
  | {
      customId: string;
      newName: string; // should include file extension
    };
ArgumentsTypeRequiredDescription
renamesRename || Rename[]YesObject specifying what file to rename and the new name

getSignedURL

Added in v6.2

Retrieve a signed URL for a private file.

import { utapi } from "~/server/uploadthing.ts";
 
const fileKey = "2e0fdb64-9957-4262-8e45-f372ba903ac8_image.jpg";
const url = await utapi.getSignedURL(fileKey, {
  expiresIn: 60 * 60, // 1 hour
  // expiresIn: '1 hour',
  // expiresIn: '3d',
  // expiresIn: '7 days',
});
💡

The expiresIn option can only be used if you allow overrides in your app settings on the UploadThing dashboard.

ArgumentsTypeRequiredDescription
keystringYesThe file key you want to get the URL for.
opts.expiresInnumber | TimeStringNoHow long the URL should be valid for. Must be positive and less than 604 800 (7 days).
opts.keyType"fileKey" | "customId"NoThe type of key you are passing in. Defaults to fileKey

TimeString refers to a human-readable string that can be parsed as a number, followed by a unit of time. For example, 1s, 1 second, 2m, 2 minutes, 7 days etc. If no unit is specified, seconds are assumed.

updateACL

Added in v6.8

Update the ACL of set of files.

import { utapi } from "~/server/uploadthing.ts";
 
// Make a single file public
await utapi.updateACL(
  "2e0fdb64-9957-4262-8e45-f372ba903ac8_image.jpg",
  "public-read",
);
 
// Make multiple files private
await utapi.updateACL(
  [
    "2e0fdb64-9957-4262-8e45-f372ba903ac8_image.jpg",
    "1649353b-04ea-48a2-9db7-31de7f562c8d_image2.jpg",
  ],
  "private",
);
ArgumentsTypeRequiredDescription
keysstring | string[]YesThe fileKeys (or customIds) you want to update the ACL for
acl"public-read" | "private"YesThe ACL to update to.
opts.keyType"fileKey" | "customId"NoThe type of key you are passing in. Defaults to fileKey