<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Eitan Peer</title>
    <description>The latest articles on DEV Community by Eitan Peer (@eitan_peer_174abe7b78358d).</description>
    <link>https://dev.to/eitan_peer_174abe7b78358d</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3987474%2F3405706f-8446-4464-a893-518cb9986292.png</url>
      <title>DEV Community: Eitan Peer</title>
      <link>https://dev.to/eitan_peer_174abe7b78358d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eitan_peer_174abe7b78358d"/>
    <language>en</language>
    <item>
      <title>Automate Cloudinary Image-to-Video Workflows with n8n</title>
      <dc:creator>Eitan Peer</dc:creator>
      <pubDate>Wed, 26 Aug 2026 18:44:16 +0000</pubDate>
      <link>https://dev.to/cloudinary/automate-cloudinary-image-to-video-workflows-with-n8n-36jb</link>
      <guid>https://dev.to/cloudinary/automate-cloudinary-image-to-video-workflows-with-n8n-36jb</guid>
      <description>&lt;p&gt;This n8n workflow automates Cloudinary image-to-video generation from a tagged source image and a prompt. It gives media teams a repeatable no-code process that creates, tracks, and stores the finished video beside its source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The upload:&lt;/strong&gt; a 728×546 WebP, 26 KB.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8bgnay8wgohrfxr55tc0.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8bgnay8wgohrfxr55tc0.webp" alt="Street photograph of a man walking with a woman while turning to look back at another woman passing by; she reacts with a disapproving expression."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The sentence:&lt;/strong&gt; &lt;code&gt;Slow cinematic push-in with subtle parallax and slight lateral drift.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The result:&lt;/strong&gt; the subjects and framing are preserved; the camera does the work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk288prqyrvud8h3h0uks.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk288prqyrvud8h3h0uks.webp" alt="Animated preview of the generated video: the still photograph moves with a slow push-in and slight lateral drift."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://player.cloudinary.com/embed/?cloud_name=eitanpeer&amp;amp;public_id=image-to-video%2Fi2v_9f3d639b5fb74adbb838a2780efbffc6&amp;amp;player[loop]=true&amp;amp;player[muted]=true&amp;amp;player[fluid]=true" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Watch the real MP4 in the Cloudinary Video Player&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Eleven n8n nodes, with no code. The generation call is one HTTP request. The workflow defines which uploads qualify, where the prompt lives, how the asynchronous job is tracked, and how to find the video later.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you'll build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Trigger Cloudinary image-to-video generation from an upload.&lt;/li&gt;
&lt;li&gt;Control eligibility with tags and metadata.&lt;/li&gt;
&lt;li&gt;Poll an asynchronous generation job safely.&lt;/li&gt;
&lt;li&gt;Tag the source image and return an embeddable video URL.&lt;/li&gt;
&lt;li&gt;Import and adapt the n8n workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What decides that an upload becomes a video
&lt;/h2&gt;

&lt;p&gt;Every rule below is a choice this example made, not a requirement of the API. All three live in a single &lt;strong&gt;Eligible?&lt;/strong&gt; IF node, so swap them for whatever your own pipeline keys off: a folder path, an upload preset, a structured metadata field, a public ID prefix, or the uploading user. What matters is that the check happens once, in one place, and that everything failing it stops there.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;resource_type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;is &lt;code&gt;image&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Video uploads land in the same notification stream and would otherwise loop.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tags&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;contains &lt;code&gt;video_gen&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;This is the opt-in.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.custom.prompt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;is not empty&lt;/td&gt;
&lt;td&gt;This is the direction for the shot.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So the interface here is a tag plus a text field. Contextual metadata is editable in the Media Library, in the Upload API, and through the Admin API, so the prompt can come from a human, a spreadsheet, or another workflow. Nobody has to open n8n. If your prompts are house style rather than per-image direction, drop the context condition and hard-code the sentence in the next node instead.&lt;/p&gt;

&lt;p&gt;The full &lt;code&gt;prompt&lt;/code&gt; value on the image above, second sentence included:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Slow cinematic push-in with subtle parallax and slight lateral drift. Preserve the image exactly—no new objects or altered details.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Everything else is set once, in one node
&lt;/h3&gt;

&lt;p&gt;The remaining parameters are fixed in the request body, so changing the house look for every future video is a single edit. &lt;code&gt;resolution&lt;/code&gt; takes &lt;code&gt;720p&lt;/code&gt; or &lt;code&gt;1080p&lt;/code&gt;, &lt;code&gt;duration&lt;/code&gt; takes 4, 6, or 8 seconds, and &lt;code&gt;aspect_ratio&lt;/code&gt; takes &lt;code&gt;auto&lt;/code&gt;, &lt;code&gt;16:9&lt;/code&gt;, or &lt;code&gt;9:16&lt;/code&gt;. The &lt;a href="https://cloudinary.com/documentation/image_to_video_reference" rel="noopener noreferrer"&gt;image-to-video API reference&lt;/a&gt; has the rest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$json.context.custom.prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"image_asset_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$json.asset_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"720p"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aspect_ratio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"auto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"generate_audio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"enhance_prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How the n8n Cloudinary image-to-video workflow works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhnb33y38qgc0mmh6n54x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhnb33y38qgc0mmh6n54x.png" alt="The n8n workflow canvas: Webhook feeds Get Asset, then an Eligible? check. Its true branch runs Start Generation into a Wait 15s, Poll Job, Completed? loop. Completed? true goes to Tag Source Image and Video Player URL; false goes to Give Up?, which either returns to Wait 15s or ends at Stop and Error."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The poll loop is the long connector running back from &lt;strong&gt;Give Up?&lt;/strong&gt; to &lt;strong&gt;Wait 15s&lt;/strong&gt;. Everything above that line is the happy path.&lt;/p&gt;

&lt;p&gt;Eleven nodes, front to back:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Webhook&lt;/strong&gt;: Cloudinary POSTs here on every upload. Register the production URL as your notification endpoint once and forget it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get Asset&lt;/strong&gt;: Fetches the full asset record by &lt;code&gt;asset_id&lt;/code&gt;. The notification payload is thin; tags and context are read from here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eligible?&lt;/strong&gt;: The three conditions above, combined with AND. The false branch is deliberately unwired; most uploads stop here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start Generation&lt;/strong&gt;: POSTs the JSON above to the image-to-video endpoint and gets back a &lt;code&gt;job_id&lt;/code&gt;. Generation is asynchronous.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait 15s&lt;/strong&gt;: n8n suspends the execution rather than holding a worker open.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Poll Job&lt;/strong&gt;: GETs the job by ID and reads &lt;code&gt;data.status&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Completed?&lt;/strong&gt;: On &lt;code&gt;completed&lt;/code&gt;, go forward. Anything else goes to the give-up check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Give Up?&lt;/strong&gt;: Errors out on &lt;code&gt;failed&lt;/code&gt;, or when &lt;code&gt;$runIndex &amp;gt;= 20&lt;/code&gt;. Otherwise it loops back to &lt;strong&gt;Wait 15s&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stop and Error&lt;/strong&gt;: Fails the execution with the job ID and last-seen status, so the n8n execution log tells you which asset to retry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tag Source Image&lt;/strong&gt;: Appends &lt;code&gt;video_gen_done&lt;/code&gt; to the source image. This is the idempotency marker and the audit trail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video Player URL&lt;/strong&gt;: Builds a Cloudinary Video Player embed URL for the finished asset, muted, looping, and fluid, ready to paste into a CMS.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Watch this line.&lt;/strong&gt; &lt;code&gt;$runIndex &amp;gt;= 20&lt;/code&gt; in &lt;strong&gt;Give Up?&lt;/strong&gt; is the only thing between you and an infinite poll loop. Twenty polls at 15 seconds is a five-minute ceiling. Raise it for longer clips; do not remove it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Delivering the result
&lt;/h2&gt;

&lt;p&gt;The generated MP4 is 1.25 MB at source. Adding &lt;code&gt;f_auto&lt;/code&gt; and &lt;code&gt;q_auto&lt;/code&gt; as the last two components of the delivery URL takes it to 436 KB and lets the CDN pick the codec per browser: AV1 or VP9 where supported, H.264 everywhere else.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# video
https://&amp;lt;cloud&amp;gt;.cloudinary.com/video/upload/c_limit,w_1280/f_auto/q_auto/v1787656854/image-to-video/i2v_9f3d....mp4

# source image
https://&amp;lt;cloud&amp;gt;.cloudinary.com/image/upload/c_limit,w_800/f_auto/q_auto/v1787656781/n8n-demo/couple-meme.webp

# poster frame, pulled from the video at t=0
https://&amp;lt;cloud&amp;gt;.cloudinary.com/video/upload/c_limit,w_1280/so_0/f_auto/q_auto/v1787656854/image-to-video/i2v_9f3d....jpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MP4 at source&lt;/td&gt;
&lt;td&gt;1.25 MB (1280×720, 4s)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;With &lt;code&gt;q_auto&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;436 KB, 65% smaller&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Poll ceiling&lt;/td&gt;
&lt;td&gt;5 min (20 × 15s)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nodes&lt;/td&gt;
&lt;td&gt;11, zero code nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;c_limit&lt;/code&gt; caps the width without ever upscaling, so an asset smaller than the requested width is delivered untouched. Keep &lt;code&gt;f_auto&lt;/code&gt; out of named and incoming transformations: format selection has to resolve per request, at the edge.&lt;/p&gt;

&lt;h3&gt;
  
  
  Or skip the URL building entirely
&lt;/h3&gt;

&lt;p&gt;The last node returns a Video Player embed URL, with the playback options already folded in as query parameters. It is a page you can open, link, or drop straight into a CMS embed field; no &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; element or player script is needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://player.cloudinary.com/embed/?cloud_name=&amp;lt;cloud&amp;gt;&amp;amp;public_id=image-to-video%2Fi2v_9f3d...&amp;amp;player[loop]=true&amp;amp;player[muted]=true&amp;amp;player[fluid]=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;player[…]&lt;/code&gt; keys map one-to-one onto the node's playback and layout fields, so the muted, looping, fluid-width behaviour is configured in n8n rather than in your front end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Import the n8n Cloudinary image-to-video workflow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://eitanpeer-res.cloudinary.com/raw/upload/v1787658491/Cloudinary_Image_to_Video_tag__video_gen_SHARED.json" rel="noopener noreferrer"&gt;Download the workflow JSON&lt;/a&gt; and import it through &lt;strong&gt;Workflows → Import from File&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Install the &lt;a href="https://cloudinary.com/documentation/n8n_integration" rel="noopener noreferrer"&gt;Cloudinary node for n8n&lt;/a&gt;: in a new n8n flow, search the nodes panel for &lt;strong&gt;Cloudinary&lt;/strong&gt;, select the integration, and click &lt;strong&gt;Install node&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Create two credentials and re-select them on the nodes marked &lt;code&gt;REPLACE_ME&lt;/code&gt;: a &lt;strong&gt;Cloudinary API&lt;/strong&gt; credential for the three Cloudinary nodes, and an &lt;strong&gt;HTTP Basic Auth&lt;/strong&gt; credential for the two HTTP Request nodes. Its username is your API key and its password is your API secret.&lt;/li&gt;
&lt;li&gt;Replace &lt;code&gt;YOUR_CLOUD_NAME&lt;/code&gt; in the URLs on &lt;strong&gt;Start Generation&lt;/strong&gt; and &lt;strong&gt;Poll Job&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Open &lt;strong&gt;Eligible?&lt;/strong&gt; and set the conditions to your own rules: the tag name, the metadata field, or whatever else decides that an upload should become a video.&lt;/li&gt;
&lt;li&gt;Copy the production webhook URL and add it in the Cloudinary Console under &lt;strong&gt;Settings → Upload → Notification URL&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Press &lt;strong&gt;Cmd/Ctrl+S&lt;/strong&gt; to save, then activate the workflow. An unsaved workflow will not fire.&lt;/li&gt;
&lt;li&gt;Upload an image with the &lt;code&gt;video_gen&lt;/code&gt; tag and a &lt;code&gt;prompt&lt;/code&gt; context value.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where to take it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Aspect-ratio presets by tag.&lt;/strong&gt; Branch on &lt;code&gt;video_gen_9x16&lt;/code&gt; or &lt;code&gt;video_gen_1x1&lt;/code&gt; and set &lt;code&gt;aspect_ratio&lt;/code&gt; per branch, so social formats come out of the same upload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the result back.&lt;/strong&gt; Add a node that stores the video's public ID in the source image's context. The pairing then survives outside n8n's execution log.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured metadata instead of context.&lt;/strong&gt; A structured metadata field gives the prompt validation and a proper label in the Media Library UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backfill.&lt;/strong&gt; Point the Search API at &lt;code&gt;tags=video_gen AND -tags=video_gen_done&lt;/code&gt; and feed the results into the same chain to catch everything tagged before the workflow existed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tell someone.&lt;/strong&gt; A Slack node after &lt;strong&gt;Video Player URL&lt;/strong&gt; posts the player link to the channel that asked for the video.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get a cloud to run it on
&lt;/h2&gt;

&lt;p&gt;Everything here works on a free account. &lt;a href="https://cloudinary.com/users/register_free" rel="noopener noreferrer"&gt;Sign up&lt;/a&gt;, then find the cloud name, API key, and secret on your dashboard. If an agent is doing the setup, it can provision its own environment instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @cloudinary/cloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command writes working credentials to &lt;code&gt;.env&lt;/code&gt; with no signup. Delivery is locked to the IP the command ran from, and the cloud expires in 24 hours unless someone claims it with an email address. At that point the same credentials become permanent. The &lt;a href="https://cloudinary.com/documentation/agents_start_here" rel="noopener noreferrer"&gt;agent quickstart&lt;/a&gt; covers the claim step and the IP flags.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Workflow JSON:&lt;/strong&gt; &lt;a href="https://eitanpeer-res.cloudinary.com/raw/upload/v1787658491/Cloudinary_Image_to_Video_tag__video_gen_SHARED.json" rel="noopener noreferrer"&gt;Cloudinary — Image to Video (tag: video_gen)&lt;/a&gt;, import-ready, credentials stripped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;n8n integration:&lt;/strong&gt; &lt;a href="https://cloudinary.com/documentation/n8n_integration" rel="noopener noreferrer"&gt;Cloudinary node for n8n&lt;/a&gt;: installation, credentials, and supported operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API reference:&lt;/strong&gt; &lt;a href="https://cloudinary.com/documentation/image_to_video_reference" rel="noopener noreferrer"&gt;Image-to-video API&lt;/a&gt;: every parameter the &lt;strong&gt;Start Generation&lt;/strong&gt; node sends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href="https://cloudinary.com/documentation/video_optimization" rel="noopener noreferrer"&gt;Video optimization&lt;/a&gt; · &lt;a href="https://cloudinary.com/documentation/notifications" rel="noopener noreferrer"&gt;Upload notifications&lt;/a&gt; · &lt;a href="https://cloudinary.com/documentation/video_player_how_to_embed" rel="noopener noreferrer"&gt;Video Player embed&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free account:&lt;/strong&gt; &lt;a href="https://cloudinary.com/users/register_free" rel="noopener noreferrer"&gt;cloudinary.com/users/register_free&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For agents:&lt;/strong&gt; &lt;a href="https://cloudinary.com/documentation/agents_start_here" rel="noopener noreferrer"&gt;Claimable clouds&lt;/a&gt;: &lt;code&gt;npx @cloudinary/cloud&lt;/code&gt;, no signup.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Cloudinary ❤️ developers&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ready to level up your media workflow? Start using Cloudinary for free and build better visual experiences today.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👉 &lt;strong&gt;&lt;a href="https://link.cloudinary.com/usq8w" rel="noopener noreferrer"&gt;Create your free account&lt;/a&gt;&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>n8n</category>
      <category>cloudinary</category>
      <category>automation</category>
      <category>ai</category>
    </item>
    <item>
      <title>Automate Your Media at Scale: 6 Cloudinary Workflows You Can Import Into n8n Today</title>
      <dc:creator>Eitan Peer</dc:creator>
      <pubDate>Wed, 17 Jun 2026 12:58:22 +0000</pubDate>
      <link>https://dev.to/cloudinary/automate-your-media-at-scale-6-cloudinary-workflows-you-can-import-into-n8n-today-22m1</link>
      <guid>https://dev.to/cloudinary/automate-your-media-at-scale-6-cloudinary-workflows-you-can-import-into-n8n-today-22m1</guid>
      <description>&lt;p&gt;Media is where automation pipelines quietly fall apart.&lt;/p&gt;

&lt;p&gt;This post walks through six importable n8n workflows, built on the Cloudinary community node, that hand those media steps back to the pipeline.&lt;/p&gt;

&lt;p&gt;You've wired up a beautiful no-code flow — a new product lands in your PIM, a webhook fires, records sync. Then someone has to &lt;em&gt;resize the hero image for the storefront, cut the launch video into a square for the feed and a vertical for Reels, export a poster frame, and add captions for accessibility.&lt;/em&gt; So the "automated" pipeline stops and waits for a human with Photoshop and a video editor.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.npmjs.com/package/n8n-nodes-cloudinary" rel="noopener noreferrer"&gt;Cloudinary community node for n8n&lt;/a&gt; just closed that gap. The latest release turns Cloudinary's transformation, delivery, and video player engine into native n8n steps, so media work becomes just another node in the flow.&lt;/p&gt;

&lt;p&gt;Below are &lt;strong&gt;six ready-to-import example workflows&lt;/strong&gt; — two clicks to load — designed to run on a free Cloudinary account, subject to &lt;a href="https://cloudinary.com/pricing" rel="noopener noreferrer"&gt;usage limits&lt;/a&gt; (credits, video processing, and some add-ons count against your plan). Each one is self-describing (every workflow ships with a sticky-note README inside n8n) and contains &lt;strong&gt;no credentials&lt;/strong&gt; — you add your own. Each one below links straight to its JSON.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💾 &lt;strong&gt;One-time setup gotcha worth knowing up front:&lt;/strong&gt; after you import a workflow and pick your Cloudinary credential on the first node, &lt;strong&gt;press Cmd/Ctrl+S to save before running.&lt;/strong&gt; That single save persists the credential to every Cloudinary node in the flow at once — so a full &lt;strong&gt;Execute Workflow&lt;/strong&gt; run finds credentials everywhere. Skip the save and the run can fail node-after-node with &lt;em&gt;"Node does not have any credentials set,"&lt;/em&gt; even though the credential looks selected. (More in Add your Cloudinary credentials.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What you'll build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One master video cut for every social platform&lt;/li&gt;
&lt;li&gt;Uniform, AI-filled catalog images at scale&lt;/li&gt;
&lt;li&gt;A paste-in responsive srcset&lt;/li&gt;
&lt;li&gt;An embeddable, adaptive video player&lt;/li&gt;
&lt;li&gt;An automated media-library governance audit&lt;/li&gt;
&lt;li&gt;Accessible video with AI-generated captions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's new in the Cloudinary n8n node
&lt;/h2&gt;

&lt;p&gt;The release adds three things that matter for automation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A Transform resource that builds delivery URLs — with no upload and no API call.&lt;/strong&gt; Optimize, Resize and Crop with an additional conversion option for images and trimming and thumbnails for video. Each operation returns a finished &lt;code&gt;secure_url&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; a reusable transformation string. Because they're pure URL construction, they're instant and free of round-trips.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Transformations that compose three ways.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compose: Combine Transformations&lt;/strong&gt; chains several steps (trim → crop → optimize) inside a single node.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continue From Transformation&lt;/strong&gt; chains steps &lt;em&gt;across&lt;/em&gt; nodes — wire one node's transformation output into the next node's input and they compound into one URL.&lt;/li&gt;
&lt;li&gt;And the same transformation string drops straight into the &lt;strong&gt;Video Player&lt;/strong&gt; widget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Advanced media features — no code required:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Generative Fill&lt;/strong&gt; — extend an image to a new shape with AI-painted background instead of cropping.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video Player&lt;/strong&gt; widget — generate an embeddable player with HLS adaptive streaming (and an MP4 progressive fallback), a poster, picture-in-picture, and &lt;strong&gt;on-demand AI captions, transcripts, and chapters&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asset Search&lt;/strong&gt; — paginate through all matching assets, one n8n item per asset, for governance and audits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let's put them to work.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. One source video → a cut for every platform
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; marketing ships one master video. It needs a 9:16 for TikTok/Reels, a 1:1 for the feed, and a 16:9 for YouTube — each trimmed, each with a poster frame, each optimized. Today that's a manual export-fest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The workflow:&lt;/strong&gt; &lt;a href="https://product-demos-res.cloudinary.com/raw/upload/v1781532950/ax/01-social-video-variations.json" rel="noopener noreferrer"&gt;01-social-video-variations.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upload the master once, then three &lt;strong&gt;Compose: Combine Transformations&lt;/strong&gt; nodes each build a single delivery URL that &lt;strong&gt;trims → crops to the platform's aspect ratio (with auto-focus to keep the subject in frame) → auto-optimizes&lt;/strong&gt;. A matching &lt;strong&gt;Video: Thumbnail&lt;/strong&gt; generates each poster. A final Code node collects everything into a tidy list of &lt;code&gt;{platform, video_url, poster_url}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvvnvnqze7l4h2iq1e5q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvvnvnqze7l4h2iq1e5q.png" alt="The workflow canvas showing the fan-out from Upload Source Video to the three platform variants and their posters." width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The win:&lt;/strong&gt; one trigger produces every platform's asset, ready to hand to a social scheduler or CMS. Add a platform by copying a node and changing one aspect ratio.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Bulk product photos → uniform, AI-filled catalog images
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; product photography arrives in every shape and on every background. Your storefront wants identical, square, optimized product images for thousands of SKUs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The workflow:&lt;/strong&gt; &lt;a href="https://product-demos-res.cloudinary.com/raw/upload/v1781533869/ax/02-ecommerce-image-pipeline.json" rel="noopener noreferrer"&gt;02-ecommerce-image-pipeline.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For each product, the flow ingests the photo, then runs &lt;strong&gt;Image: Crop with Generative Fill&lt;/strong&gt; — instead of cropping the product, Cloudinary &lt;em&gt;extends&lt;/em&gt; the canvas to a perfect 1200×1200 square and &lt;strong&gt;paints a matching background with AI&lt;/strong&gt; (guided by a prompt like &lt;em&gt;"clean seamless studio background"&lt;/em&gt;). It then chains a &lt;strong&gt;Convert → WebP&lt;/strong&gt; step onto that same transformation. Out comes one catalog-ready URL per product.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Feitanpeer-res.cloudinary.com%2Fimage%2Fupload%2Fc_pad%2Cw_1200%2Ch_1200%2Cb_white%2Fbo_3px_solid_rgb%3A888888%2Fl_n8n_blog%3Aproducts%3Aanalog-watch%2Fb_gen_fill%2Cc_pad%2Cw_1200%2Ch_1200%2Fbo_3px_solid_rgb%3A888888%2Ffl_layer_apply%2Cg_west%2Cx_1206%2Fb_white%2Cco_rgb%3A222222%2Cl_text%3AArial_56_bold%3A%25C2%25A0Original%25C2%25A0%2Ffl_layer_apply%2Cg_north_west%2Cx_40%2Cy_40%2Fb_white%2Cco_rgb%3A222222%2Cl_text%3AArial_56_bold%3A%25C2%25A0Generative%2520Fill%25C2%25A0%2Ffl_layer_apply%2Cg_north_west%2Cx_1246%2Cy_40%2Ff_auto%2Fq_auto%2Fn8n_blog%2Fproducts%2Fanalog-watch" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Feitanpeer-res.cloudinary.com%2Fimage%2Fupload%2Fc_pad%2Cw_1200%2Ch_1200%2Cb_white%2Fbo_3px_solid_rgb%3A888888%2Fl_n8n_blog%3Aproducts%3Aanalog-watch%2Fb_gen_fill%2Cc_pad%2Cw_1200%2Ch_1200%2Fbo_3px_solid_rgb%3A888888%2Ffl_layer_apply%2Cg_west%2Cx_1206%2Fb_white%2Cco_rgb%3A222222%2Cl_text%3AArial_56_bold%3A%25C2%25A0Original%25C2%25A0%2Ffl_layer_apply%2Cg_north_west%2Cx_40%2Cy_40%2Fb_white%2Cco_rgb%3A222222%2Cl_text%3AArial_56_bold%3A%25C2%25A0Generative%2520Fill%25C2%25A0%2Ffl_layer_apply%2Cg_north_west%2Cx_1246%2Cy_40%2Ff_auto%2Fq_auto%2Fn8n_blog%2Fproducts%2Fanalog-watch" alt="An off-center product photo on the left, the square AI-filled result on the right." width="2412" height="1206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The win:&lt;/strong&gt; consistent, optimized product imagery with zero designer time — and it scales to your whole catalog by swapping the input list for a Cloudinary Search or a PIM lookup.&lt;/p&gt;

&lt;p&gt;Generative Fill is a generative-AI effect: it uses a special transformation count, is subject to your &lt;a href="https://cloudinary.com/pricing" rel="noopener noreferrer"&gt;plan limits&lt;/a&gt;, and may render asynchronously on the first request. &lt;a href="https://cloudinary.com/users/register_free" rel="noopener noreferrer"&gt;Create a free account&lt;/a&gt; to try it.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. One image → a responsive srcset you can paste into any page
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; you're still hand-exporting @1x/@2x assets, and shipping desktop-sized images to phones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The workflow:&lt;/strong&gt; &lt;a href="https://product-demos-res.cloudinary.com/raw/upload/v1781533869/ax/03-responsive-srcset.json" rel="noopener noreferrer"&gt;03-responsive-srcset.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Point it at one source image and a list of widths. It builds an &lt;strong&gt;Image: Resize&lt;/strong&gt; URL per width (using &lt;em&gt;Limit&lt;/em&gt; fit so it never upscales), chains &lt;strong&gt;Optimize&lt;/strong&gt; (&lt;code&gt;f_auto&lt;/code&gt;/&lt;code&gt;q_auto&lt;/code&gt;) onto each so Cloudinary serves AVIF/WebP/JPEG per browser at the right quality, and assembles a ready-to-paste &lt;code&gt;&amp;lt;img srcset=…&amp;gt;&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tyo41izoak8s5h3dkw1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tyo41izoak8s5h3dkw1.png" alt="The Build srcset HTML node output, showing the generated img srcset markup." width="799" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The win:&lt;/strong&gt; crisp Retina displays &lt;em&gt;and&lt;/em&gt; lightweight mobile loads from a single asset — with the markup generated for you. Change a breakpoint by editing one array.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. A source video → a polished, embeddable player
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; putting a real video player on a landing page or CMS usually means a JS build step and a streaming setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The workflow:&lt;/strong&gt; &lt;a href="https://product-demos-res.cloudinary.com/raw/upload/v1781599646/ax/04-embeddable-video-player.json" rel="noopener noreferrer"&gt;04-embeddable-video-player.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The flow trims a preview cut, grabs a matching poster frame (chained onto the trim), and generates a &lt;strong&gt;Video Player&lt;/strong&gt; embed with &lt;strong&gt;HLS adaptive streaming and an MP4 progressive fallback&lt;/strong&gt;, picture-in-picture, playsinline, and muted autoplay-on-scroll. It outputs both an &lt;code&gt;embed_url&lt;/code&gt; and a responsive &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; snippet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclj8hz7j1o504lhyt5j6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclj8hz7j1o504lhyt5j6.png" alt="The rendered Cloudinary Video Player in a browser, with the controls and poster visible." width="800" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The win:&lt;/strong&gt; a production-grade, adaptive player as a paste-in snippet — no front-end code.&lt;/p&gt;

&lt;p&gt;The workflow feeds the player the &lt;em&gt;trim&lt;/em&gt; transformation, not an &lt;em&gt;optimize&lt;/em&gt; one — adaptive streaming (HLS/DASH) can't be combined with a format-pinned transform (&lt;code&gt;f_auto:video&lt;/code&gt;). Helpfully, the node catches that exact conflict and tells you how to fix it.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Audit and govern a sprawling library — automatically
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; at scale, media libraries rot. Untagged assets, oversized files, content nobody owns. Cleaning it up by hand doesn't happen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The workflow:&lt;/strong&gt; &lt;a href="https://product-demos-res.cloudinary.com/raw/upload/v1781533869/ax/05-asset-governance-audit.json" rel="noopener noreferrer"&gt;05-asset-governance-audit.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asset → Search Assets&lt;/strong&gt; with &lt;em&gt;Return All&lt;/em&gt; paginates through all matching assets (it handles pagination and surfaces rate-limit errors clearly), emitting one n8n item per asset with its tags. The template is scoped to &lt;code&gt;tags=n8n-blog&lt;/code&gt; so it's safe to run as-is — change or remove that expression (e.g. &lt;code&gt;folder:products/*&lt;/code&gt;, or leave it empty) to scan more broadly, up to your whole library. A Code node applies your governance rules — here, &lt;em&gt;flag anything untagged or over 1 MB&lt;/em&gt;. Flagged assets get a &lt;code&gt;needs-review&lt;/code&gt; tag appended (existing tags preserved); everything rolls up into an audit report you can send to Slack or email.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ls0b0pij5oebglnuqw2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ls0b0pij5oebglnuqw2.png" alt="The Audit Report workflow canvas." width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The win:&lt;/strong&gt; continuous, policy-driven hygiene that works identically on 50 assets or 50,000. Swap the tag action for structured-metadata updates or (carefully) deletes.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Accessible video with AI-generated captions — no .vtt files
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; captions are often required by accessibility standards and regulations (such as WCAG, the ADA, and the European Accessibility Act), and a global audience needs subtitles in several languages. Authoring caption files for every video, by hand, doesn't scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The workflow:&lt;/strong&gt; &lt;a href="https://product-demos-res.cloudinary.com/raw/upload/v1781599628/ax/06-accessible-video-player.json" rel="noopener noreferrer"&gt;06-accessible-video-player.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the workflow that shows what Cloudinary's video features can do. The &lt;strong&gt;Video Player&lt;/strong&gt; node ships an accessibility-first config — keyboard controls on, &lt;strong&gt;no autoplay-with-sound&lt;/strong&gt;, playsinline, chapters button visible — plus an &lt;strong&gt;AI-Generated Content&lt;/strong&gt; section that's just a set of toggles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Generate Captions&lt;/strong&gt; → the player &lt;strong&gt;auto-generates a transcript&lt;/strong&gt; and shows it as toggleable captions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate Title / Description / Chapters&lt;/strong&gt; → AI-generated metadata and chapter markers for navigation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are &lt;strong&gt;enabled by default&lt;/strong&gt; on most accounts, so there's nothing to switch on. The player only generates content that doesn't already exist, returning a 202 while it works and caching the result. Nobody writes a caption file: no code is needed to generate captions — the workflow's Code node only formats the player embed snippet.&lt;/p&gt;

&lt;p&gt;Need subtitles in other languages? Set &lt;strong&gt;Subtitle Languages&lt;/strong&gt; (e.g. &lt;code&gt;es&lt;/code&gt;, &lt;code&gt;fr-FR&lt;/code&gt;) for auto-translated tracks. Translation uses the &lt;strong&gt;Google Translate add-on&lt;/strong&gt;: register for it (free tier available) on the &lt;a href="https://console.cloudinary.com/settings/addons" rel="noopener noreferrer"&gt;Cloudinary Add-ons page&lt;/a&gt;, then enable it under &lt;strong&gt;Settings → Security → Unsigned add-on transformations&lt;/strong&gt;. The original-language captions above need no add-on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx09c4vqzzrylyv22u2yp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx09c4vqzzrylyv22u2yp.png" alt="The player with the auto-generated captions toggled on and the language menu open." width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The win:&lt;/strong&gt; videos with dialogue can get captions, chapters, and optional translated tracks automatically — as part of the same flow that published them, with no caption files to author.&lt;/p&gt;

&lt;p&gt;Auto-generation lives in the player's JS config (not iframe URL params), so this workflow outputs a &lt;code&gt;player.source(...)&lt;/code&gt; snippet for the &lt;a href="https://cloudinary.com/documentation/cloudinary_video_player" rel="noopener noreferrer"&gt;Cloudinary Video Player SDK&lt;/a&gt;. On most accounts the unsigned actions for generating video details, transcripts, and chapters are enabled by default — see the &lt;a href="https://cloudinary.com/documentation/video_player_customization" rel="noopener noreferrer"&gt;customization docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to import these workflows
&lt;/h2&gt;

&lt;p&gt;Every workflow is a single &lt;code&gt;.json&lt;/code&gt; file — each section above links straight to it. Importing one takes a few seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install the Cloudinary node (once)
&lt;/h3&gt;

&lt;p&gt;Follow &lt;a href="https://docs.n8n.io/integrations/community-nodes/installation/verified-install/#install-a-community-node" rel="noopener noreferrer"&gt;these instructions&lt;/a&gt; to install the Cloudinary community node (&lt;code&gt;n8n-nodes-cloudinary&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufskmpi32nq7lg28p1wv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufskmpi32nq7lg28p1wv.png" alt="The " width="766" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Import the workflow
&lt;/h3&gt;

&lt;p&gt;Open the workflows list, click the &lt;strong&gt;⋯&lt;/strong&gt; menu (top-right) → &lt;strong&gt;Import from File…&lt;/strong&gt;, and select one of the &lt;code&gt;.json&lt;/code&gt; files. (You can also drag the file onto the canvas.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf905bk6t4llrl856cwk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf905bk6t4llrl856cwk.png" alt="The workflow ⋯ menu open, with Import from File… highlighted." width="762" height="986"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The workflow opens with its sticky-note README already on the canvas explaining what every node does.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Add your Cloudinary credentials
&lt;/h3&gt;

&lt;p&gt;The templates contain &lt;strong&gt;no connection details&lt;/strong&gt; — they're yours to add.&lt;/p&gt;

&lt;p&gt;First, create the credential once: in the &lt;strong&gt;Credentials&lt;/strong&gt; sidebar → &lt;strong&gt;Add Credential&lt;/strong&gt; → &lt;strong&gt;Cloudinary API&lt;/strong&gt;, and paste your &lt;strong&gt;Cloud name&lt;/strong&gt;, &lt;strong&gt;API Key&lt;/strong&gt;, and &lt;strong&gt;API Secret&lt;/strong&gt; from the &lt;a href="https://console.cloudinary.com/settings/api-keys" rel="noopener noreferrer"&gt;Cloudinary Console → API Keys&lt;/a&gt;. Save it. Now it's offered in the dropdown on every Cloudinary node, in this template and every one you import later.&lt;/p&gt;

&lt;p&gt;Then, on the imported workflow, open the &lt;strong&gt;first&lt;/strong&gt; Cloudinary node and pick that credential from the &lt;strong&gt;Credential&lt;/strong&gt; dropdown. n8n back-fills the other nodes that share it — you'll see &lt;em&gt;"Added this credential to N other node(s)."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;💾 &lt;strong&gt;Then save before you run — this is the important bit.&lt;/strong&gt; Press &lt;strong&gt;Cmd/Ctrl+S&lt;/strong&gt; right after picking the credential. The save persists the binding to every Cloudinary node at once, so a full &lt;strong&gt;Execute Workflow&lt;/strong&gt; run finds credentials everywhere.&lt;/p&gt;

&lt;p&gt;If you &lt;em&gt;don't&lt;/em&gt; save first, the full run can fail one node at a time with &lt;strong&gt;"Node does not have any credentials set"&lt;/strong&gt; — even though the credential clearly looks selected on the node. (Tell-tale sign: running a node on its own with &lt;strong&gt;Execute step&lt;/strong&gt; works, but &lt;strong&gt;Execute Workflow&lt;/strong&gt; fails.) A save fixes it in one shot.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Run it
&lt;/h3&gt;

&lt;p&gt;Click &lt;strong&gt;Test workflow&lt;/strong&gt;. The first few workflows upload a public Cloudinary demo asset into &lt;em&gt;your&lt;/em&gt; account so everything downstream resolves against your cloud — so they run out of the box, then become yours the moment you point them at your own media.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to take it next
&lt;/h2&gt;

&lt;p&gt;These six are starting points, not end points. Because every Transform op emits a reusable &lt;code&gt;transformation&lt;/code&gt; string and every node speaks plain n8n JSON, you can drop these media steps into &lt;em&gt;any&lt;/em&gt; pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trigger the social-variations flow from a &lt;strong&gt;webhook&lt;/strong&gt; when a new video lands in your CMS.&lt;/li&gt;
&lt;li&gt;Feed the e-commerce pipeline from a &lt;strong&gt;Google Sheet&lt;/strong&gt; or your &lt;strong&gt;PIM&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Schedule the governance audit to run nightly and post the report to &lt;strong&gt;Slack&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Chain the player + AI-captions flow onto the end of any video upload.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install the node, import a workflow, and let the media steps run themselves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which Cloudinary feature are you missing in the n8n integration?&lt;/strong&gt; We're actively expanding the node — tell us what you'd build next by &lt;a href="https://github.com/cloudinary/n8n-nodes-cloudinary/issues/new" rel="noopener noreferrer"&gt;opening an issue on GitHub&lt;/a&gt; or reaching out through &lt;a href="https://support.cloudinary.com/hc/en-us/requests/new" rel="noopener noreferrer"&gt;Cloudinary Support&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Cloudinary ❤️ developers&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ready to level up your media workflow? Start using Cloudinary for free and build better visual experiences today.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👉 &lt;strong&gt;&lt;a href="https://link.cloudinary.com/uqET9" rel="noopener noreferrer"&gt;Create your free account&lt;/a&gt;&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;👉 &lt;strong&gt;Get the node:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/n8n-nodes-cloudinary" rel="noopener noreferrer"&gt;&lt;code&gt;n8n-nodes-cloudinary&lt;/code&gt; on npm&lt;/a&gt;&lt;br&gt;
👉 &lt;strong&gt;Request a feature / report a bug:&lt;/strong&gt; &lt;a href="https://github.com/cloudinary/n8n-nodes-cloudinary/issues" rel="noopener noreferrer"&gt;GitHub issues&lt;/a&gt;&lt;br&gt;
👉 &lt;strong&gt;How to import a workflow:&lt;/strong&gt; &lt;a href="https://docs.n8n.io/workflows/export-import/" rel="noopener noreferrer"&gt;n8n's import &amp;amp; export guide&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>n8n</category>
      <category>video</category>
      <category>a11y</category>
    </item>
  </channel>
</rss>
