Een mislukte video render in n8n lijkt al snel een probleem met de video API. In de praktijk zit de fout vaak eerder: de HTTP Request node stuurt niet de echte video-URL door, maar de n8n expression zelf.
De API ontvangt dan bijvoorbeeld dit als tekst:
{
"media_list": [
{
"type": "video",
"url": "={{ $('Code in JavaScript2').item.json.videoUrl }}",
"duration": 60
}
]
}
Dat is geen URL. Dat is een instructie die n8n had moeten oplossen voordat de request naar buiten ging.
Wat er fout gaat
In n8n zijn expressions alleen dynamisch als het veld ook echt in expression mode staat, of als je de body via een Code node als object opbouwt. Staat de waarde als normale tekst in je JSON body, dan verstuurt n8n precies die tekst.
Voor een JSON to video request is dat fataal. De renderer kan alleen media downloaden vanaf een echte publieke URL, zoals:
{
"media_list": [
{
"type": "video",
"url": "https://cdn.example.com/product-video.mp4",
"duration": 60
}
],
"settings": {
"aspect_ratio": "9:16"
}
}
Alles wat geen http:// of https:// URL is, hoort niet in media_list[].url. Geen lokale bestandsnaam. Geen Google Drive preview-link zonder directe download. Geen unresolved expression.
De snelste check in n8n
- Open de execution waarin de video faalde.
- Klik op de node vóór je HTTP Request node en controleer of
videoUrlecht in de output staat. - Klik op de HTTP Request node en bekijk de final request body die n8n heeft verstuurd.
- Controleer
media_list[0].url. Zie je={{ ... }}? Dan is het veld niet goed geëvalueerd. - Plak de uiteindelijke URL in een incognito browservenster. Als de video daar niet opent of downloadt, kan de renderer er ook niet bij.
Deze volgorde bespaart veel tijd. Je hoeft nog niet naar retries, queue workers of render logs te kijken zolang de request body zelf niet klopt.
HTTP Request node: Expression mode of Code node
Er zijn twee nette manieren om dit te fixen.
Optie 1: veld in Expression mode
Gebruik expression mode in het URL-veld en laat n8n de waarde ophalen uit de vorige node. Controleer daarna in de execution dat de request body geen expression meer bevat, maar een echte URL.
Optie 2: bouw de body in een Code node
Bij complexere workflows is een Code node vaak duidelijker. Je bouwt dan één object en stuurt dat door naar de HTTP Request node.
return [{
json: {
media_list: [
{
type: 'video',
url: $json.videoUrl,
duration: 60
}
],
settings: {
aspect_ratio: '9:16'
}
}
}];
Daarna zet je de HTTP Request body op JSON en gebruik je de output van deze Code node als body. Minder magie, minder kans dat een expression als tekst blijft staan.
Welke API-fout je nu krijgt
SamAutomation stopt dit soort requests nu eerder af. In plaats van later in de render te crashen, krijg je direct een duidelijke 400-response.
| Foutmelding | Betekenis | Fix |
|---|---|---|
media_list[0].url must be a valid HTTP(S) URL | De media URL is geen downloadbare HTTP(S) URL. | Laat n8n de expression oplossen en stuur de uiteindelijke URL. |
Invalid payload shape | De body is geen JSON object, of data is geen object. | Stuur een object zoals {"media_list":[...]}, geen JSON string. |
Wanneer is de URL goed genoeg?
Een goede media URL voldoet aan drie eisen:
- De URL begint met
http://ofhttps://. - De URL opent direct het bestand of een downloadbare response.
- De URL is bereikbaar zonder browser-login, cookies of een privé sessie.
Signed URLs mogen, zolang ze lang genoeg geldig blijven voor de render. Een URL die maar een paar seconden werkt, is riskant bij wachtrijen of retries.
Links voor je workflow
Gebruik de SamAutomation API docs voor n8n media URLs als checklist naast je HTTP Request node.
Wil je de volledige API-route bekijken? Start bij JSON to video op SamAutomation.
Mijn vaste regel
Debug nooit op basis van wat je denkt dat n8n verstuurt. Debug op basis van de final request body in de execution. Daar zie je direct of je workflow een echte media URL doorstuurt, of alleen een expression die nooit is opgelost.