Migrate from Cloudinary to Transloadit
Cloudinary supports upload presets, transformation URLs, and an asset library. Transloadit centers processing around Assembly Instructions: explicit workflows that run Robots for uploading, importing, transforming, optimizing, storing, and serving files.
Transloadit offers hosted files through Transloadit Storage (currently in beta). Your own storage bucket is optional when using Transloadit Storage. The File Library (preview) offers digital asset management for browsing, organizing, previewing, and downloading files in Transloadit Storage. File Library access is enabled per Workspace; ask us about availability.
This guide demonstrates the bring-your-own-storage route: it migrates uploads and processing into
Templates and exports assets to your bucket. Keep your application’s asset catalog alongside that
storage. Migrating existing DAM folders and metadata, moving production delivery to Smart CDN URLs
on tlcdn.com, and replacing approval workflows, rights management, asset pickers, or CMS
integrations need their own migration plan. File Library availability does not imply one-to-one
compatibility with every Cloudinary DAM feature.
Migration map
| Cloudinary concept | Transloadit migration choice |
|---|---|
| Upload preset | Saved Template referenced by template_id |
| Transformation URL | An Assembly request, or Smart CDN with compatible Robots and a final /file/serve Step |
| Eager transformation | Run Template Steps at upload time instead of on demand |
| Image resize/crop | 🤖/image/resize; compare crops on representative assets |
| Image optimization | 🤖/image/optimize; choose formats and quality deliberately |
| Video transcode | 🤖/video/encode |
| Adaptive video | 🤖/video/adaptive or 🤖/video/ondemand |
| Asset storage | 🤖/s3/store or another export Robot, plus your asset catalog |
| Delivery URLs | Your storage/CDN URLs, or Smart CDN with a final 🤖/file/serve Step |
| Upload widget | Uppy with its Transloadit plugin; update callbacks and server signing |
| Webhooks | Assembly Notifications; rewrite event handling and signature verification |
Decisions before migrating. This table maps tasks, not interchangeable APIs. Recreate preset
validation, naming, and access rules in your backend. Cloudinary’s
automatic format and quality selection
and gravity-based cropping need output
comparisons; the fixed WebP crop below does not reproduce f_auto, q_auto, or g_auto behavior.
Inventory named transformations, overlays, AI effects, and add-ons separately and decide which to
rebuild, retain, or leave out. This guide does not provide equivalents for those effects.
Start with the workflow, not the URL
Cloudinary transformation URLs encode processing parameters in the delivery path. In Transloadit, put the required processing Steps into a Template and call it from your app. Keep Template definitions in version control alongside your application code and regression assets.
For example, this Template produces a fixed 1600 × 900 WebP crop and optimizes that output. Compare its appearance and file size with the Cloudinary rendition you are replacing:
{
"steps": {
":original": {
"robot": "/upload/handle"
},
"hero": {
"use": ":original",
"robot": "/image/resize",
"width": 1600,
"height": 900,
"resize_strategy": "fillcrop",
"format": "webp"
},
"optimized": {
"use": "hero",
"robot": "/image/optimize",
"result": true
},
"exported": {
"use": "optimized",
"robot": "/s3/store",
"credentials": "YOUR_AWS_CREDENTIALS",
"path": "media/${unique_prefix}/${file.url_name}",
"url_prefix": "https://cdn.example.com/",
"acl": "bucket-default"
}
}
}
Replace YOUR_AWS_CREDENTIALS with saved Third-party Credentials.
This example assumes your CDN serves the bucket root and has permission to read its objects;
url_prefix only changes returned URLs, not CDN configuration or access permissions.
acl: "bucket-default" sends no object ACL; configure access through
your bucket policy and CDN origin access.
Your backend creates a signed Assembly request with the saved template_id and a notify_url for
Assembly Notifications. Verify the notification signature and require
ASSEMBLY_COMPLETED before switching application records. In this example, read the exported files
from results.optimized: the storage Step updates the producing Step’s URLs. Persist only results
with is_temp_url: false; temporary Transloadit URLs expire after 24 hours and are not delivery URLs. See
saving conversion results.
Replace dynamic image URLs
If your app relies on dynamic transformation URLs, there are two common migration paths:
- Use a Template per transformation family, then trigger an Assembly when the asset is created or changed.
- Use Smart CDN with signed URLs for on-demand transformations that should be cached at the edge.
For high-traffic pages, prefer generating and storing canonical variants up front. For very large asset libraries with long-tail access patterns, Smart CDN can reduce pre-processing work.
Smart CDN needs a separate Template made only of compatible Robots, with a response branch ending
in /file/serve. For example, import an image, resize it, and serve that output. /video/encode and
/video/adaptive are not Smart CDN-compatible; generate signed Smart CDN URLs on your backend.
Replace delivery references. Keep a mapping from each original and used rendition URL to its
verified destination, including references in database records, srcset, CSS, email templates, and
CMS content. Cloudinary delivery URLs
encode the cloud name, resource and delivery types, and public ID, with optional transformation and
version components; changing only the hostname cannot translate those paths. Replace embedded
res.cloudinary.com references in your application. Put redirects on an application route or media
hostname you control, preserve
authorization for restricted media, and retain the source service while old links still need it.
Import existing Cloudinary assets
Build the inventory first. Use Cloudinary’s
Admin API to list the resource types and delivery
types your account uses, follow next_cursor through every page, and request tags, context, and
metadata explicitly. If you restrict the response with fields, include those fields there too.
Respect the account’s Admin API rate limit. Record asset_id, public_id, type, version, source URL,
byte size, and the destination mapping in your own manifest. Include application-only asset records
that the Cloudinary inventory cannot supply.
Preserve organization separately. Downloading a file does not transfer its asset catalog:
| Information | Preservation decision |
|---|---|
| Tags, contextual and structured metadata | Store values in your database or sidecar files, retaining structured field definitions, types, and validation rules |
| Folders and display names | Preserve asset_folder, display name, and public ID separately in dynamic folder mode; folder moves do not change delivery URLs. In fixed folder mode, the public ID carries the folder path |
| Collections | Preserve manually selected membership or dynamic collection filter rules, plus sharing decisions; a storage path alone cannot represent them |
| Versions and backups | Decide whether to copy only the current file or retained history. List backed-up versions and download selected versions separately; earlier files are not recoverable through backup if backup was never enabled |
Rebuild catalog relationships and permissions in your application. The import Template below copies the selected binary and a thumbnail; it does not create a hosted DAM catalog or migrate metadata, collections, or version history. A delivery URL’s version component controls CDN cache refresh; use the backup download mechanism to export retained earlier files.
If the selected media is available through an authorized HTTPS URL, use 🤖/http/import instead of uploading it again:
{
"steps": {
"imported": {
"robot": "/http/import",
"url": "${fields.cloudinary_url}"
},
"thumbnail": {
"use": "imported",
"robot": "/image/resize",
"width": 400,
"height": 400,
"resize_strategy": "fillcrop",
"result": true
},
"exported": {
"use": ["imported", "thumbnail"],
"robot": "/s3/store",
"credentials": "YOUR_AWS_CREDENTIALS",
"path": "cloudinary-import/${unique_prefix}/${file.url_name}",
"acl": "bucket-default"
}
}
}
Pass an authorized source URL as the Assembly field cloudinary_url, selected by your backend from
your asset inventory. A
transformed Cloudinary URL imports
that rendition; select the original deliberately when you need it. For
restricted assets, generate the
appropriate authorized download on your backend and allow enough time for the import. Keep the old
asset ID and URL until the completed export is accessible through your intended delivery path and
its dimensions and quality meet your requirements. This import Template returns exported files
under results.imported and results.thumbnail. A private S3 object still needs an authorized
download or your configured CDN.
Upload widget and automation. Replace the Cloudinary Upload widget with Uppy and follow the server-signed integration guide. Update callbacks to persist verified Assembly results. A Cloudinary Media Library picker selects existing DAM assets; replacing that picker and its CMS integration requires a separate asset browser and catalog, beyond replacing the upload UI.
Cloudinary’s notifications cover multiple asset events, including separate eager-transformation notifications. Map processing completion to Assembly Notifications and handle rename, delete, catalog, and moderation events in your application. Rewrite signature verification for Transloadit’s notification format, acknowledge only after durable handling, and deduplicate updates by Assembly ID. Test failures and retry handling using the Webhooks API documentation, and record failed imports in the manifest before replaying them.
Security decisions. Cloudinary supports signed and unsigned uploads; the signature scheme is not interchangeable with Transloadit authentication. Authorize users and sign only allowed Templates and fields on your backend. Treat delivery access separately: Cloudinary’s private delivery type protects originals but allows derived assets by default, while its authenticated type protects both. Recreate the intended policy in your bucket and CDN; a signed upload or signed processing URL is not an ACL for an exported object.
If you use Cloudinary’s Perception Point malware detection add-on, plan scanning and quarantine before public delivery in the replacement pipeline. Neither example here enables malware scanning or content moderation. This guide does not configure a quarantine system, content-moderation policy, DRM, or a complete access-control implementation.
Agents and repeatable execution. Cloudinary’s agent tools and MCP servers expose asset, transformation, analysis, and environment operations to AI clients. Inventory any agents that call those tools as application dependencies. Have agents propose versioned Template Instructions, then review and execute the saved workflow with bounded inputs and output variants. Keep Assembly IDs, failure reasons, and destination mappings for support and replay; adding an agent does not migrate the asset catalog or guarantee identical pixels. This guide does not port individual MCP tools or agent integrations.
Checklist
Effort estimate. As a planning allowance, reserve several engineering days for one upload path, a few fixed transformations, and public delivery, followed by backfill time. A DAM-heavy application with history, custom effects, restricted delivery, and CMS integrations can require weeks or more. These are estimates, not measured migration benchmarks. Measure a representative batch to estimate transfer time and processing cost; include source download charges, destination storage/CDN costs, and a period of overlap. A hosted DAM replacement needs a separate estimate.
- Inventory assets, metadata, used transformations, widget/picker integrations, and authorization rules.
- Create versioned Templates and Third-party Credentials; compare representative outputs.
- Define bounded batch sizes, concurrency, retry limits, and a migration budget. Confirm execution region, storage region, retention, and compliance requirements with your team before moving data.
- Run a small pilot; verify completion, durable URLs, dimensions, file sizes, metadata mappings, private access, and error recovery.
- Switch new uploads behind a feature flag and backfill existing assets in bounded batches. Record every success and failure so retries do not create untracked duplicate assets.
- Replace delivery references or add redirects on infrastructure you control; test real pages, email links, and cached content.
- Keep the Cloudinary identifiers and delivery path for rollback until the agreed overlap period ends and the inventory reconciles. Decommission only after resolving missing assets and old links.