Flag of Ukraine   We stand with the brave people of Ukraine. Stop the war. Find out how you can help.


The @uppy/transloadit plugin can be used to upload files to Transloadit for all kinds of processing, such as transcoding video, resizing images, zipping/unzipping, and much more.

If you’re okay to trade some flexibility for ergonomics, consider using
the Robodog Plugin instead, which is a higher-level abstraction for
encoding files with Uppy and Transloadit.

Try it live

import Transloadit from '@uppy/transloadit'

uppy.use(Transloadit, {
  service: 'https://api2.transloadit.com',
  params: null,
  waitForEncoding: false,
  waitForMetadata: false,
  importFromUploadURLs: false,
  alwaysRunAssembly: false,
  signature: null,
  fields: {},
  limit: 0,

As of Uppy version 0.24, the Transloadit plugin includes the Tus plugin to handle the uploading, so you no longer have to add it manually.


This plugin is published as the @uppy/transloadit package.

Install from NPM:

npm install @uppy/transloadit

In the CDN package, the plugin class is available on the Uppy global object:

const { Transloadit } = Uppy

Hosted Companion Service

You can use this plugin together with Transloadit’s hosted Companion service to let your users import files from third party sources across the web.
To do so each provider plugin must be configured with Transloadit’s Companion URLs:

import { COMPANION_URL, COMPANION_ALLOWED_HOSTS } from '@uppy/transloadit'
import Dropbox from '@uppy/dropbox'

uppy.use(Dropbox, {
  companionUrl: COMPANION_URL,
  companionAllowedHosts: COMPANION_ALLOWED_HOSTS,

This will already work. Transloadit’s OAuth applications are used to authenticate your users by default. Your users will be asked to provide Transloadit access to their files. Since your users are probably not aware of Transloadit, this may be confusing or decrease trust. You may also hit rate limits, because the OAuth application is shared between everyone using Transloadit.

To solve that, you can use your own OAuth keys with Transloadit’s hosted Companion servers by using Transloadit Template Credentials. Create a Template Credential on the Transloadit site. Select “Companion OAuth” for the service, and enter the key and secret for the provider you want to use. Then you can pass the name of the new credentials to that provider:

import { COMPANION_URL, COMPANION_ALLOWED_HOSTS } from '@uppy/transloadit'
import Dropbox from '@uppy/dropbox'

uppy.use(Dropbox, {
  companionUrl: COMPANION_URL,
  companionAllowedHosts: COMPANION_ALLOWED_HOSTS,
  companionKeysParams: {
    credentialsName: 'my_companion_dropbox_creds',

Static exports


The main endpoint for Transloadit’s hosted companions. You can use this constant in remote provider options, like so:

import Dropbox from '@uppy/dropbox'
import { COMPANION_URL } from '@uppy/transloadit'

uppy.use(Dropbox, {
  companionUrl: COMPANION_URL,

When using COMPANION_URL, you should also configure companionAllowedHosts: COMPANION_ALLOWED_HOSTS.

The value of this constant is https://api2.transloadit.com/companion. If you are using a custom service option, you should also set a custom host option in your provider plugins, by taking a Transloadit API url and appending /companion:

uppy.use(Dropbox, {
  companionUrl: 'https://api2-us-east-1.transloadit.com/companion',


A RegExp pattern matching Transloadit’s hosted companion endpoints. The pattern is used in remote provider companionAllowedHosts options, to make sure that third party authentication messages cannot be faked by an attacker’s page, but can only originate from Transloadit’s servers.

Use it whenever you use companionUrl: COMPANION_URL, like so:

import Dropbox from '@uppy/dropbox'
import { COMPANION_ALLOWED_HOSTS } from '@uppy/transloadit'

uppy.use(Dropbox, {
  companionAllowedHosts: COMPANION_ALLOWED_HOSTS,

The value of this constant covers all Transloadit’s Companion servers, so it does not need to be changed if you are using a custom service option. But, if you are not using the Transloadit Companion servers at *.transloadit.com, make sure to set the companionAllowedHosts option to something that matches what you do use.



A unique identifier for this plugin (string, default: 'Transloadit').


The Transloadit API URL to use (string, default: https://api2.transloadit.com).

The default will try to route traffic efficiently based on the location of your users. You could for instance set it to https://api2-us-east-1.transloadit.com if you need the traffic to stay inside a particular region.


Limit the amount of uploads going on at the same time (number, default: 5).

Setting this to 0 means no limit on concurrent uploads, but we recommend a value between 5 and 20. This option is passed through to the @uppy/tus plugin, which this plugin uses internally.


Configure the Assembly Instructions, the fields to send along to the assembly, and authentication (object | function, default: null).

The object you can pass or return from a function has this structure:

  "params": {
    "auth": { "key": "key-from-transloadit" },
    "template_id": "id-from-transloadit",
    "steps": {
      // Overruling Template at runtime
    "notify_url": "https://your-domain.com/assembly-status",
  "signature": "generated-signature",
  "fields": {
    // Dynamic or static fields to send along to the assembly
  • params is used to authenticate with Transloadit and using your desired template.
    • auth.key (required) is your authentication key which you can find on the “Credentials” page of your account.
    • template_id (required) is the unique identifier to use the right template from your account.
    • steps (optional) can be used to overrule Templates at runtime.
      A typical use case might be changing the storage path on the fly based on the session user id. For most use cases, we recommend to let your Templates handle dynamic cases (they can accept fields and execute arbitrary JavaScript as well), and not pass in steps from a browser. The template editor also has extra validations and context.
    • notify_url (optional) is a pingback with the assembly status as JSON. For instance, if you don’t want to block the user experience by letting them wait for your template to complete with waitForEncoding, but you do want to want to asynchrounously have an update, you can provide an URL which will be “pinged” with the assembly status.
  • signature (optional, but recommended) is a cryptographic signature to provide further trust in unstrusted environments. Refer to “Signature Authentication” for more information.
  • fields (optional) can be used to to send along key/value pairs, which can be used dynamically in your template.

When you go to production always make sure to set the signature.
Not using Signature Authentication can be a security risk.
Signature Authentication is a security measure that can prevent outsiders from tampering with your Assembly Instructions.
While Signature Authentication is not implemented (yet),
we recommend to enable allow_steps_override in your Templates to avoid outsiders being able to pass in any Instructions and storage targets on your behalf.

Example as a function

A custom assemblyOptions() option should return an object or a promise for an object.

uppy.use(Transloadit, {
  assemblyOptions (file) {
    return {
      params: {
        auth: { key: 'TRANSLOADIT_AUTH_KEY_HERE' },
        template_id: 'xyz',
      fields: {
        caption: file.meta.caption,

The ${fields.caption} variable will be available in the Assembly spawned from Template xyz. You can use this to dynamically watermark images for example.

assemblyOptions() may also return a Promise, so it could retrieve signed Assembly parameters from a server. For example, assuming an endpoint /transloadit-params that responds with a JSON object with { params, signature } properties:

uppy.use(Transloadit, {
  async assemblyOptions (file) {
    const res = await fetch('/transloadit-params')
    return response.json()

Example as an object

If you don’t need to change anything dynamically, you can also pass an object directly.

uppy.use(Transloadit, {
  assemblyOptions: {
    params: { auth: { key: 'transloadit-key' } },

Example with @uppy/form

Combine the assemblyOptions() option with the Form plugin to pass user input from a <form> to a Transloadit Assembly:

// This will add form field values to each file's `.meta` object:
uppy.use(Form, { getMetaFromForm: true })
uppy.use(Transloadit, {
  getAssemblyOptions (file) {
    return {
      params: { /* ... */ },
      // Pass through the fields you need:
      fields: {
        message: file.meta.message,

waitForEncoding: false

By default, the Transloadit plugin uploads files to Assemblies and then marks the files as complete in Uppy. The Assemblies will complete (or error) in the background but Uppy won’t know or care about it.

When waitForEncoding is set to true, the Transloadit plugin waits for Assemblies to complete before the files are marked as completed. This means users have to wait for a potentially long time, depending on how complicated your Assembly instructions are. But, you can receive transcoding results on the client side, and have a fully client-side experience this way.

When this is enabled, you can listen for the transloadit:result and transloadit:complete events.

waitForMetadata: false

By default, the Transloadit plugin uploads files to Assemblies and then marks the files as complete in Uppy. The Assemblies will complete (or error) in the background but Uppy won’t know or care about it.

When waitForMetadata is set to true, the Transloadit plugin waits for Transloadit’s backend to extract metadata from all the uploaded files. This is mostly handy if you want to have a quick user experience (so your users don’t necessarily need to wait for all the encoding to complete), but you do want to let users know about some types of errors that can be caught early on, like file format issues.

When this is enabled, you can listen for the transloadit:upload event.


Instead of uploading to Transloadit’s servers directly, allow another plugin to upload files, and then import those files into the Transloadit Assembly. This is set to false by default.

When enabling this option, Transloadit will not configure the Tus plugin to upload to Transloadit. Instead, a separate upload plugin must be used. Once the upload completes, the Transloadit plugin adds the uploaded file to the Assembly.

For example, to upload files to an S3 bucket and then transcode them:

uppy.use(AwsS3, {
  getUploadParameters (file) {
    return { /* upload parameters */ }
uppy.use(Transloadit, {
  importFromUploadURLs: true,
  params: {
    auth: { key: 'YOUR_API_KEY' },
    template_id: 'YOUR_TEMPLATE_ID',

For this to work, the upload plugin must assign a publically accessible uploadURL property to the uploaded file object. The Tus and S3 plugins both do this automatically. For the XHRUpload plugin, you may have to specify a custom getResponseData function.


When set to true, always create and run an Assembly when uppy.upload() is called, even if no files were selected. This allows running Assemblies that do not receive files, but instead use a robot like /s3/import to download the files from elsewhere, for example, for a bulk transcoding job.

locale: {}

export default {
  strings: {
    // Shown while Assemblies are being created for an upload.
    creatingAssembly: 'Preparing upload...',
    // Shown if an Assembly could not be created.
    creatingAssemblyFailed: 'Transloadit: Could not create Assembly',
    // Shown after uploads have succeeded, but when the Assembly is still executing.
    // This only shows if `waitForMetadata` or `waitForEncoding` was enabled.
    encoding: 'Encoding...',

Deprecated options

getAssemblyOptions, params, signature, and fields have been deprecated in favor of assemblyOptions, which we now recommend for all use cases. You can still use these options, but they will be removed in the next major version.

You can view the old docs for them here.


If an error occurs when an Assembly has already started, you can find the Assembly Status on the error object’s assembly property.

uppy.on('error', (error) => {
  if (error.assembly) {
    console.log(`Assembly ID ${error.assembly.assembly_id} failed!`)



Fired when an Assembly is created.


  • assembly - The initial Assembly Status.
  • fileIDs - The IDs of the files that will be uploaded to this Assembly.
uppy.on('transloadit:assembly-created', (assembly, fileIDs) => {
  console.group('Created', assembly.assembly_id, 'for files:')
  for (const id of fileIDs) {


Fired when Transloadit has received an upload.


  • file - The Transloadit file object that was uploaded.
  • assembly - The Assembly Status of the Assembly to which the file was uploaded.


Fired when Transloadit has received all uploads, and is executing the Assembly.



Fired when a result came in from an Assembly.


  • stepName - The name of the Assembly step that generated this result.
  • result - The result object from Transloadit.
    This result object has one more property, namely localId.
    This is the ID of the file in Uppy’s local state, and can be used with uppy.getFile(id).
  • assembly - The Assembly Status of the Assembly that generated this result.
uppy.on('transloadit:result', (stepName, result) => {
  const file = uppy.getFile(result.localId)
      <h2>From ${file.name}</h2>
      <a href=${result.ssl_url}> View </a>


Fired when an Assembly completed.


uppy.on('transloadit:complete', (assembly) => {
  // Could do something fun with this!

Assembly behavior when Uppy is closed

When integrating @uppy/transloadit with @uppy/dashboard, closing the dashboard will result in continuing assemblies on the server. When the user manually cancels the upload any running assemblies will be cancelled.