I've been working on Rendofy, a video rendering API for automation workflows, and one thing became obvious pretty quickly:
Rendering the video isn't really the hard part. Making rendering behave nicely inside an automation is.
A render might take several seconds (or longer), so keeping an HTTP request open until everything finishes isn't ideal. Polling the API every few seconds works, but now you've added more requests, more workflow executions and more state to keep track of.
What I really wanted was something much simpler:
'''text
Send JSON
↓
Start render
↓
Go do something else
↓
Get a webhook when the MP4 is ready'''
That's the approach I ended up using with Rendofy.
Here's how it works.
Start with structured data
Instead of sending a video file, the workflow starts with ordinary JSON.
For example:
'''json
{
"quote": "Ship the boring version first.",
"author": "Rendofy"
}'''
Nothing particularly interesting there, and that's kind of the point.
That JSON could have come from an RSS feed, database, CMS, Google Sheet, AI workflow or another API. The rendering step doesn't really care where it came from.
The application just needs to turn that data into a video.
Send the render request
Rendofy accepts the render request through an HTTP endpoint:
'''text
POST https://api.rendofy.com/webhook/render-intake'''
A basic request looks like this:
'''bash
curl -X POST \
https://api.rendofy.com/webhook/render-intake \
-H "Content-Type: application/json" \
-d '{
"api_key": "YOUR_API_KEY",
"callback_url": "https://your-app.example/webhooks/render",
"payload": {
"quote": "Ship the boring version first.",
"author": "Rendofy"
}
}'''
In a real workflow I'd obviously keep the API key in the platform's credential store or an environment variable rather than putting it directly into the workflow.
The important piece here is callback_url.
That's where the finished result will come back.
Don't wait for the video
The API doesn't make the original request sit around while the renderer does its work.
It responds immediately with something like:
'''json
{
"status": "queued",
"job_id": "YOUR_JOB_ID"
}'''
I initially found this separation really useful when testing the system because it makes it very clear what queued actually means.
It doesn't mean:
your video is ready.
It means:
I accepted your render job. I'll get back to you.
The caller can move on.
Then the webhook arrives
Once the render finishes, Rendofy POSTs the result to the callback URL supplied earlier.
A successful result contains the completed job information and the MP4 URL.
Conceptually, it looks like:
'''json
{
"status": "completed",
"job_id": "YOUR_JOB_ID",
"video_url": "https://cdn.example.com/rendered-video.mp4"
}'''
At that point the automation has an actual video it can do something with.
Upload it somewhere. Store it. Pass it to another service. Continue another workflow. Whatever makes sense.
So the complete flow becomes:
'''text
Content/data
↓
Build JSON
↓
POST render request
↓
Job queued
.
. rendering happens
.
↓
Webhook received
↓
MP4 URL
↓
Next step'''
Why I preferred this over polling
Polling would have been easier to explain at first.
Submit the render, wait five seconds, check the status, wait again, check again...
But it felt wrong for the kind of workflows I was trying to support.
If 100 renders are running, I don't want 100 workflows repeatedly asking the rendering service whether they're finished.
I'd rather have the renderer say:
"I'm done. Here's your result."
It also maps surprisingly well to tools like n8n and Make because webhooks are already a normal part of how those platforms work.
What this looks like in n8n
For example, you could have one side of an n8n workflow create the render:
'''text
RSS / CMS / API
↓
Prepare content
↓
Create render'''
Then continue when the callback arrives:
'''text
Webhook
↓
Receive completed render
↓
Use MP4 URL
↓
Next action'''
I've been testing this pattern quite a bit while building the Rendofy n8n integration.
It also means the source of the content is completely separate from rendering.
You could swap an RSS feed for Airtable tomorrow and the rendering architecture wouldn't need to change.
Make works the same way
I recently built the same integration for Make, and the architecture ended up being almost identical.
'''text
Content source
↓
Rendofy: Create a Render
↓
.
rendering
.
↓
Custom Webhook
↓
Continue scenario'''
That was actually a nice validation of the API design.
If the same asynchronous pattern fits naturally into two different automation platforms without special handling, the abstraction is probably doing its job.
One thing I learned while testing this
Error handling matters more than I expected.
There's an important difference between:
"We couldn't accept your request."
and:
"We accepted your request, but the render later failed."
Those need to be treated differently.
For example, an invalid API key should fail immediately. A bad callback URL should also be rejected before creating a render job.
But something that fails during the actual rendering process happens after the job has been accepted, so that result needs to come through the asynchronous path.
I ended up thinking about the lifecycle as three possibilities:
Request → rejected
Request → queued → completed
Request → queued → failed
Simple, but having that distinction made debugging the integration much easier.
Where I'm taking this
The bigger idea behind Rendofy is that I don't want video rendering to be a separate manual workflow.
I want it to behave like infrastructure.
If an automation already has the data needed to make a video, it should be able to send that data somewhere and get an MP4 back without someone opening an editor.
That opens up some interesting workflows:
- RSS → video
- CMS → video
- automated quote videos
- data-driven social content
- personalized video generation
- scheduled video pipelines
- AI workflow → structured JSON → video
I'm building Rendofy around this model.
I've also put the API quickstarts, webhook examples and JavaScript/Python/cURL examples in the Rendofy developer repo.
I'm still building out the integrations, so I'm especially interested in hearing from people using n8n or Make:
What would you actually automate if video rendering were just another node in your workflow?
Top comments (0)