Generate AI videos in n8n with plain HTTP Request nodes: quote, create, wait, download A developer working on the Revana pay-as-you-go image and video generation API published an n8n workflow, built entirely from stock HTTP Request, IF, Wait and Stop and Error nodes, that quotes a generation job's cost before spending, enforces a per-run budget, submits the job with an idempotency key, then polls and downloads the finished video. The workflow targets Revana's REST endpoints, where a quote call is free and returns a quoted price plus a reserved maximum, and the author reports that Seedance 2.5 at 720p, 5 seconds, 9:16 with audio quoted $1.05 on November 5, 2026, versus $0.68 for Kling 4.0 and $0.35 for Wan 3.0. Disclosure: I work on Revana https://revana.si?utm source=devto&utm medium=article&utm campaign=crosspost-4 , a pay-as-you-go API for image and video models. The workflow below calls its REST API, but the shape price first, cap the spend, one idempotency key per job, wait without hammering the API is what you want around any paid generation API in n8n. Most "AI video in n8n" tutorials stop at one HTTP Request node that fires a prompt at a model. That works once in a demo. In a real workflow it breaks in three ways: This post builds a workflow out of stock n8n nodes HTTP Request, IF, Wait, Stop and Error that handles all three. No community node is required, though there is one at the end if you prefer it. php Manual Trigger - Settings Set - Quote HTTP Request, free - Within budget? IF --no-- Stop and Error - Create generation HTTP Request, Idempotency-Key - Wait 20 s - Get generation HTTP Request - Succeeded? IF --yes-- Download video HTTP Request, file --no--- Failed? IF --yes-- Stop and Error --no--- back to Wait Every Revana model goes through the same two endpoints, so the workflow is the same for Seedance 2.5, Kling 4.0, Wan 3.0, Veo 3.1 Fast and the rest. Only the model value and its options change. Create an API key at revana.si/dashboard https://revana.si/dashboard?utm source=devto&utm medium=article&utm campaign=crosspost-4 . In n8n, go to Credentials Add credential Header Auth : Authorization Bearer sr live ... Call it Revana API . On each HTTP Request node below, set Authentication to Generic Credential Type , Generic Auth Type to Header Auth , and pick that credential. A Set node holds everything you'd want to change per run: | Field | Example | |---|---| | model | seedance-2.5 | | prompt | a paper boat drifting down a rainy street at night, neon reflections, rain sounds | | resolution | 720p | | duration | 5 | | aspect ratio | 9:16 | | audio | true | | budget usd | 2 | Valid values differ by model. GET https://api.revana.si/v1/models no key needed lists each model's resolutions, durations and aspect ratios, for example Seedance 2.5 takes 4 to 30 seconds and Kling 4.0 takes 3 to 30. A value a model doesn't offer is refused with 422 invalid input before anything is charged, so a typo costs nothing. POST /v1/generations/quote takes exactly the body you're about to send and answers what it will cost. It's free: nothing is created, held or charged. Quote node HTTP Request : POST https://api.revana.si/v1/generations/quote ={{ JSON.stringify { model: $json.model, input: { prompt: $json.prompt, resolution: $json.resolution, duration: $json.duration, aspect ratio: $json.aspect ratio, audio: $json.audio } } }} The answer has two numbers worth knowing: quoted usd : the price on the first route tried. This is what a successful job normally costs. reserved usd : the most it could cost if the first provider fails and a dearer backup delivers instead. That amount is held from your balance while the job runs. With the settings above Seedance 2.5, 720p, 5 s, 9:16, audio , the quote on November 5, 2026 was $1.05 $0.21 per second , with up to $4.05 reserved if every backup were allowed. The same settings on Kling 4.0 quoted $0.68, on Wan 3.0 $0.35, and Veo 3.1 Fast at 6 seconds it takes 4, 6 or 8 $0.60. Re-quote rather than copying these: prices change, and some inputs cost more than the model's headline rate. Seedance 2.5 with a first frame quoted $0.25 a second instead of $0.21. Within budget? IF node , Number condition: {{ $json.quoted usd }} is less than or equal to {{ $ 'Settings' .item.json.budget usd }} The false branch goes to a Stop and Error node with a message like Costs ${{ $json.quoted usd }}, over the budget . Create generation HTTP Request : https://api.revana.si/v1/generations Idempotency-Key = n8n-{{ $execution.id }} ={{ JSON.stringify { model: $ 'Settings' .item.json.model, input: { prompt: $ 'Settings' .item.json.prompt, resolution: $ 'Settings' .item.json.resolution, duration: $ 'Settings' .item.json.duration, aspect ratio: $ 'Settings' .item.json.aspect ratio, audio: $ 'Settings' .item.json.audio }, max cost usd: $json.quoted usd } }} Two things make this node safe to retry: 200 instead of starting a second one. Sending the same key with a 409 idempotency conflict , which is what you want if someone edits the node between attempts. If you loop over many items in one execution, make the key per item, for example n8n-{{ $execution.id }}-{{ $itemIndex }} . max cost usd is a hard ceiling. The response is 202 with a generation object: id , status queued , quoted usd , reserved usd , and cost usd null until it finishes . A 5-second 720p clip usually takes one to a few minutes, sometimes longer. Polling every second wastes executions and can hit the per-second burst guard 429 rate limited . A loop with a Wait node is enough: GET https://api.revana.si/v1/generations/{{ $ 'Create generation' .item.json.id }} {{ $json.status }} equals succeeded → download. failed → Stop and Error with {{ $json.error.code }}: {{ $json.error.message }} . Otherwise connect the false branch back to Two details: $0 cost usd: 0 . error.retryable tells you whether sending the same request later can work model busy , timeout , all routes failed or whether the request itself has to change content policy , invalid input , max cost exceeded . {{ $runIndex }} is greater than 60 about 20 minutes at 20 s per lap . $runIndex counts how many times that node has run in this execution. Download video HTTP Request : GET https://api.revana.si/v1/generations/{{ $json.id }}/content The API redirects to a short-lived file link, and n8n follows it. The video arrives as binary data, ready for a Google Drive, S3, Slack or Write Binary File node. Result files expire, so store them; don't keep the link. If your n8n is reachable on public HTTPS n8n Cloud, or self-hosted behind a domain , you can drop the loop. Revana's queue endpoint accepts a completion webhook, and n8n's Wait node can pause until a URL is called. {model, input} wrapper, with fal webhook query parameter: POST https://api.revana.si/v1/queue/revana/{{ $ 'Settings' .item.json.model }}?fal webhook={{ encodeURIComponent $execution.resumeUrl }} Idempotency-Key: n8n-{{ $execution.id }} { "prompt": "...", "resolution": "720p", "duration": 5, "aspect ratio": "9:16", "audio": true, "max cost usd": 1.05 } GET https://api.revana.si/v1/queue/revana/{model}/requests/{{ $ 'Create generation' .item.json.request id }}/status , and when it's COMPLETED without an error , download .../requests/{request id}/content with Response Format: File. The callback URL must be public HTTPS on port 443 with no redirects, so this won't work against localhost:5678 . For local development, keep the polling loop. minimax-h3-free is a free model in the same catalog 5 to 15 seconds, 480p/720p/768p, sound always on . Set model to it in Settings , and the quote comes back $0.00 . The account needs one top-up first the smallest pack is $10, an anti-abuse rule , but free jobs never spend it. It's a good way to run the whole workflow end to end before you point it at a paid model. n8n import:workflow --input=seedance-2.5-video-generator.json . n8n-nodes-revana Settings Community Nodes Install, if your instance allows community nodes wraps this into Nothing here is n8n-specific. Make's HTTP module, Zapier's Webhooks by Zapier, Pipedream or a cron job can run the same sequence: POST /v1/generations/quote , POST /v1/generations with an Idempotency-Key and max cost usd , then GET /v1/generations/{id} on an interval and GET /v1/generations/{id}/content at the end. The full API is in the docs https://revana.si/docs?utm source=devto&utm medium=article&utm campaign=crosspost-4 and openapi.json https://revana.si/openapi.json?utm source=devto&utm medium=article&utm campaign=crosspost-4 , and every model and price is at revana.si/pricing https://revana.si/pricing?utm source=devto&utm medium=article&utm campaign=crosspost-4 . Prices and quotes in this post are from Revana's live API on November 5, 2026.