Flag of Ukraine

My first App

As indicated in What we offer, Transloadit is versatile and there are many ways to leverage our API. To pick one happy path for demo purposes, we'll default to a web browser integration with Uppy's Robodog Plugin.

We will create a simple web page where the following happens:

  1. You can upload a photo (handled by Transloadit via the /upload/handle Robot).
  2. Transloadit will then automatically detect a face and crop the photo accordingly (via the /image/facedetect Robot).
  3. The result is stored in your S3 bucket (via the /s3/store Robot).

Let's look at the Assembly Instructions to accomplish this. We'll see three Steps that we named: :original, faces_detected, and exported:

  ":original": {
    "robot": "/upload/handle"
  "faces_detected": {
    "use": ":original",
    "robot": "/image/facedetect",
    "crop": true,
    "faces": "max-confidence",
    "format": "preserve",
    "crop_padding": "10%"
  "exported": {
    "use": [
    "robot": "/s3/store",
    "credentials": "YOUR_AWS_CREDENTIALS",
    "url_prefix": "https://demos.transloadit.com/"

Note: The credentials to S3 are stored separately for security purposes. You can read more about this in the Template Credentials docs. You refer to them by name, replacing YOUR_S3_CREDENTIALS.

Now, let's take a closer look at those three Steps:

  1. :original invokes the /upload/handle Robot, which will receive any file Uppy throws at it, and then make it available for other Robots to consume.
  2. faces_detected is happy to take those files off :original's hands. It explicitly says "use": ":original" to indicate that. It also lists "robot": "/image/facedetect" to invoke face detection, along with some parameters that are specific to the /image/facedetect Robot, such as crop.
  3. exported takes files emitted by both :original and faces_detected, and then invokes the /s3/store robot to export them to an S3 bucket. This way, we'll have saved both the original upload, and the cropped face, to S3.

If you don't have an S3 bucket (or any other supported export target), you could create one or leave out the exported Step for now. Our prototype will still work, but result files are then hosted with us and removed after 24h.

We save these JSON Instructions in a Template in the Template Editor in your account. That way, we can get a Template ID, which we can then refer to in our Uppy integration (currently indicated by YOUR_TEMPLATE_ID). We'll add this to any HTML page that is accessible in your browser, which could be just a local test.html for now:

<!-- This pulls Uppy from our CDN. Alternatively use `npm i @uppy/robodog --save` -->
<!-- if you want smaller self-hosted bundles and/or to use modern JavaScript -->
<link href="//releases.transloadit.com/uppy/robodog/v2.9.1/robodog.min.css" rel="stylesheet">
<script src="//releases.transloadit.com/uppy/robodog/v2.9.1/robodog.min.js"></script>
<button id="browse">Select Files</button>
  document.getElementById('browse').addEventListener('click', function () {
    var uppy = window.Robodog.pick({
      providers: [ 'instagram', 'url', 'webcam', 'dropbox', 'google-drive', 'facebook', 'onedrive' ],
      waitForEncoding: true,
      params: {
        // To avoid tampering, use Signature Authentication
        auth: { key: 'YOUR_TRANSLOADIT_KEY' },
        template_id: 'YOUR_TEMPLATE_ID'
    }).then(function (bundle) {
      // Due to `waitForEncoding: true` this is fired after encoding is done.
      // Alternatively, set `waitForEncoding` to `false` and provide a `notify_url`
      // for Async Mode where your back-end receives the encoding results
      // so that your user can be on their way as soon as the upload completes.
      console.log(bundle.transloadit) // Array of Assembly Statuses
      console.log(bundle.results)     // Array of all encoding results

You'll notice that along with YOUR_TEMPLATE_ID, we'll also need to replace YOUR_TRANSLOADIT_KEY, the value for which can be obtained from the API Settings in your Account.

And there you have it! ✨ If you were copy/pasting/replacing along, you now have a working prototype. The results are dumped in your browser's console log, but you can also see Assemblies added to your account in real time. If you didn't type along, you can still try it live in this face detect demo.

We're not quite there yet, though. The results are now safely in your S3 bucket, with references in the browser's console log, but how do we get those results to your back-end so that others can enjoy them too?

20% off any plan for the Uppy community
Use the UPPY20 code when upgrading.
Sign up
20% off any plan for the tus community
Use the TUS20 code when upgrading.
Sign up
Product Hunt
20% off any plan for Product Hunters
Use the PRH20 code when upgrading.
Sign up