Secure Delivery (Authenticated URLs)

Control who and for how long can access files in your project via authenticated URLs. When enabled, a user will require a token to access your content by the link like this:{uuid}/?token=exp={timestamp}~hmac={token}

In other words, Secure Delivery is a CDN URL with GET parameters that include the token and its expiration time to access protected content.

Use cases

When to use Secure Delivery:

  • Users upload personal, medical, and other sensitive data.
  • Only an authorized client can access certain content.
  • Content access is limited in time.

How Secure Delivery works

Contact us to enable the Secure Delivery feature.

Prior to using Secure Delivery, set up a custom CNAME. The URL format depends on your custom domain's CDN provider.

Akamai as a primary CDN provider for Uploadcare users. Here's an example:{uuid}/?token=exp={timestamp}~acl={acl}~hmac={token}
  • {uuid} is a UUID of any file in your Uploadcare project or a URI (UUID + transformations + filename), which is a URL part.
  • {acl} is an optional Access Control List parameter. It supports wildcards (*, ?). Also, it can be a string (single path) or an array (multi-paths).

ACL examples to access files with a token:

  • acl=/*/ – any file in a project
  • acl=/{uuid}/ – original file with UUID
  • acl=/{uuid}/-/resize/640x/ – modified file version

Token generation

Your backend app should take care of generating access tokens. We recommend that you start with ready-made Akamai solutions for popular languages:

Full Akamai implementation guide: Auth Token 2.0 Verification and DD.

Proxy Backend example

The proxy backend is an API endpoint of your application. The app needs to resolve the following tasks:

  • Accept escaped preview URL as a GET parameter.
  • Check user authorization.
  • Generate expiring access tokens for that URL.
  • Append access tokens to the URL.
  • Redirect to that URL.

Don’t forget to check user credentials on your backend. Make sure not to authenticate anonymous user requests. Otherwise using Secure Delivey don't make any sense.

Here is a basic proxy backend Node.js app:

app.get('/preview', (req, res) => {
  const url = req.query.url
  const user = req.user

  if (!user) {
    res.status(403).send('Authorization failed')

  const expire = Math.round( / 1000) + 120
  const token = generateToken(url, expire)

  const secureUrl = url + `?token=${token}&expire=${expire}`


Show Image Previews in File Uploader

After uploading, File Uploader loads image previews from the CDN:

-> (GET){uuid}/

With Secure Delivery on, File Upload can't show previews because authenticated URLs include a token part. To work that around, you can load images through a proxy backend, where it can hook up the token info:

-> (GET){uuid}%2F
-> (Redirect){uuid}/?token={token}&expire={expire}

Here are two options that can help you show image previews over Secure Delivery:

Option previewProxy

Implementing the previewProxy option works best for these cases:

  • Your application uses cookie-based authorization.
  • Your proxy backend and your app are located in the same domain (otherwise, cookies won't be sent).
  • You don’t need any other image-related data beside URLs.

To use previewProxy option, specify your proxy backend endpoint URL, and you're good to go:


It'll let File Uploader load image previews via the following URL:{uuid}%2F

It appends a query parameter with image preview URL to previewProxy:

newPreviewUrl = previewProxy + 'url={previewUrl}'

By default, the uploader uses url as the query parameter name, but you can have a custom naming as well:

'' + 'url={previewUrl}'
'' + '&url={previewUrl}'
'' + '{previewUrl}'

Option previewUrlCallback

This option provides you with explicit control over the File Uploader preview URLs. In code, previewUrlCallback is a function with a signature:

(previewUrl, fileInfo) => previewUrl


UPLOADCARE_PREVIEW_URL_CALLBACK = function(previewUrl, fileInfo) {
    const jwtToken = getJWTToken()
    return `` +
      `url=${encodeURIComponent(previewUrl)}&` +
      `uuid=${fileInfo.uuid}&` +

Note, previewUrlCallback overrides previewProxy, and the latter option will be ignored.