Upload control with signed uploads

Signed uploads restrict who can upload files to your Uploadcare project, and for how long. They work with File Uploader, jQuery File Uploader (deprecated), and Upload API.

Enable signed uploads

  1. Go to your Dashboard and select an existing project or create a new one.
  2. Click Enable next to Signed Uploads in the uploading settings.

Once enabled, every Upload API request must include a signature and expire.

How it works

Your backend computes an HMAC-SHA256 signature of the expire timestamp using your project’s secret key, then sends both signature and expire as request parameters with the upload request. Upload API recomputes the same signature and compares — if it doesn’t match, or is missing, the upload is rejected.

Generate a signature

The signature is a hex-encoded HMAC-SHA256 digest:

  • Key: your project’s secret key (from the API keys section), UTF-8 encoded
  • Message: the expire value as a decimal string (e.g. "1700000000")
The @uploadcare/signed-uploads package accepts milliseconds and converts to seconds internally. If you implement signing without this package, expire must be a Unix timestamp in seconds — not milliseconds.

Here’s how to generate the signature on your backend:

1// Option 1: by expiration timestamp (milliseconds since epoch)
2import { generateSecureSignature } from '@uploadcare/signed-uploads'
3
4const { secureSignature, secureExpire } = generateSecureSignature('YOUR_SECRET_KEY', {
5 expire: Date.now() + 60 * 30 * 1000 // expire in 30 minutes
6})
1// Option 2: by expiration date
2import { generateSecureSignature } from '@uploadcare/signed-uploads'
3
4const { secureSignature, secureExpire } = generateSecureSignature('YOUR_SECRET_KEY', {
5 expire: new Date("2099-01-01") // expire on 2099-01-01
6})
1// Option 3: by lifetime
2import { generateSecureSignature } from '@uploadcare/signed-uploads'
3
4const { secureSignature, secureExpire } = generateSecureSignature('YOUR_SECRET_KEY', {
5 lifetime: 60 * 30 * 1000 // expire in 30 minutes
6})

Expiration

The expire value is a Unix timestamp in seconds that defines when the signature expires.

Upload example

Request:

$curl -F "UPLOADCARE_PUB_KEY=YOUR_PUBLIC_KEY" \
> -F "signature=YOUR_SIGNATURE" \
> -F "expire=YOUR_EXPIRE" \
> -F "file=@image.jpg" \
> "https://upload.uploadcare.com/base/"

Response:

1{
2 "file": "c0d776d4-8c8e-47df-9e92-03b68b99c2ba"
3}

File Uploader integration

For File Uploader, set the secure signature and secure expire options directly, or use secureUploadsSignatureResolver to fetch a fresh signature automatically as it nears expiration.

jQuery File Uploader was deprecated on September 1, 2025. The signed uploads integration still works, but we recommend migrating to File Uploader.

Errors

ErrorStatusCause
signature is required.400Missing signature parameter
expire is required.400Missing expire parameter
expire must be a UNIX timestamp.400expire is not a valid integer
Expired signature.403expire is in the past
Invalid signature.403HMAC does not match any project secret key

For the complete list of Upload API errors, see the Upload API errors.