Working with Files
After your files have been uploaded, you will most likely want to do something with them. This page shows how to work with your uploaded files.
Accessing Public Files
UploadThing serves all files from a CDN at the following URL pattern:
https://<APP_ID>.ufs.sh/f/<FILE_KEY>
If you set a customId
when uploading the file, you can also use
https://<APP_ID>.ufs.sh/f/<CUSTOM_ID>
to access it.
Do not use the raw file URL from the storage provider, e.g. https://bucket.s3.region.amazonaws.com/<FILE_KEY>
. We reserve the right to move objects between different storage providers and/or buckets, so this URL is not guaranteed to remain valid.
Previously, all files were served from https://utfs.io/f/<FILE_KEY>
.
This is still supported, but not recommended and may be deprecated in the future.
Given that all files are served from a subdomain of your app, you have granular control over what URLs are allowed to be processed. Below is an example of how to setup image optimization allow filtering in Next.js that only allows optimizing images from your app:
/** @type {import('next').NextConfig} */
export default {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "<APP_ID>.ufs.sh",
pathname: "/f/*",
},
],
},
};
Accessing Private Files
If your files are protected with
access controls, you can generate a
presigned URL using
UTApi.getSignedUrl
. Here's a reference
implementation using Node.js crypto:
import crypto from "node:crypto";
const apiKey = "sk_live_...";
const url = new URL("https://<APP_ID>.ufs.sh/f/<FILE_KEY>");
const algorithm = "hmac-sha256";
// Set expiration to 30 seconds from now (you choose how long you want the URL to be valid for)
const expires = Date.now() + 1000 * 30;
url.searchParams.set("expires", String(expires));
const signature = crypto
.createHmac(algorithm, apiKey)
.update(url.href)
.digest("hex");
url.searchParams.set("signature", `${algorithm}=${signature}`);
// The URL is now signed and ready to use
await fetch(url); // Status 200 OK
The URL will be valid for the duration in milliseconds you set in the expires
parameter or until the API key is deleted or revoked.
You can also request presigned URLs using the /requestFileAccess
API
endpoint (see OpenAPI Specification). However,
generating URLs client-side is faster as it avoids an additional API call.
The presigned URL follows the same patterns as public files, with additional query parameters to authenticate the request.
Other File Operations
Please refer to our server SDK, UTApi for more information on how to work with files. You can also access the API directly using the OpenAPI Specification.