Transloadit
Pricing
  • File Uploads
  • File Importing
  • Batch Processing
  • Video Encoding
  • Audio Encoding
  • Image Processing
  • Document Processing
  • Artificial Intelligence
  • File Filtering & Security
  • Media Cataloging
  • File Compression
  • Code Evaluation
  • File Exporting
  • Smart CDN
  • View all services
  • Explore integrations
  • Explore live demos
  • Uppy
  • TransloaditKit
  • Android SDK
  • Node.js SDK
  • Python SDK
  • Ruby SDK
  • Go SDK
  • Java SDK
  • PHP SDK
  • Zapier
  • MCP Server
  • Transloadit CLI
  • Terraform
  • Essentials
  • Best Practices
  • FAQ
  • Robots
  • API
  • Formats
  • Build your first app
  • About
  • Comparisons
  • Open Source
  • Testimonials
  • Jobs
  • Security
  • Posts
  • DevTimes
  • DevTips
  • Press
  • Research
  • Case Studies
  • Solutions
  • Guides
  • Glossary
  • Legal
  • Tools
  • Helping Coursera bring education to millions around the world
  • Transloadit Support
  • Open Source Support
  • Service level agreement
EssentialsRobotsFAQAPIFormatsBest Practices
Topics
  • Endpoints
  • Response codes
  • Authentication
  • Webhooks
  • Metadata
  • API security
  • Rate limiting
  • Queues
  • Resumable uploads
Authentication
  • Create a bearer token
  • Create a new Auth Key
  • Retrieve list of Auth Keys
  • Retrieve Auth Key scopes
  • Edit an Auth Key
  • Delete an Auth Key
  • Retrieve an Auth Key secret
Assemblies
  • Create a new Assembly
  • Retrieve an Assembly Status
  • Create an Assembly with a supplied ID
  • Stream Assembly changes live
  • Cancel a running Assembly
  • Replay an Assembly
  • Retrieve list of Assemblies
  • Assembly Status response
  • Retrieve Assembly statistics
Webhooks
  • Retrieve Assembly Notifications
  • Replay Assembly Notification
Billing
  • Retrieve a month’s bill
Queues
  • Retrieve currently used priority job slots
  • Retrieve priority job slot statistics
Resumable Uploads
  • Discover tus capabilities
  • Create a tus upload
  • Retrieve a tus upload offset
  • Upload tus file bytes
  • Terminate a tus upload
  • Download a tus upload
Template Credentials
  • Create a new Template Credential
  • Retrieve a Template Credential
  • Edit a Template Credential
  • Delete a Template Credential
  • Retrieve list of Template Credentials
  • Retrieve Template Credential types
Templates
  • Create a new Template
  • Retrieve a Template
  • Edit a Template
  • Delete a Template
  • Retrieve list of Templates
Digital Asset Management
  • Move or rename a DAM asset alpha
  • Delete a DAM asset alpha
  • Move DAM assets in bulk alpha
  • Delete DAM assets in bulk alpha
  • Move a Storage file or folder alpha
  • Retrieve a Storage asset
  • List Storage assets

Authentication

Auth Keys

For multipart Assembly-creation requests authenticated with an Auth Key, include an auth object inside the JSON-encoded params form field. The smallest such params value is shown below.

{
  "auth": {
    "key": "23c96d084c744219a2ce156772ec3211"
  }
}

The key field refers to the Auth Key associated with your Transloadit Workspace, found on the Credentials page. The above is the minimum authentication object for an Assembly request that uses an Auth Key. Other endpoints and authentication methods can use different request formats, as described by their endpoint documentation and below.

Assemblies that use /transloadit/import, directly or through a Template, require either a bearer token or signed params with a future params.auth.expires timestamp. This applies even when Workspace Signature Authentication is disabled. An Auth Key alone is not sufficient; bearer-authenticated requests do not need a separate signature or expiry.

Signature Authentication

We recommend enabling Signature Authentication on your account, especially if you're integrating with Transloadit from an untrusted environment (such as from the browser with Uppy⁠). You can enable Signature Authentication from your Workspace Settings.

Warning

We strongly recommend enabling Signature Authentication when interfacing with our API, particularly in untrusted environments where users may be able to access your Auth Key.

With Signature Authentication enabled, your Workspace's Auth Secret (found next to your Auth Key on the Credentials page) is then used as the key for an HMAC generated from the exact serialized params value. That value contains both a key (which is your Auth Key as mentioned earlier), and an expires param, which is a timestamp in the near future used as an expiry date for the request.

For creating Assemblies with Transloadit, your back-end could calculate a Signature that only covers certain parameters, authenticated users, and a timeframe that it deems legitimate usage. For instance, it would refuse to generate a signature for users that are not logged in. You could use any business logic on the server-side here to decide if you hand out a signature, or not. Transloadit can require a correct signature for the payload when an API request authenticates with your Auth Key.

To require Signature Authentication for API requests authenticated with your Auth Key:

  1. Go to the Workspace Settings in your account.
  2. In the API Settings section, enable the Require a correct Signature option.
  3. Hit the Save button.

Valid bearer tokens bypass signature requirements, including Workspace and Template settings; token scopes and audience restrictions still apply. These settings do not add authentication to capability-based access such as Assembly status, cancellation or resumable upload URLs. Keep Assembly IDs and capability URLs private, and follow each endpoint’s authentication guidance.

Note

Most back-end SDKs automatically use Signature Authentication when you supply your Auth Secret. So perhaps, just this introduction is all you need to know. If you are integrating Transloadit into untrusted environments, however, such as browsers (Uppy!), you’ll want to continue reading to see how your back-end can supply signatures to it.

How to generate Signatures

So, how does this all look?

The typical params field when creating an Assembly without Signature Authentication is as follows:

{
  "auth": {
    "key": "23c96d084c744219a2ce156772ec3211"
  },
  "steps": {
    // …
  }
}

The auth.key in this example is the Auth Key from API Credentials in your account.

To sign this request, the additional auth.expires field needs to be added. This adds it to our payload, which is protected by our signature. If someone would change it, Transloadit would reject the request as the signature no longer matches. You signed a different payload than the one we received. If the signature does match, then we will naturally compare and reject by date as instructed. This way, requests become very hard to indefinitely repeat by a third party that got a hold of this payload. Because even though our A+ grade HTTPS should already go a long way in preventing that, browser cache could be easier to snoop on.

The expires property must contain a timestamp in the (near) future. Use ISO 8601 format (YYYY-MM-DDTHH:mm:ss.sssZ) for the date, making sure that UTC is used for the timezone. For example:

{
  "auth": {
    "key": "23c96d084c744219a2ce156772ec3211",
    "expires": "YOUR_FUTURE_ISO_8601_TIMESTAMP"
  },
  "steps": {
    // …
  }
}

To calculate the signature for this request:

  1. From your front-end, stringify the above JavaScript object into JSON and send it to your back-end.
  2. From your back-end, calculate an RFC 6234-compliant⁠ HMAC hex signature on the string, with your Auth Secret as the key and the algorithm configured in your Auth Key’s signature_algo. New Auth Keys default to sha384. Legacy Auth Keys without a configured algorithm accept sha384, sha256, or sha1. Prefix the signature string with the algorithm name in lowercase. For example, the default algorithm uses sha384:<HMAC-signature>. You can send that string to your front-end (as long as you made the appropriate checks to guarantee it was a genuine request from your front-end).
  3. From your front-end, add a signature multipart POST field containing this value to your request (e.g., with a hidden field in an HTML form).
Note

If your implementation uses a template_id instead of steps, there’s no need to generate a signature for the Instructions that your Template contains. We should only sign communication payloads.

Note

We strongly recommend including a randomly generated params.nonce value for each request at the top level of params. This makes independently generated signatures distinct and avoids accidental signature reuse. A nonce does not make retries idempotent: retrying an Assembly-creation request can create another Assembly. Handle retry deduplication in your application when needed. Do not reuse signed params across endpoints. Template reads, Auth Key listing, Template Credential listing, and billing reads reject signatures already recorded for a different endpoint or used to create an Assembly, with SIGNATURE_REUSE_DETECTED. Generate fresh signed params for each request.

The full request should look similar to the below:

{
  "params": {
    "auth": {
      "key": "23c96d084c744219a2ce156772ec3211",
      "expires": "YOUR_FUTURE_ISO_8601_TIMESTAMP",
    },
    "nonce": "04ac6cb6-df43-41fb-a7fd-e5dd711a64e1",
    "steps": {
      // …
    },
  },
  "signature": "sha384:YOUR_SIGNATURE",
}

Once the request was received by Transloadit, we also generate a signature following the same process, and compare the two signatures. If the signatures are different, then our servers will respond with INVALID_SIGNATURE.

In summary, the process is as follows:

  1. Generate a JSON payload to send to Transloadit as the params field.
  2. Calculate a signature based off the contents of the payload, using your Auth Secret as a key.
  3. Send the request to Transloadit, with the signature passed in the signature field
  4. Transloadit will calculate the same signature using your account's Auth Secret, and the contents of the payload.
  5. If the signatures match, the request is permitted, and an appropriate response is sent. Otherwise, the request is denied, and an error will be returned with the code INVALID_SIGNATURE.

This lets Transloadit authenticate the caller and verify the integrity of params, since a third party could not calculate a matching signature without access to your Auth Secret. TLS authenticates Transloadit to your client and protects the connection. Webhook signing is a separate flow for requests Transloadit sends to your servers.

Below are a few examples of how to perform a POST request to create an Assembly. We strongly recommend using one of our SDKs, which handle signature generation automatically and are well-tested.

Note

Webhooks are signed differently from API requests. Transloadit signs the exact JSON string in the transloadit form field using HMAC-SHA1 and the applicable Auth Secret. The signature field contains the hexadecimal digest without an algorithm prefix. Follow the webhook verification instructions, including how to select the Auth Secret, instead of using the API-request signing examples below.

Example code for different languages

The examples below demonstrate creating Assemblies using our official SDKs. The SDKs handle all signature generation internally, making integration simpler and more secure.

// yarn add @transloadit/node
// or
// npm install --save @transloadit/node

import { Transloadit } from '@transloadit/node'

const transloadit = new Transloadit({
  authKey: 'YOUR_TRANSLOADIT_KEY',
  authSecret: 'YOUR_TRANSLOADIT_SECRET',
})

const response = await transloadit.createAssembly({
  params: {
    template_id: 'YOUR_TRANSLOADIT_TEMPLATE_ID',
    // your other params like notify_url, fields, etc.
  },
  waitForCompletion: true,
})

console.log(response)

If you need to calculate a signature separately (e.g., for front-end use), you can use calcSignature:

const { signature, params } = transloadit.calcSignature({
  template_id: 'YOUR_TRANSLOADIT_TEMPLATE_ID',
})

console.log(signature, params)

View signature implementation source code⁠

Note

If you prefer to see the raw signature implementation details (e.g., to implement signing in a language we don’t have an SDK for), check the source code links above. The signature is an RFC 6234-compliant⁠ HMAC hex digest calculated on the JSON-encoded params string, using your Auth Secret as the key and the algorithm configured in your Auth Key’s signature_algo. New Auth Keys default to sha384. Prefix the signature with its lowercase algorithm name (e.g., sha384:...).

curl --fail-with-body -sS --location 'https://api2.transloadit.com/assemblies' \
  --form 'params={"auth":{"key":"23c96d084c744219a2ce156772ec3211","expires":"YOUR_FUTURE_ISO_8601_TIMESTAMP"},"template_id":"9cf67cbba601e37ee10c442b037e0"}' \
  --form 'signature=sha384:YOUR_SIGNATURE' \
  --form 'files=@/path/to/your/file.jpg'

Smart CDN signed URLs

To sign a Smart CDN URL, a similar process as for regular API signatures is used. A HMAC digest is calculated on a string, that is derived from the Smart CDN URL, with the Auth Secret as the key. For the signature to be valid, the used Auth Key must be enabled for Smart CDN use.

Important

To generate a signed Smart CDN URL, use the Auth Key designated for Smart CDN usage from your Credentials page. Smart CDN URLs require sha256. Regular API request signatures use the algorithm configured in the Auth Key’s signature_algo; new Auth Keys default to sha384.

Note

Legacy Smart CDN signatures based on s= and expires= are deprecated. New integrations should always use sig= with exp=.

The generation of a Smart CDN signature must be performed on the back-end. The process uses the Auth Secret, which is confidential and must not be exposed to your users on the front-end.

A typical Smart CDN URL has the following structure:

https://[your-workspace].tlcdn.com/[template-name]/[file-path]?[parameters]
  • [your-workspace] is your Transloadit Workspace name
  • [template-name] is the name of your Template
  • [file-path] is the path to the file you want to transform
  • [parameters] are desired transformation parameters (e.g. h=100)

A signed Smart CDN URL is generated by following these steps:

  1. Add the exp query parameter for defining a time in the future after which the signature is not accepted by the Smart CDN anymore. This is useful to limit temporal access to a file. The expiration moment is represented by the number of milliseconds since the UNIX epoch (the midnight at the beginning of January 1, 1970, UTC). While this parameter is optional, we highly recommend always setting an expiration time. For example, a signature using exp=1722517200000 is valid until Thu, 01 Aug 2024 13:00:00 GMT.
  2. Add the auth_key query parameter to define the Auth Key corresponding to the Auth Secret that is used to create the signature. If this parameter is not set, Transloadit's API assumes that the oldest, Smart-CDN-enabled Auth Key pair has been used for the signature. Setting the auth_key parameters allows you to rotate your Auth Key without interrupting your users, and we thus highly recommend setting it. For example: auth_key=23c96d084c744219a2ce156772ec3211
  3. Sort the query parameters by key in ascending order using UTF-16 code units, matching URLSearchParams.sort(). The sorting should be stable, i.e. if a key appears multiple times in the query string, the corresponding values should retain their relative ordering. For example, h=100&f=png&f=jpg&auth_key=hello&exp=123 is sorted into auth_key=hello&exp=123&f=png&f=jpg&h=100.
  4. Construct the string to sign by concatenating the values:
    [your-workspace]/[template-name]/[file-path]?[sorted-parameters]
    
    The values for [your-workspace], [template-name], and [file-path] must be URL-encoded to ensure they only contain URL-safe characters. Note that the string does not start with a leading slash. The ? character must be omitted if [sorted-parameters] is empty.
  5. Calculate an RFC 6234-compliant⁠ HMAC hex signature on the string to sign, with your Auth Secret as the key, and SHA256 as the hash algorithm. Prefix the hex signature with the algorithm name in lowercase and a colon, i.e. sha256:. For example, for SHA256, use sha256:[hmac-signature].
  6. Append the prefixed hex signature under the sig query parameter to the URL, giving the signed Smart CDN URL:
    https://[your-workspace].tlcdn.com/[template-name]/[file-path]?[parameters]&sig=sha256:[hmac-signature]
    
    The values for [your-workspace], [template-name], and [file-path] must be URL-encoded to ensure they only contain URL-safe characters. This signed URL can then be sent to or used in your front-end until the expiration date is reached.

Security and cache lifetime

Signed Smart CDN URLs are not just an access-control mechanism. Their expiration also determines how long a freshly generated result may remain cacheable.

  • Shorter exp values reduce the replay window and tighten access control.
  • Longer exp values increase cache reuse, reduce origin work, and generally lower latency and encoding volume.
  • In practice, the effective cache lifetime of a signed Smart CDN response is bounded by the remaining signature lifetime.

That means the trade-off is straightforward:

  • More security sensitivity: use a shorter exp, which also means a shorter effective cache TTL.
  • More cache reuse and lower cost: use a longer exp, which also means the URL remains usable for longer.

Choose the expiration window according to the sensitivity of the content and how much cache reuse you want. For many image and preview use cases, a moderate expiration window gives a good balance. For highly sensitive content, use a much shorter one.

Example code

Below you can find examples in different languages for generating signed Smart CDN URLs using our SDKs.

// yarn add @transloadit/node
// or
// npm install --save @transloadit/node

import { Transloadit } from '@transloadit/node'

const transloadit = new Transloadit({
  authKey: 'YOUR_TRANSLOADIT_KEY',
  authSecret: 'YOUR_TRANSLOADIT_SECRET',
})

const url = transloadit.getSignedSmartCDNUrl({
  workspace: 'YOUR_WORKSPACE',
  template: 'YOUR_TEMPLATE',
  input: 'image.png',
  urlParams: { height: 100, width: 100 },
})

console.log(url)

Read access after cancellation

Canceled Workspaces cannot create new bearer tokens. Endpoints that explicitly permit access after cancellation link to this recipe. Use an existing active Auth Key and its Auth Secret; the key must still grant the scopes listed for the endpoint. This does not restore write access or make other endpoints available after cancellation.

In a trusted server-side Node.js project, install the SDK with yarn add @transloadit/node. Set TRANSLOADIT_KEY and TRANSLOADIT_SECRET, then set TRANSLOADIT_URL to the complete HTTPS URL shown on the endpoint page, replacing any path parameters with your resource values. Keep both credentials, the signed URL and the response private. Never run this setup in browser code.

The SDK signs params with sha384, the default for new Auth Keys, and supplies the expiry. The example adds a fresh nonce to avoid signature reuse. If your key uses another signature algorithm, pass it as the second argument to calcSignature. Put any endpoint filters inside the object passed as its first argument, alongside the nonce. The SDK does not call /token for this recipe.

Save this as read-api.mjs and run node read-api.mjs:

import { randomUUID } from 'node:crypto'

import { Transloadit } from '@transloadit/node'

const { TRANSLOADIT_KEY, TRANSLOADIT_SECRET, TRANSLOADIT_URL } = process.env
if (!TRANSLOADIT_KEY || !TRANSLOADIT_SECRET || !TRANSLOADIT_URL) {
  throw new Error('Set TRANSLOADIT_KEY, TRANSLOADIT_SECRET, and TRANSLOADIT_URL')
}
const transloadit = new Transloadit({
  authKey: TRANSLOADIT_KEY,
  authSecret: TRANSLOADIT_SECRET,
})
const { params, signature } = transloadit.calcSignature({ nonce: randomUUID() })
const url = new URL(TRANSLOADIT_URL)
url.searchParams.set('params', params)
url.searchParams.set('signature', signature)
const response = await fetch(url, { redirect: 'error' })
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`)
const result = await response.json()
if (result.error) throw new Error(result.error)
console.log(JSON.stringify(result, null, 2))

Bearer tokens (client credentials)

If you need a short-lived token for server-to-server or headless clients, you can exchange your Auth Key and Auth Secret for a Bearer token. This mirrors an OAuth 2.0 client_credentials flow but is handled directly by the Transloadit API. For the full endpoint reference, see the /token API docs.

Using the token

Pass the token as Authorization: Bearer <access_token> on API requests. When a request is authenticated with a valid Bearer token, API2 treats Signature Authentication as satisfied and skips signature validation. Signature Authentication is enforced only for key/secret requests. Scope and audience checks still apply. The mcp audience is accepted by the MCP server and rejected by regular API2 endpoints. You can omit auth.key in params, but the params envelope is still required for endpoints that expect it.

curl --fail-with-body -sS --request POST \
  --url 'https://api2.transloadit.com/assemblies' \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --form 'params={"template_id":"YOUR_TEMPLATE_ID"}'

MCP auto-auth for /ai/chat

If your /ai/chat steps call a Transloadit-hosted MCP server, API2 can mint and inject a short-lived Bearer token automatically (auto-auth). This is opt-in per MCP server entry:

{
  "mcp_servers": [
    {
      "type": "http",
      "url": "https://api2.transloadit.com/mcp",
      "auth": "transloadit"
    }
  ]
}

Behavior:

  • If auth: "transloadit" is set and no Authorization header is present, API2 mints a token and injects Authorization: Bearer <token>.
  • If Authorization is already provided in mcp_servers[].headers, it is left untouched.
  • Auto-auth only works over HTTPS for Transloadit-managed apex hosts and subdomains: transloadit.com, *.transloadit.com, transloadit.dev, *.transloadit.dev, transloadit.website, *.transloadit.website, transloadit.work, *.transloadit.work.
  • The URL must use port 443 and the exact /mcp path or a subpath below /mcp/.
  • The URL must not contain credentials, a query string, or a fragment.
  • The Auth Key must grant at least one of these safe MCP scopes: assemblies:write, assemblies:read, templates:read.
  • The minted token is narrowed to the intersection of those safe MCP scopes and the Auth Key’s scopes; it never gains a scope that the Auth Key does not grant.

FAQs

Does Transloadit include signatures with its requests?

Transloadit signs Webhook requests so your server can verify their authenticity. Webhook signing is separate from the HMAC that authenticates API requests sent to Transloadit.

Why can’t I use my Auth Secret as the Bearer token?

Except for the server-to-server token exchange described above, your Auth Secret must never be transmitted to a client or included in API request parameters. POST /token sends it as the HTTP Basic password over HTTPS and must be called only from your back-end. For signed requests, the secret remains on your back-end and is used as the HMAC key. This prevents a malicious actor from intercepting a signed request and spoofing requests to your account. Keep your Auth Secret safe by using whichever secret management system you prefer. Examples are: Vault⁠, AWS Secrets Manager⁠, GCP Secret Manager⁠, and Kubernetes Secrets⁠, but there are many more that could be suitable depending on your back-end platform of choice.

Note

You should ensure that Auth Secrets are never included as part of the front-end of your application, or exposed to users.

What order do the keys in the body need to be in?

The order you choose for the keys in the body can be arbitrary, however it’s important to note that whichever order you choose needs to be consistent with your signature generation. The hash generated depends on the contents of the JSON, and a different ordering will generate a different hash, meaning your request will be denied.

Previous page ← Response codesNext page Webhooks →
Contact support⁠

TransloaditChecking status…

Product

  • Services
  • Pricing
  • Demos
  • Tools
  • Security
  • Support

Company

  • About/Press
  • Blog/Jobs
  • Comparisons/Compliance matrix
  • Research
  • Open source
  • Solutions
  • Pioneers of the web

Docs

  • Getting started
  • Transcoding
  • FAQ
  • API
  • Guides/DevTips
  • Supported formats

More

  • Platform status⁠
  • Community forum⁠
  • StackOverflow⁠
  • Uppy
  • tus⁠

© 2009–2026 Transloadit-II GmbH

PrivacyTermsImprint
EnglishDeutschEspañolPortuguês (Brasil)