Migration guide

Migrate from Cloudinary to FileSpin

Move to FileSpin and keep your Cloudinary image URLs working. Change the hostname, and your public image paths and supported transformations carry on while your library copies across, on first request or in bulk.

The setup follows the same sequence for both approaches: connect Cloudinary, verify ownership, choose how to copy your images, test your URLs, then switch the delivery hostname.


Choose who carries out the migration

Assisted migration: we provide the necessary tools to migrate assets from on-premise and cloud storage while your technical team runs the migration, including the mapped metadata import and relationships.

Managed migration: the FileSpin team carries out the migration: source extraction or export coordination, field mapping, import, validation and cutover support.

Native URL migration, below, moves your public images; assisted or managed migration covers the rest of the library.

1. Scope and prerequisites

This guide covers Cloudinary public image delivery using /image/upload/, eligible original image files, and translation of supported image transformations.

This route serves public /image/upload/ images. Video, raw files, fetched images, and private and authenticated assets move in the planned migration, alongside your metadata, versions, uploads and automation, and are checked before traffic switches.

Have these ready:

  • A FileSpin administrator account.
  • Your Cloudinary delivery base URL, including the cloud name: https://res.cloudinary.com/your-cloud-name. Cloudinary accounts on their own delivery domain are supported on the Custom and Enterprise plans.
  • Your Cloudinary API key and API secret for connection testing, credential-based ownership verification and library listing.
  • A representative set of image URLs and access to their originals.
  • Access to the application settings or stored image URLs where you can replace res.cloudinary.com with cdn.filespin.io.
  • A migration window, with a named owner for monitoring and recovery.

Your Cloudinary API key and secret connect the source, verify ownership and list the library; private and authenticated images move in the planned migration.

Keep Cloudinary available throughout testing and while FileSpin still needs to fetch uncopied images.

2. How migration works

Migrate images from Cloudinary to FileSpin

Connect your Cloudinary source, verify ownership, check your image URLs, then copy images on first request or in bulk before switching traffic. The recording shows a test hostname; your account uses cdn.filespin.io.

FileSpin reads the Cloudinary-style URL, identifies your verified account and translates supported transformation parameters. A source-path mapping connects the old public ID to its FileSpin asset.

  1. Receive the requested image path.
  2. Resolve the verified account and translate supported parameters.
  3. Deliver from the ready FileSpin asset, or fetch the source rendition while the original copies.
  4. Reconcile the copied original and test later FileSpin-rendered output.

A first response can therefore come from Cloudinary through FileSpin while the original is being copied. Later requests use the FileSpin asset when it is ready.


ApproachWhen images are copiedGood fitBefore cutover
Lazy migrationWhen images are copied: When an image is requested and its original is missing from FileSpinGood fit: A gradual move while Cloudinary remains availableBefore cutover: Bulk-copy required images that get no traffic, and check the first and later responses
Bulk migrationWhen images are copied: A selected set is copied before, or alongside, delivery changesGood fit: Storefronts and other workloads that need the required library ready before cutoverBefore cutover: Reconcile the copy report and check output before switching

You can combine them: bulk-copy your live catalogue, then leave lazy fetching enabled temporarily for eligible images missed by that selection. Bulk copying gets the selected images ready in FileSpin before you switch delivery.

Cloudinary to FileSpin migration in two lanes: native image transfer (connect the source, check real URLs, copy images, test the results) and a separately scoped library and integrations migration (agree the scope, map metadata, import and validate, reconnect systems), meeting at the traffic switch
Native transfer moves your public images; the library, private media and integrations move in the planned migration and are checked before traffic switches.

3. Inventory your Cloudinary setup

Collect enough examples to represent your application, including seasonal images and low-traffic pages.


CollectIncludeWhy it matters
Images and identifiersInclude: Public IDs, folders, formats, dimensions and a full required-asset listWhy it matters: Reconcile what must be copied
Delivery URLsInclude: Product cards, detail pages, banners, feeds, emails and srcset variantsWhy it matters: Test what users actually request
TransformationsInclude: Fit/fill, quality, formats, gravity, rotation, chains, named transforms and overlaysWhy it matters: Identify compatible paths and exceptions
Images needing separate handlingInclude: Private/authenticated images and URLs with signing or access restrictionsWhy it matters: Keep unsupported private assets outside this migration; check protection separately for signed public-image URLs
Image URL referencesInclude: Generated URLs, base-host settings and stored references using res.cloudinary.comWhy it matters: Identify where to replace the hostname with cdn.filespin.io
Library dataInclude: Tags, custom metadata, versions, relationships and permissions you need to retainWhy it matters: Exported through the Admin API in the planned migration; the image copy records each source path

Before configuring, public images are separated from assets on another route, and each exception has an owner. Replacements made in Cloudinary after an image is copied come across in the final sync.

4. Configure FileSpin and choose a migration method

Connect your Cloudinary account

  1. In FileSpin’s left navigation, open Configure → Migrate to FileSpin. On a new setup, choose Cloudinary. An account can migrate from one provider at a time.
  2. Under Your old provider, enter Your images are at. Copy only the base URL through the cloud name. For example, from https://res.cloudinary.com/acme/image/upload/w_300/products/shoe.jpg, enter https://res.cloudinary.com/acme.
  3. Enter the Cloudinary API key and API secret in their respective fields.
  4. Click Test connection. Check that the connection succeeds and any returned sample paths belong to the intended cloud. Testing typed credentials does not save them.
  5. Click Save. Saving supplied credentials also runs a connection check. Verify that the source is saved and connected.

Expected result: the Cloudinary source is connected. If testing fails, check the cloud name and the credentials together. If saving reports that the identifier is already claimed, resolve that account association with FileSpin before continuing.

Cloudinary selected with its delivery base URL in the Your old provider section

The Your old provider section with the Cloudinary delivery base URL.

Verify ownership

Under Serving your old URLs, check Ownership. A successful credential check may already show Verified. If it still shows Not verified, choose Verify now and wait for verification of the same cloud name used in your URLs.

Expected result: Ownership shows Verified beside the same cloud name used in your image URLs. Continue with the saved API credentials; no verification-file upload is needed for this walkthrough.

Option A: migrate as images are requested

  1. Turn on Fetch missing images from your old provider.
  2. Note the hostname in Point your images here: cdn.filespin.io.
  3. Make a test URL by changing the hostname of one supported Cloudinary image URL, keeping the cloud name and the rest of its path intact.
  4. Request the image, then verify that its original becomes ready in FileSpin and that a later FileSpin-rendered response meets your requirements.
  5. Complete the checks in sections 5–7 before switching live traffic.

Expected result: a missing eligible image is served through the origin-fetch path, copied in the background, and subsequently delivered from FileSpin. Keep fetching enabled and Cloudinary available until you have reconciled all required images.

Lazy migration only copies images that are requested.

Verified ownership, enabled missing-image fetching, and the FileSpin delivery hostname

Serving your old URLs: ownership verified, missing-image fetching on and the cdn.filespin.io hostname.

Option B: copy your library before switching

Open Copy library… under Getting your images across. Choose the scope that matches your migration:


What to copyWhat to enterUse it for
EverythingWhat to enter: No additional selectionUse it for: All eligible images returned by the source listing
One folderWhat to enter: The source folder or prefixUse it for: A product range or staged migration; the preview shows the images included
Whatever I tagged at my providerWhat to enter: A Cloudinary tagUse it for: A set you have already marked for migration
A list of paths I haveWhat to enter: One image per line, or upload .txt/.csvUse it for: An exact asset selection from a CMS, PIM or inventory

Enter each image’s Cloudinary public ID, one per line. Include any folder that is part of the public ID, but leave out the hostname, cloud name, /image/upload/, transformation settings and version segment. For example, this delivery URL:

https://res.cloudinary.com/acme/image/upload/w_300/v1234567890/products/shoe.jpg
https://res.cloudinary.com/acme/image/upload/w_300/v1234567890/products/shoe.jpg
https://res.cloudinary.com/acme/image/upload/w_300/v1234567890/products/shoe.jpg

uses the public ID products/shoe. A path list could be:

products/shoe
products/summer/hat
banners/hero
products/shoe
products/summer/hat
banners/hero
products/shoe
products/summer/hat
banners/hero

Use the public ID shown in Cloudinary, rather than inferring it from the Media Library’s display folder: in dynamic-folder setups these can differ. The usual image public ID has no file extension; retain an extension only if it is genuinely part of that public ID. FileSpin combines the supplied ID with your configured Cloudinary source to fetch the original. Full delivery URLs are also accepted by the current importer, but are not required.

Use the dialog’s Example .txt or Example .csv to match the supported file shape. A CSV can use a path column. Preview a small sample on your deployment before submitting a large export.

Expand More options:

  • Stop after: set a positive limit for a small trial; leave it empty for the complete matching selection.
  • Leave some folders out: enter one exclusion per line. archive/** excludes descendants as well; drafts/* matches direct children only.
  • Retry images that failed before: enable after fixing the reason those images could not be processed.
Copy your library dialog showing Everything, a copy limit, folder exclusions, retry, and preview controls

Then:

  1. Select Preview first. It lists the matching images and the reasons for any exclusions, without copying them.
  2. Check the selection against your inventory. Correct the folder, tag, paths, limit or exclusions if necessary.
  3. Select Start copying when the intended selection is ready.
  4. Wait for the run to finish, then review Found, Copied, Already here, Skipped, Failed and Cannot be used.
  5. Reconcile the required paths against the destination. Resolve missing or unusable images before cutover.

Closing the dialog does not stop a running copy; use Stop to cancel it. A later run skips images already copied, and replaced originals come across in the final sync.

5. Check URLs and transformation compatibility

What changes in the URL

Replace res.cloudinary.com with cdn.filespin.io, retaining the cloud name, transformation segment and asset path:

Before
https://res.cloudinary.com/acme/image/upload/w_300,h_300,c_fill/products/shoe.jpg

After
https://cdn.filespin.io/acme/image/upload/w_300,h_300,c_fill/products/shoe.jpg
Before
https://res.cloudinary.com/acme/image/upload/w_300,h_300,c_fill/products/shoe.jpg

After
https://cdn.filespin.io/acme/image/upload/w_300,h_300,c_fill/products/shoe.jpg
Before
https://res.cloudinary.com/acme/image/upload/w_300,h_300,c_fill/products/shoe.jpg

After
https://cdn.filespin.io/acme/image/upload/w_300,h_300,c_fill/products/shoe.jpg

acme and the asset path stand for your verified cloud and image. Supported syntax stays as it is; the URL check and output tests confirm each pattern.

Make this change in your application’s generated URLs, base-host setting or stored image references. The supported migration path is a hostname replacement with cdn.filespin.io.

Cloudinary’s URL structure includes transformation, version and public-ID components. FileSpin accepts version segments in the path and looks images up by public ID. Revision history moves in the planned migration.

Run the safety check

  1. Open Check URLs….
  2. Paste one full delivery URL per line, or upload .txt/.csv using the provided example format.
  3. Select Check … URLs.
  4. Review Parameters translated, Slightly different, Will not work and Unreadable. Download the full CSV report and assign any exceptions.
URL checker classifies three Cloudinary URLs as Parameters translated and explains that rendering and access are not checked

Compatibility matrix

Supported public image paths include common resize, fit/fill/pad, quality and format operations. Some quality, gravity and chained operations translate with slightly different results, and layers, named transformations and conditionals need their own FileSpin output. The URL check sorts each pattern, and the output tests in section 6 confirm the rendering.

The public image path and Cloudinary public ID are preserved for lookup. Version segments are ignored for lookup, and Cloudinary signatures are not validated as access controls. Private/authenticated images and other resource/delivery types remain outside this route, as described in section 1.

For delivered responses, inspect X-FileSpin-Compat-Dialect and X-FileSpin-Asset-Id. X-FileSpin-Compat-Served-By: origin-proxy identifies an origin-served response when present. X-FileSpin-Compat-Dropped and X-FileSpin-Compat-Unsupported show any dropped or unsupported parameters.

6. Test in parallel

Keep live Cloudinary delivery running while you test the FileSpin endpoint. Include a small untouched test image for the first-request path and an already copied image for destination rendering.

For each case, record the original URL, FileSpin URL, date/environment, HTTP status, content type, dimensions, bytes, serving headers and visual/access verdict. Save the records using the test record fields listed above.


TestAcceptance criterion
Original without transformsCorrect asset resolves; the stored original matches the source where byte comparison is applicable
First request and later deliveryOrigin retrieval succeeds when needed; the original becomes ready; FileSpin’s rendition passes
Required sizes and formatsDimensions, crop, transparency, animation and format meet the application’s requirements
Missing imageIntended not-found behavior; no assumption that an unsupported fallback transform will supply a placeholder
Access protectionUnauthorized, expired and altered-signature requests fail where protection is required
ReplacementA controlled source update reaches the destination through an agreed update/import procedure and cache refresh
Real page integrationProduct pages, CSS backgrounds, srcset, feeds and image-loader allowlists use the correct endpoint
Recovery rehearsalReverting the planned host/base-URL change restores delivery for the test slice

A practical response check, after replacing the illustrative cloud and path:

curl --fail-with-body --silent --show-error \
  --dump-header filespin-headers.txt \
  --output filespin-image.jpg \
  'https://cdn.filespin.io/acme/image/upload/w_300/products/shoe.jpg'
curl --fail-with-body --silent --show-error \
  --dump-header filespin-headers.txt \
  --output filespin-image.jpg \
  'https://cdn.filespin.io/acme/image/upload/w_300/products/shoe.jpg'
curl --fail-with-body --silent --show-error \
  --dump-header filespin-headers.txt \
  --output filespin-image.jpg \
  'https://cdn.filespin.io/acme/image/upload/w_300/products/shoe.jpg'

Check the saved image as well as the headers, so the response is the FileSpin rendition your layout expects.

Cutover criteria: required cases pass; exceptions have a working route; required bulk copies are ready; monitoring is available; and recovery has been rehearsed.

7. Switch delivery and prepare recovery

Replace the Cloudinary hostname in your application

  1. Preserve the current Cloudinary base-host configuration and deployment so it can be restored.
  2. Change the image hostname to cdn.filespin.io for a small approved set of pages or traffic. Preserve the cloud-name path.
  3. Update image-loader/CDN allowlists, Content Security Policy and other integration settings that restrict image hosts.
  4. Confirm in browser requests and FileSpin delivery evidence that the selected pages use the target endpoint. Check several sizes and a copied asset’s response headers.
  5. Monitor errors, latency, missing-image retrieval, copy failures and visual regressions. Expand only after the selected slice meets your acceptance criteria.

Recovery

If delivery or required outputs fail, restore the previous application image hostname for the affected slice. Keep both services operating until the reverted application configuration has reached users and delivery has been checked.

Recheck real pages and access rules after reversal. Preserve the migration setup, reports and copied assets while investigating. Clear this set-up removes the identifiers used to resolve old paths; it is not a rollback control for live compatibility URLs.

Routing reversal does not copy new FileSpin uploads back to Cloudinary or reverse writes. Keep the libraries aligned during overlap, or explicitly handle images created after cutover before reverting their delivery.

8. Move uploads and remaining library data

Changing delivery does not change where your application uploads new files. If your application still sends new images or replacements to Cloudinary, those images continue to depend on Cloudinary. This stage is needed when moving those uploads too; it is not required just to test delivery of existing images. Identify the upload code or widget, saved upload settings, image-replacement jobs and processing notifications that need to move. Use FileSpin’s asset lifecycle guide for the upload and processing integration, then test a complete sequence: upload → process → store the returned asset ID → render → receive and handle the callback.

New FileSpin uploads get FileSpin IDs and URLs; existing Cloudinary paths keep resolving through the migration set-up.


Data or integrationHow it moves
Required originals not reached by lazy migrationUse a reconciled bulk selection or explicit path list
Tags and structured metadataExported with each asset and mapped to FileSpin fields; tag selection chooses images, and the tags move with the metadata export
Versions and relationshipsThe versions you keep come from Cloudinary backup; relationships are rebuilt from the manifest
Permissions and private assetsConfigure and test destination access controls before making assets reachable
Webhooks, presets and automationRecreate the intended behavior and test retries and failure handling
Copies in PIM, CMS and marketplacesUpdate and verify each destination’s own ingestion or refresh mechanism

Each copied asset records its source system and Cloudinary path, which the reconciliation uses.

Export the library data alongside the files

  1. The Admin API lists every required resource and delivery type, up to 500 per page with next_cursor; tags, context and structured metadata are requested explicitly. API secrets stay in server-side configuration.
  2. Save immutable asset IDs, public IDs, folder values, resource type, delivery type and original retrieval references in a manifest. Keep display folders separate from public-ID paths.
  3. Request tags, contextual metadata and structured metadata values. Export field definitions, types, options and validation rules separately; map these to FileSpin presets or Enterprise custom schemas.
  4. Originals are retrieved with authorised access. Cloudinary backup is off by default; where it is on, the versions you keep download with download_backup, each stored with its version ID.
  5. Collections are rebuilt as FileSpin collections from a recorded list, and permissions and approval workflows are set up in FileSpin.
  6. The export paces itself to Cloudinary’s Admin API hourly limit (500 an hour on Free, from 2,000 on paid plans), reads the reset header after an HTTP 420, and resumes from the manifest.
  7. Reconcile file counts, byte sizes and available checksums. Join imported asset IDs back to the source manifest, then validate metadata types, values and relationships.
  8. Take a final inventory of new or changed assets before switching writes. Import that delta, test replacement behaviour and retain the source until the acceptance checklist passes. Cloudinary’s notifications for uploads, deletes, renames and tag, context and metadata changes show what changed.
An illustrative Cloudinary record (asset ID, public ID, type, tags, structured metadata and display folder) mapped to a FileSpin record in the E-Commerce schema with SKU 31077 and season SS27, and the folder recreated as a collection
Illustrative mapping: the Cloudinary record is a synthetic example; the FileSpin record is the imported FileSpin asset.

9. Verify completion

Use the readiness counters under Getting your images across. Images here counts copies present; Ready to serve is the relevant readiness signal. Investigate Still processing and Cannot be used, and download the unusable-image list when available.

Migration readiness shows 452 images present, 450 ready, and two unusable images with a CSV report button

Readiness counters: images present, ready to serve, and the unusable-image report.

Before retiring Cloudinary:

  • [ ] Every required source path is accounted for in FileSpin or an explicitly retained route.
  • [ ] Required images are ready, and visual/output checks have passed.
  • [ ] New uploads, replacements and callbacks work through the intended destination integrations.
  • [ ] Metadata, permissions and retained history pass their checks.
  • [ ] Origin-fetch activity has been reviewed across a representative period, including low-traffic assets from the inventory.
  • [ ] Missing-image fetching can be turned off without breaking the required test set, after cache/configuration propagation is checked.
  • [ ] Application logs, scheduled jobs, feeds and integrations show no remaining required Cloudinary dependency.
  • [ ] Parallel storage/delivery charges, retention needs and recovery requirements have been reviewed by their owners.
  • [ ] A content owner finds the selected assets by business fields and completes a review.
  • [ ] A test campaign link and a share download appear in Delivery Insights and Share analytics.

Inventory reconciliation accounts for images nobody requested, which the origin log can’t show.

FileSpin Overview showing users, assets, collections, shares and total storage used
FileSpin Overview: compare asset and collection counts with the source inventory.
FileSpin AI Usage account ledger listing credit grants and debits with amount, running balance and operation source
AI Usage ledger: credits used by each agent run, for the budget check.
Reconciliation report for four synthetic Cloudinary assets: source asset IDs beside FileSpin asset IDs, file, metadata and collection checks, and one exception where tags were missing after the image copy
Reconciliation report with synthetic source records: one row per source asset, its FileSpin ID and checks, and the exception resolved before sign-off.

Cloudinary migration questions

Do our Cloudinary URLs keep working?
Yes, for public image URLs. Replace res.cloudinary.com with cdn.filespin.io and your /image/upload/ URLs keep working, with the cloud name, public IDs and supported transformations carrying across while your library copies over, on first request or in bulk. Cloudinary accounts on their own delivery domain are supported on the Custom and Enterprise plans. Signed, private and authenticated URLs, video, raw files and fetched images move in the planned migration and are checked before you switch traffic.
Can we keep working in Cloudinary during the migration?
Yes. Cloudinary keeps serving your pages and your team keeps uploading while FileSpin copies your images, and any image not yet copied is fetched from Cloudinary the first time it’s requested. Cloudinary’s notifications for uploads, deletes, renames and tag, context and metadata changes show what changed, and the final sync brings new and replaced images across before uploads move to FileSpin.
Do metadata, folders and versions come across?
Yes. The planned migration exports each asset through Cloudinary’s Admin API with its tags, contextual and structured metadata, and the field definitions map to FileSpin schemas (industry presets on any plan; custom schema authoring is an Enterprise capability). Folders and public IDs stay together in the manifest, so your team finds images by folder and old URLs still resolve, and collections are rebuilt as FileSpin collections. Where Cloudinary backup is on, the versions you keep come across with their version IDs.
Do we need to run the migration ourselves?
No. In a managed migration, the FileSpin team carries out the transfer. In an assisted migration, we provide the tools and your technical team runs it. Either way, you provide a Cloudinary API key and secret for your product environment, plus read access to your backup bucket if Cloudinary backs up there.

10. Troubleshooting and next steps


SymptomEstablished cause or likely checkAction
Connection test failsEstablished cause or likely check: Wrong cloud/credential combination or source API accessAction: Recheck the base URL and credentials; rerun the test
Compatibility URL returns 404Established cause or likely check: Unverified/wrong identifier, missing source, fetching disabled, or unsupported delivery typeAction: Check ownership, cloud-name path, source URL and media scope
Image appears initially but cannot later be usedEstablished cause or likely check: Original copy/processing can fail after an origin responseAction: Review readiness and the failure report; resolve the source format or processing cause
Crop, quality or dimensions differEstablished cause or likely check: Approximated parameters or operation orderingAction: Compare warm output; rework the transformation or pre-render the required result
Protected URL opens without accessEstablished cause or likely check: Cloudinary signatures are not validated by the translatorAction: Keep that asset off the cutover route until destination access controls pass negative tests
Cloudinary replacement is not reflectedEstablished cause or likely check: Existing copy/alias and cached rendition remainAction: Use a verified destination replacement and purge procedure; a version-path change alone is insufficient
Bulk scope is incompleteEstablished cause or likely check: Exclusions, copy limit, folder/tag selection, unsupported types or failuresAction: Reconcile paths and preview the corrected selection
CSV selection behaves unexpectedlyEstablished cause or likely check: File shape or importer behaviorAction: Compare the file with Example .csv, preview a small sample and contact support if it still fails; a checked plain-text public-ID list is an alternative
URL checker is green but image is wrong or missingEstablished cause or likely check: Syntax classification does not test rendering, existence or accessAction: Fetch and inspect the actual FileSpin output

For migration questions, contact FileSpin support and include the environment, failing URL, expected behavior and relevant report/header details. Never send API secrets in screenshots or delivery URLs.

Plan your Cloudinary migration with FileSpin. Tell us the size of your library, the URLs and integrations it feeds and the history you need, and we’ll scope the native transfer with an assisted or managed migration.