diff --git a/automation/activepieces.mdx b/automation/activepieces.mdx index c33deda..65c8302 100644 --- a/automation/activepieces.mdx +++ b/automation/activepieces.mdx @@ -105,7 +105,7 @@ When the job ends, Rendobar's callback resumes the flow. The step then re-reads If Rendobar cannot reach this Activepieces from the internet, there is nowhere to call back to. The step polls instead for up to **Maximum Wait (seconds)**, 300 by default, then returns the job as it stands. Keep that below the flow timeout. The job keeps running on Rendobar either way. -Turn **Wait for the Result** off to submit and move on, then pick up the result with [Finished Job](#start-a-flow-when-a-job-finishes). Two more settings shape the step: +Turn **Wait for the Result** off to submit and move on, then pick up the result with [Finished Job](#how-do-i-start-a-flow-when-a-job-finishes). Two more settings shape the step: - **Fail This Step if the Job Fails** is on by default, so a failed job runs the flow's error path. Turn it off to branch on `succeeded` instead. - **Idempotency Key** is derived from the run, the step and the submission when left empty. An automatic retry then settles on the job it already created instead of billing a second one. diff --git a/automation/n8n.mdx b/automation/n8n.mdx index 466d081..c7b8268 100644 --- a/automation/n8n.mdx +++ b/automation/n8n.mdx @@ -37,7 +37,7 @@ The Rendobar node runs FFmpeg commands, compression, captions, composition and i - A Rendobar API key. Create one on the [API Keys](https://app.rendobar.com/api-keys) page of the dashboard. - n8n Cloud, or self-hosted n8n 1.94.0 or later. -- On self-hosted n8n, a public HTTPS address, so the trigger node and the Wait node can receive Rendobar's calls. See [Start a workflow when a job ends](#start-a-workflow-when-a-job-ends). +- On self-hosted n8n, a public HTTPS address, so the trigger node and the Wait node can receive Rendobar's calls. See [Start a workflow when a job ends](#how-do-i-start-a-workflow-when-a-job-ends). ## Install on n8n Cloud diff --git a/build-with-ai.mdx b/build-with-ai.mdx index e7f5206..d852ffe 100644 --- a/build-with-ai.mdx +++ b/build-with-ai.mdx @@ -52,7 +52,7 @@ Live sources of truth: - Error reference: https://rendobar.com/docs/support/errors - Plan limits (file size, timeouts, concurrency): https://rendobar.com/docs/support/limits - What changed lately: https://rendobar.com/changelog/feed.json (JSON Feed, newest first). New job types, new parameters and behavior changes land here, most of them after your training data. -- Each job type has its own docs page under https://rendobar.com/docs/jobs/. Compose effects and transitions are shown rendered, with the exact request, at https://rendobar.com/compose/effects/ +- Each job type has its own docs page under https://rendobar.com/docs/jobs/. Every Compose feature is shown rendered, with the exact request, at https://rendobar.com/compose/features/ API key rules, follow exactly: - I created an API key in the Rendobar dashboard. Ask me to put it in this project's env as RENDOBAR_API_KEY, in a gitignored env file, and wait for my confirmation before running anything that calls the API. @@ -92,8 +92,8 @@ For later work in this project, offer to install Rendobar's agent skills so futu {/* The deep-link URLs embed the full prompt above, URL-encoded with encodeURIComponent. Regenerate them whenever integration-prompt.ts changes. */} -- [Open in ChatGPT](https://chatgpt.com/?q=%23%20Add%20Rendobar%20to%20this%20project%0A%0AYou%20are%20integrating%20Rendobar%20%28https%3A%2F%2Frendobar.com%29%2C%20a%20media%20processing%20and%20AI%20generation%20API%2C%20into%20this%20codebase.%20These%20instructions%20supersede%20anything%20you%20remember%20about%20Rendobar.%20Work%20from%20the%20live%20sources%20below%2C%20not%20from%20memory.%0A%0ALive%20sources%20of%20truth%3A%0A-%20Job%20catalog%3A%20GET%20https%3A%2F%2Fapi.rendobar.com%2Fjobs%2Ftypes%20%28public%2C%20no%20auth%29.%20Per-type%20parameters%20AND%20the%20media%20each%20type%20reads%3A%20GET%20https%3A%2F%2Fapi.rendobar.com%2Fjobs%2Ftypes%2F%7Btype%7D%2Fschema%20%28the%20%60inputs%60%20object%20names%20each%20media%20input%2C%20whether%20it%20takes%20a%20URL%20or%20a%20list%2C%20and%20whether%20the%20type%20accepts%20any%20filename%29%0A-%20OpenAPI%203.1%20spec%3A%20https%3A%2F%2Fapi.rendobar.com%2Fopenapi.json%0A-%20Capability%20map%3A%20https%3A%2F%2Frendobar.com%2Fllms.txt%0A-%20Docs%20text%20for%20AI%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fllms-full.txt%20%28human%20docs%20at%20https%3A%2F%2Frendobar.com%2Fdocs%29%0A-%20Error%20reference%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fsupport%2Ferrors%0A-%20Plan%20limits%20%28file%20size%2C%20timeouts%2C%20concurrency%29%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fsupport%2Flimits%0A-%20What%20changed%20lately%3A%20https%3A%2F%2Frendobar.com%2Fchangelog%2Ffeed.json%20%28JSON%20Feed%2C%20newest%20first%29.%20New%20job%20types%2C%20new%20parameters%20and%20behavior%20changes%20land%20here%2C%20most%20of%20them%20after%20your%20training%20data.%0A-%20Each%20job%20type%20has%20its%20own%20docs%20page%20under%20https%3A%2F%2Frendobar.com%2Fdocs%2Fjobs%2F.%20Compose%20effects%20and%20transitions%20are%20shown%20rendered%2C%20with%20the%20exact%20request%2C%20at%20https%3A%2F%2Frendobar.com%2Fcompose%2Feffects%2F%0A%0AAPI%20key%20rules%2C%20follow%20exactly%3A%0A-%20I%20created%20an%20API%20key%20in%20the%20Rendobar%20dashboard.%20Ask%20me%20to%20put%20it%20in%20this%20project's%20env%20as%20RENDOBAR_API_KEY%2C%20in%20a%20gitignored%20env%20file%2C%20and%20wait%20for%20my%20confirmation%20before%20running%20anything%20that%20calls%20the%20API.%0A-%20Never%20ask%20me%20to%20paste%20the%20key%20into%20this%20chat.%20Never%20print%2C%20log%2C%20or%20commit%20it.%20Never%20put%20it%20in%20client-side%20code.%0A%0AStay%20current%2C%20every%20time%3A%0A-%20Before%20writing%20code%2C%20read%20the%20newest%20changelog%20entries%20and%20the%20live%20schema%20of%20every%20job%20type%20you%20use.%20Trust%20them%20over%20your%20memory%20and%20over%20older%20code%20in%20this%20project.%0A-%20Install%20the%20latest%20%40rendobar%2Fsdk%20%28check%20with%20npm%20view%20%40rendobar%2Fsdk%20version%29.%20Never%20pin%20a%20version%20from%20memory.%0A-%20If%20a%20parameter%2C%20field%20or%20error%20code%20is%20missing%2C%20renamed%20or%20new%2C%20re-read%20the%20schema%20and%20the%20changelog%20before%20guessing.%0A-%20Compose%20timelines%3A%20check%20each%20one%20with%20POST%20https%3A%2F%2Fapi.rendobar.com%2Fcompose%2Fvalidate%20before%20submitting.%0A%0AStep%200%2C%20detect%20the%20stack%20before%20writing%20code%3A%0A-%20Inspect%20the%20project%20%28package.json%2C%20requirements.txt%2C%20go.mod%2C%20composer.json%2C%20Gemfile%29.%20JavaScript%20or%20TypeScript%3A%20use%20the%20official%20SDK%2C%20%40rendobar%2Fsdk.%20Anything%20else%3A%20call%20the%20REST%20API%20directly%20using%20the%20OpenAPI%20spec%20above.%20Same%20endpoints%2C%20same%20shapes.%0A-%20If%20the%20project%20is%20empty%2C%20ask%20me%20which%20stack%20I%20want.%0A%0ASteps%20%28SDK%20path%3B%20mirror%20with%20plain%20HTTP%20on%20the%20REST%20path%29%3A%0A1.%20Install%20%40rendobar%2Fsdk.%20Create%20the%20client%20with%20createClient%28%7B%20apiKey%3A%20process.env.RENDOBAR_API_KEY%20%7D%29.%0A2.%20Read%20the%20live%20job%20catalog%20and%20pick%20the%20job%20types%20this%20project%20needs%20from%20what%20it%20actually%20lists.%20Do%20not%20invent%20job%20types%20or%20parameters.%0A3.%20Submit%20with%20client.jobs.create%28%7B%20type%2C%20inputs%2C%20params%20%7D%29.%20Media%20inputs%20are%20URLs.%20Pass%20an%20idempotencyKey%20anywhere%20a%20retry%20could%20double-submit.%0A4.%20Results%3A%20client.jobs.wait%28job.id%29%20is%20fine%20for%20scripts.%20For%20a%20production%20server%2C%20use%20webhooks%3A%20ask%20me%20to%20add%20an%20endpoint%20at%20https%3A%2F%2Fapp.rendobar.com%2Fwebhooks%2C%20then%20verify%20signatures%20with%20verifyWebhook%20from%20%22%40rendobar%2Fsdk%2Fwebhooks%22.%0A5.%20Handle%20errors%20by%20machine%20code%20%28error.code%29%2C%20never%20message%20text.%20INSUFFICIENT_CREDITS%3A%20tell%20me%20to%20top%20up%20at%20https%3A%2F%2Fapp.rendobar.com%2Fbilling.%20RATE_LIMITED%3A%20retry%20with%20backoff.%20Full%20list%20in%20the%20error%20reference.%0A6.%20Local%20files%3A%20upload%20through%20the%20assets%20flow%20%28POST%20https%3A%2F%2Fapi.rendobar.com%2Fassets%2C%20documented%20in%20the%20docs%29%2C%20then%20pass%20the%20returned%20asset%20url%20as%20the%20job%20input.%0A7.%20Definition%20of%20done%3A%20a%20runnable%20check%20that%20submits%20an%20ffprobe%20job%20on%20https%3A%2F%2Fcdn.rendobar.com%2Fassets%2Fexamples%2Fsample.mp4%20and%20prints%20the%20result.%20Read%20that%20job%20type's%20schema%20first%2C%20its%20parameters%20are%20not%20the%20same%20as%20every%20other%20type.%20Show%20me%20the%20one%20command%20that%20runs%20it.%20On%20a%20401%2C%20check%20both%20causes%20before%20reporting%3A%20the%20key%20may%20not%20be%20reaching%20the%20process%20env%2C%20or%20the%20key%20itself%20may%20be%20invalid%20for%20this%20API%20%28revoked%2C%20mistyped%2C%20or%20issued%20for%20a%20different%20environment%20such%20as%20staging%29.%20Tell%20me%20which%20one%20it%20is.%0A%0AHard%20rules%3A%0A-%20The%20API%20base%20is%20https%3A%2F%2Fapi.rendobar.com%20with%20no%20version%20prefix.%20There%20is%20no%20batch%20endpoint.%20One%20job%20produces%20one%20output.%0A-%20Additive%20changes%20only.%20Do%20not%20refactor%20or%20remove%20unrelated%20code.%0A-%20When%20something%20is%20ambiguous%2C%20choose%20the%20smallest%20default%20that%20keeps%20the%20app%20compiling%20and%20tell%20me%20what%20you%20chose.%20Ask%20me%20only%20when%20it%20is%20a%20product%20decision.%0A%0AIf%20I%20am%20talking%20to%20you%20inside%20an%20MCP-capable%20client%20%28Claude%2C%20Cursor%2C%20and%20others%29%2C%20also%20offer%20to%20connect%20Rendobar's%20MCP%20server%20for%20running%20jobs%20in%20conversation%3A%20https%3A%2F%2Fapi.rendobar.com%2Fmcp%20over%20OAuth%2C%20or%20npx%20-y%20%40rendobar%2Fmcp%20with%20the%20key%20read%20from%20env.%20That%20is%20separate%20from%20the%20codebase%20integration%20above.%0A%0AFor%20later%20work%20in%20this%20project%2C%20offer%20to%20install%20Rendobar's%20agent%20skills%20so%20future%20sessions%20start%20from%20current%20Rendobar%20knowledge%3A%20npx%20skills%20add%20rendobar%2Fagent-skills%20%28in%20Claude%20Code%3A%20%2Fplugin%20marketplace%20add%20rendobar%2Fagent-skills%29.) submits the prompt as soon as the page loads. -- [Open in Cursor](https://cursor.com/link/prompt?text=%23%20Add%20Rendobar%20to%20this%20project%0A%0AYou%20are%20integrating%20Rendobar%20%28https%3A%2F%2Frendobar.com%29%2C%20a%20media%20processing%20and%20AI%20generation%20API%2C%20into%20this%20codebase.%20These%20instructions%20supersede%20anything%20you%20remember%20about%20Rendobar.%20Work%20from%20the%20live%20sources%20below%2C%20not%20from%20memory.%0A%0ALive%20sources%20of%20truth%3A%0A-%20Job%20catalog%3A%20GET%20https%3A%2F%2Fapi.rendobar.com%2Fjobs%2Ftypes%20%28public%2C%20no%20auth%29.%20Per-type%20parameters%20AND%20the%20media%20each%20type%20reads%3A%20GET%20https%3A%2F%2Fapi.rendobar.com%2Fjobs%2Ftypes%2F%7Btype%7D%2Fschema%20%28the%20%60inputs%60%20object%20names%20each%20media%20input%2C%20whether%20it%20takes%20a%20URL%20or%20a%20list%2C%20and%20whether%20the%20type%20accepts%20any%20filename%29%0A-%20OpenAPI%203.1%20spec%3A%20https%3A%2F%2Fapi.rendobar.com%2Fopenapi.json%0A-%20Capability%20map%3A%20https%3A%2F%2Frendobar.com%2Fllms.txt%0A-%20Docs%20text%20for%20AI%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fllms-full.txt%20%28human%20docs%20at%20https%3A%2F%2Frendobar.com%2Fdocs%29%0A-%20Error%20reference%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fsupport%2Ferrors%0A-%20Plan%20limits%20%28file%20size%2C%20timeouts%2C%20concurrency%29%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fsupport%2Flimits%0A-%20What%20changed%20lately%3A%20https%3A%2F%2Frendobar.com%2Fchangelog%2Ffeed.json%20%28JSON%20Feed%2C%20newest%20first%29.%20New%20job%20types%2C%20new%20parameters%20and%20behavior%20changes%20land%20here%2C%20most%20of%20them%20after%20your%20training%20data.%0A-%20Each%20job%20type%20has%20its%20own%20docs%20page%20under%20https%3A%2F%2Frendobar.com%2Fdocs%2Fjobs%2F.%20Compose%20effects%20and%20transitions%20are%20shown%20rendered%2C%20with%20the%20exact%20request%2C%20at%20https%3A%2F%2Frendobar.com%2Fcompose%2Feffects%2F%0A%0AAPI%20key%20rules%2C%20follow%20exactly%3A%0A-%20I%20created%20an%20API%20key%20in%20the%20Rendobar%20dashboard.%20Ask%20me%20to%20put%20it%20in%20this%20project's%20env%20as%20RENDOBAR_API_KEY%2C%20in%20a%20gitignored%20env%20file%2C%20and%20wait%20for%20my%20confirmation%20before%20running%20anything%20that%20calls%20the%20API.%0A-%20Never%20ask%20me%20to%20paste%20the%20key%20into%20this%20chat.%20Never%20print%2C%20log%2C%20or%20commit%20it.%20Never%20put%20it%20in%20client-side%20code.%0A%0AStay%20current%2C%20every%20time%3A%0A-%20Before%20writing%20code%2C%20read%20the%20newest%20changelog%20entries%20and%20the%20live%20schema%20of%20every%20job%20type%20you%20use.%20Trust%20them%20over%20your%20memory%20and%20over%20older%20code%20in%20this%20project.%0A-%20Install%20the%20latest%20%40rendobar%2Fsdk%20%28check%20with%20npm%20view%20%40rendobar%2Fsdk%20version%29.%20Never%20pin%20a%20version%20from%20memory.%0A-%20If%20a%20parameter%2C%20field%20or%20error%20code%20is%20missing%2C%20renamed%20or%20new%2C%20re-read%20the%20schema%20and%20the%20changelog%20before%20guessing.%0A-%20Compose%20timelines%3A%20check%20each%20one%20with%20POST%20https%3A%2F%2Fapi.rendobar.com%2Fcompose%2Fvalidate%20before%20submitting.%0A%0AStep%200%2C%20detect%20the%20stack%20before%20writing%20code%3A%0A-%20Inspect%20the%20project%20%28package.json%2C%20requirements.txt%2C%20go.mod%2C%20composer.json%2C%20Gemfile%29.%20JavaScript%20or%20TypeScript%3A%20use%20the%20official%20SDK%2C%20%40rendobar%2Fsdk.%20Anything%20else%3A%20call%20the%20REST%20API%20directly%20using%20the%20OpenAPI%20spec%20above.%20Same%20endpoints%2C%20same%20shapes.%0A-%20If%20the%20project%20is%20empty%2C%20ask%20me%20which%20stack%20I%20want.%0A%0ASteps%20%28SDK%20path%3B%20mirror%20with%20plain%20HTTP%20on%20the%20REST%20path%29%3A%0A1.%20Install%20%40rendobar%2Fsdk.%20Create%20the%20client%20with%20createClient%28%7B%20apiKey%3A%20process.env.RENDOBAR_API_KEY%20%7D%29.%0A2.%20Read%20the%20live%20job%20catalog%20and%20pick%20the%20job%20types%20this%20project%20needs%20from%20what%20it%20actually%20lists.%20Do%20not%20invent%20job%20types%20or%20parameters.%0A3.%20Submit%20with%20client.jobs.create%28%7B%20type%2C%20inputs%2C%20params%20%7D%29.%20Media%20inputs%20are%20URLs.%20Pass%20an%20idempotencyKey%20anywhere%20a%20retry%20could%20double-submit.%0A4.%20Results%3A%20client.jobs.wait%28job.id%29%20is%20fine%20for%20scripts.%20For%20a%20production%20server%2C%20use%20webhooks%3A%20ask%20me%20to%20add%20an%20endpoint%20at%20https%3A%2F%2Fapp.rendobar.com%2Fwebhooks%2C%20then%20verify%20signatures%20with%20verifyWebhook%20from%20%22%40rendobar%2Fsdk%2Fwebhooks%22.%0A5.%20Handle%20errors%20by%20machine%20code%20%28error.code%29%2C%20never%20message%20text.%20INSUFFICIENT_CREDITS%3A%20tell%20me%20to%20top%20up%20at%20https%3A%2F%2Fapp.rendobar.com%2Fbilling.%20RATE_LIMITED%3A%20retry%20with%20backoff.%20Full%20list%20in%20the%20error%20reference.%0A6.%20Local%20files%3A%20upload%20through%20the%20assets%20flow%20%28POST%20https%3A%2F%2Fapi.rendobar.com%2Fassets%2C%20documented%20in%20the%20docs%29%2C%20then%20pass%20the%20returned%20asset%20url%20as%20the%20job%20input.%0A7.%20Definition%20of%20done%3A%20a%20runnable%20check%20that%20submits%20an%20ffprobe%20job%20on%20https%3A%2F%2Fcdn.rendobar.com%2Fassets%2Fexamples%2Fsample.mp4%20and%20prints%20the%20result.%20Read%20that%20job%20type's%20schema%20first%2C%20its%20parameters%20are%20not%20the%20same%20as%20every%20other%20type.%20Show%20me%20the%20one%20command%20that%20runs%20it.%20On%20a%20401%2C%20check%20both%20causes%20before%20reporting%3A%20the%20key%20may%20not%20be%20reaching%20the%20process%20env%2C%20or%20the%20key%20itself%20may%20be%20invalid%20for%20this%20API%20%28revoked%2C%20mistyped%2C%20or%20issued%20for%20a%20different%20environment%20such%20as%20staging%29.%20Tell%20me%20which%20one%20it%20is.%0A%0AHard%20rules%3A%0A-%20The%20API%20base%20is%20https%3A%2F%2Fapi.rendobar.com%20with%20no%20version%20prefix.%20There%20is%20no%20batch%20endpoint.%20One%20job%20produces%20one%20output.%0A-%20Additive%20changes%20only.%20Do%20not%20refactor%20or%20remove%20unrelated%20code.%0A-%20When%20something%20is%20ambiguous%2C%20choose%20the%20smallest%20default%20that%20keeps%20the%20app%20compiling%20and%20tell%20me%20what%20you%20chose.%20Ask%20me%20only%20when%20it%20is%20a%20product%20decision.%0A%0AIf%20I%20am%20talking%20to%20you%20inside%20an%20MCP-capable%20client%20%28Claude%2C%20Cursor%2C%20and%20others%29%2C%20also%20offer%20to%20connect%20Rendobar's%20MCP%20server%20for%20running%20jobs%20in%20conversation%3A%20https%3A%2F%2Fapi.rendobar.com%2Fmcp%20over%20OAuth%2C%20or%20npx%20-y%20%40rendobar%2Fmcp%20with%20the%20key%20read%20from%20env.%20That%20is%20separate%20from%20the%20codebase%20integration%20above.%0A%0AFor%20later%20work%20in%20this%20project%2C%20offer%20to%20install%20Rendobar's%20agent%20skills%20so%20future%20sessions%20start%20from%20current%20Rendobar%20knowledge%3A%20npx%20skills%20add%20rendobar%2Fagent-skills%20%28in%20Claude%20Code%3A%20%2Fplugin%20marketplace%20add%20rendobar%2Fagent-skills%29.) loads the prompt into the agent. Review it, then run. +- [Open in ChatGPT](https://chatgpt.com/?q=%23%20Add%20Rendobar%20to%20this%20project%0A%0AYou%20are%20integrating%20Rendobar%20(https%3A%2F%2Frendobar.com)%2C%20a%20media%20processing%20and%20AI%20generation%20API%2C%20into%20this%20codebase.%20These%20instructions%20supersede%20anything%20you%20remember%20about%20Rendobar.%20Work%20from%20the%20live%20sources%20below%2C%20not%20from%20memory.%0A%0ALive%20sources%20of%20truth%3A%0A-%20Job%20catalog%3A%20GET%20https%3A%2F%2Fapi.rendobar.com%2Fjobs%2Ftypes%20(public%2C%20no%20auth).%20Per-type%20parameters%20AND%20the%20media%20each%20type%20reads%3A%20GET%20https%3A%2F%2Fapi.rendobar.com%2Fjobs%2Ftypes%2F%7Btype%7D%2Fschema%20(the%20%60inputs%60%20object%20names%20each%20media%20input%2C%20whether%20it%20takes%20a%20URL%20or%20a%20list%2C%20and%20whether%20the%20type%20accepts%20any%20filename)%0A-%20OpenAPI%203.1%20spec%3A%20https%3A%2F%2Fapi.rendobar.com%2Fopenapi.json%0A-%20Capability%20map%3A%20https%3A%2F%2Frendobar.com%2Fllms.txt%0A-%20Docs%20text%20for%20AI%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fllms-full.txt%20(human%20docs%20at%20https%3A%2F%2Frendobar.com%2Fdocs)%0A-%20Error%20reference%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fsupport%2Ferrors%0A-%20Plan%20limits%20(file%20size%2C%20timeouts%2C%20concurrency)%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fsupport%2Flimits%0A-%20What%20changed%20lately%3A%20https%3A%2F%2Frendobar.com%2Fchangelog%2Ffeed.json%20(JSON%20Feed%2C%20newest%20first).%20New%20job%20types%2C%20new%20parameters%20and%20behavior%20changes%20land%20here%2C%20most%20of%20them%20after%20your%20training%20data.%0A-%20Each%20job%20type%20has%20its%20own%20docs%20page%20under%20https%3A%2F%2Frendobar.com%2Fdocs%2Fjobs%2F.%20Every%20Compose%20feature%20is%20shown%20rendered%2C%20with%20the%20exact%20request%2C%20at%20https%3A%2F%2Frendobar.com%2Fcompose%2Ffeatures%2F%0A%0AAPI%20key%20rules%2C%20follow%20exactly%3A%0A-%20I%20created%20an%20API%20key%20in%20the%20Rendobar%20dashboard.%20Ask%20me%20to%20put%20it%20in%20this%20project's%20env%20as%20RENDOBAR_API_KEY%2C%20in%20a%20gitignored%20env%20file%2C%20and%20wait%20for%20my%20confirmation%20before%20running%20anything%20that%20calls%20the%20API.%0A-%20Never%20ask%20me%20to%20paste%20the%20key%20into%20this%20chat.%20Never%20print%2C%20log%2C%20or%20commit%20it.%20Never%20put%20it%20in%20client-side%20code.%0A%0AStay%20current%2C%20every%20time%3A%0A-%20Before%20writing%20code%2C%20read%20the%20newest%20changelog%20entries%20and%20the%20live%20schema%20of%20every%20job%20type%20you%20use.%20Trust%20them%20over%20your%20memory%20and%20over%20older%20code%20in%20this%20project.%0A-%20Install%20the%20latest%20%40rendobar%2Fsdk%20(check%20with%20npm%20view%20%40rendobar%2Fsdk%20version).%20Never%20pin%20a%20version%20from%20memory.%0A-%20If%20a%20parameter%2C%20field%20or%20error%20code%20is%20missing%2C%20renamed%20or%20new%2C%20re-read%20the%20schema%20and%20the%20changelog%20before%20guessing.%0A-%20Compose%20timelines%3A%20check%20each%20one%20with%20POST%20https%3A%2F%2Fapi.rendobar.com%2Fcompose%2Fvalidate%20before%20submitting.%0A%0AStep%200%2C%20detect%20the%20stack%20before%20writing%20code%3A%0A-%20Inspect%20the%20project%20(package.json%2C%20requirements.txt%2C%20go.mod%2C%20composer.json%2C%20Gemfile).%20JavaScript%20or%20TypeScript%3A%20use%20the%20official%20SDK%2C%20%40rendobar%2Fsdk.%20Anything%20else%3A%20call%20the%20REST%20API%20directly%20using%20the%20OpenAPI%20spec%20above.%20Same%20endpoints%2C%20same%20shapes.%0A-%20If%20the%20project%20is%20empty%2C%20ask%20me%20which%20stack%20I%20want.%0A%0ASteps%20(SDK%20path%3B%20mirror%20with%20plain%20HTTP%20on%20the%20REST%20path)%3A%0A1.%20Install%20%40rendobar%2Fsdk.%20Create%20the%20client%20with%20createClient(%7B%20apiKey%3A%20process.env.RENDOBAR_API_KEY%20%7D).%0A2.%20Read%20the%20live%20job%20catalog%20and%20pick%20the%20job%20types%20this%20project%20needs%20from%20what%20it%20actually%20lists.%20Do%20not%20invent%20job%20types%20or%20parameters.%0A3.%20Submit%20with%20client.jobs.create(%7B%20type%2C%20inputs%2C%20params%20%7D).%20Media%20inputs%20are%20URLs.%20Pass%20an%20idempotencyKey%20anywhere%20a%20retry%20could%20double-submit.%0A4.%20Results%3A%20client.jobs.wait(job.id)%20is%20fine%20for%20scripts.%20For%20a%20production%20server%2C%20use%20webhooks%3A%20ask%20me%20to%20add%20an%20endpoint%20at%20https%3A%2F%2Fapp.rendobar.com%2Fwebhooks%2C%20then%20verify%20signatures%20with%20verifyWebhook%20from%20%22%40rendobar%2Fsdk%2Fwebhooks%22.%0A5.%20Handle%20errors%20by%20machine%20code%20(error.code)%2C%20never%20message%20text.%20INSUFFICIENT_CREDITS%3A%20tell%20me%20to%20top%20up%20at%20https%3A%2F%2Fapp.rendobar.com%2Fbilling.%20RATE_LIMITED%3A%20retry%20with%20backoff.%20Full%20list%20in%20the%20error%20reference.%0A6.%20Local%20files%3A%20upload%20through%20the%20assets%20flow%20(POST%20https%3A%2F%2Fapi.rendobar.com%2Fassets%2C%20documented%20in%20the%20docs)%2C%20then%20pass%20the%20returned%20asset%20url%20as%20the%20job%20input.%0A7.%20Definition%20of%20done%3A%20a%20runnable%20check%20that%20submits%20an%20ffprobe%20job%20on%20https%3A%2F%2Fcdn.rendobar.com%2Fassets%2Fexamples%2Fsample.mp4%20and%20prints%20the%20result.%20Read%20that%20job%20type's%20schema%20first%2C%20its%20parameters%20are%20not%20the%20same%20as%20every%20other%20type.%20Show%20me%20the%20one%20command%20that%20runs%20it.%20On%20a%20401%2C%20check%20both%20causes%20before%20reporting%3A%20the%20key%20may%20not%20be%20reaching%20the%20process%20env%2C%20or%20the%20key%20itself%20may%20be%20invalid%20for%20this%20API%20(revoked%2C%20mistyped%2C%20or%20issued%20for%20a%20different%20environment%20such%20as%20staging).%20Tell%20me%20which%20one%20it%20is.%0A%0AHard%20rules%3A%0A-%20The%20API%20base%20is%20https%3A%2F%2Fapi.rendobar.com%20with%20no%20version%20prefix.%20There%20is%20no%20batch%20endpoint.%20One%20job%20produces%20one%20output.%0A-%20Additive%20changes%20only.%20Do%20not%20refactor%20or%20remove%20unrelated%20code.%0A-%20When%20something%20is%20ambiguous%2C%20choose%20the%20smallest%20default%20that%20keeps%20the%20app%20compiling%20and%20tell%20me%20what%20you%20chose.%20Ask%20me%20only%20when%20it%20is%20a%20product%20decision.%0A%0AIf%20I%20am%20talking%20to%20you%20inside%20an%20MCP-capable%20client%20(Claude%2C%20Cursor%2C%20and%20others)%2C%20also%20offer%20to%20connect%20Rendobar's%20MCP%20server%20for%20running%20jobs%20in%20conversation%3A%20https%3A%2F%2Fapi.rendobar.com%2Fmcp%20over%20OAuth%2C%20or%20npx%20-y%20%40rendobar%2Fmcp%20with%20the%20key%20read%20from%20env.%20That%20is%20separate%20from%20the%20codebase%20integration%20above.%0A%0AFor%20later%20work%20in%20this%20project%2C%20offer%20to%20install%20Rendobar's%20agent%20skills%20so%20future%20sessions%20start%20from%20current%20Rendobar%20knowledge%3A%20npx%20skills%20add%20rendobar%2Fagent-skills%20(in%20Claude%20Code%3A%20%2Fplugin%20marketplace%20add%20rendobar%2Fagent-skills).) submits the prompt as soon as the page loads. +- [Open in Cursor](https://cursor.com/link/prompt?text=%23%20Add%20Rendobar%20to%20this%20project%0A%0AYou%20are%20integrating%20Rendobar%20(https%3A%2F%2Frendobar.com)%2C%20a%20media%20processing%20and%20AI%20generation%20API%2C%20into%20this%20codebase.%20These%20instructions%20supersede%20anything%20you%20remember%20about%20Rendobar.%20Work%20from%20the%20live%20sources%20below%2C%20not%20from%20memory.%0A%0ALive%20sources%20of%20truth%3A%0A-%20Job%20catalog%3A%20GET%20https%3A%2F%2Fapi.rendobar.com%2Fjobs%2Ftypes%20(public%2C%20no%20auth).%20Per-type%20parameters%20AND%20the%20media%20each%20type%20reads%3A%20GET%20https%3A%2F%2Fapi.rendobar.com%2Fjobs%2Ftypes%2F%7Btype%7D%2Fschema%20(the%20%60inputs%60%20object%20names%20each%20media%20input%2C%20whether%20it%20takes%20a%20URL%20or%20a%20list%2C%20and%20whether%20the%20type%20accepts%20any%20filename)%0A-%20OpenAPI%203.1%20spec%3A%20https%3A%2F%2Fapi.rendobar.com%2Fopenapi.json%0A-%20Capability%20map%3A%20https%3A%2F%2Frendobar.com%2Fllms.txt%0A-%20Docs%20text%20for%20AI%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fllms-full.txt%20(human%20docs%20at%20https%3A%2F%2Frendobar.com%2Fdocs)%0A-%20Error%20reference%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fsupport%2Ferrors%0A-%20Plan%20limits%20(file%20size%2C%20timeouts%2C%20concurrency)%3A%20https%3A%2F%2Frendobar.com%2Fdocs%2Fsupport%2Flimits%0A-%20What%20changed%20lately%3A%20https%3A%2F%2Frendobar.com%2Fchangelog%2Ffeed.json%20(JSON%20Feed%2C%20newest%20first).%20New%20job%20types%2C%20new%20parameters%20and%20behavior%20changes%20land%20here%2C%20most%20of%20them%20after%20your%20training%20data.%0A-%20Each%20job%20type%20has%20its%20own%20docs%20page%20under%20https%3A%2F%2Frendobar.com%2Fdocs%2Fjobs%2F.%20Every%20Compose%20feature%20is%20shown%20rendered%2C%20with%20the%20exact%20request%2C%20at%20https%3A%2F%2Frendobar.com%2Fcompose%2Ffeatures%2F%0A%0AAPI%20key%20rules%2C%20follow%20exactly%3A%0A-%20I%20created%20an%20API%20key%20in%20the%20Rendobar%20dashboard.%20Ask%20me%20to%20put%20it%20in%20this%20project's%20env%20as%20RENDOBAR_API_KEY%2C%20in%20a%20gitignored%20env%20file%2C%20and%20wait%20for%20my%20confirmation%20before%20running%20anything%20that%20calls%20the%20API.%0A-%20Never%20ask%20me%20to%20paste%20the%20key%20into%20this%20chat.%20Never%20print%2C%20log%2C%20or%20commit%20it.%20Never%20put%20it%20in%20client-side%20code.%0A%0AStay%20current%2C%20every%20time%3A%0A-%20Before%20writing%20code%2C%20read%20the%20newest%20changelog%20entries%20and%20the%20live%20schema%20of%20every%20job%20type%20you%20use.%20Trust%20them%20over%20your%20memory%20and%20over%20older%20code%20in%20this%20project.%0A-%20Install%20the%20latest%20%40rendobar%2Fsdk%20(check%20with%20npm%20view%20%40rendobar%2Fsdk%20version).%20Never%20pin%20a%20version%20from%20memory.%0A-%20If%20a%20parameter%2C%20field%20or%20error%20code%20is%20missing%2C%20renamed%20or%20new%2C%20re-read%20the%20schema%20and%20the%20changelog%20before%20guessing.%0A-%20Compose%20timelines%3A%20check%20each%20one%20with%20POST%20https%3A%2F%2Fapi.rendobar.com%2Fcompose%2Fvalidate%20before%20submitting.%0A%0AStep%200%2C%20detect%20the%20stack%20before%20writing%20code%3A%0A-%20Inspect%20the%20project%20(package.json%2C%20requirements.txt%2C%20go.mod%2C%20composer.json%2C%20Gemfile).%20JavaScript%20or%20TypeScript%3A%20use%20the%20official%20SDK%2C%20%40rendobar%2Fsdk.%20Anything%20else%3A%20call%20the%20REST%20API%20directly%20using%20the%20OpenAPI%20spec%20above.%20Same%20endpoints%2C%20same%20shapes.%0A-%20If%20the%20project%20is%20empty%2C%20ask%20me%20which%20stack%20I%20want.%0A%0ASteps%20(SDK%20path%3B%20mirror%20with%20plain%20HTTP%20on%20the%20REST%20path)%3A%0A1.%20Install%20%40rendobar%2Fsdk.%20Create%20the%20client%20with%20createClient(%7B%20apiKey%3A%20process.env.RENDOBAR_API_KEY%20%7D).%0A2.%20Read%20the%20live%20job%20catalog%20and%20pick%20the%20job%20types%20this%20project%20needs%20from%20what%20it%20actually%20lists.%20Do%20not%20invent%20job%20types%20or%20parameters.%0A3.%20Submit%20with%20client.jobs.create(%7B%20type%2C%20inputs%2C%20params%20%7D).%20Media%20inputs%20are%20URLs.%20Pass%20an%20idempotencyKey%20anywhere%20a%20retry%20could%20double-submit.%0A4.%20Results%3A%20client.jobs.wait(job.id)%20is%20fine%20for%20scripts.%20For%20a%20production%20server%2C%20use%20webhooks%3A%20ask%20me%20to%20add%20an%20endpoint%20at%20https%3A%2F%2Fapp.rendobar.com%2Fwebhooks%2C%20then%20verify%20signatures%20with%20verifyWebhook%20from%20%22%40rendobar%2Fsdk%2Fwebhooks%22.%0A5.%20Handle%20errors%20by%20machine%20code%20(error.code)%2C%20never%20message%20text.%20INSUFFICIENT_CREDITS%3A%20tell%20me%20to%20top%20up%20at%20https%3A%2F%2Fapp.rendobar.com%2Fbilling.%20RATE_LIMITED%3A%20retry%20with%20backoff.%20Full%20list%20in%20the%20error%20reference.%0A6.%20Local%20files%3A%20upload%20through%20the%20assets%20flow%20(POST%20https%3A%2F%2Fapi.rendobar.com%2Fassets%2C%20documented%20in%20the%20docs)%2C%20then%20pass%20the%20returned%20asset%20url%20as%20the%20job%20input.%0A7.%20Definition%20of%20done%3A%20a%20runnable%20check%20that%20submits%20an%20ffprobe%20job%20on%20https%3A%2F%2Fcdn.rendobar.com%2Fassets%2Fexamples%2Fsample.mp4%20and%20prints%20the%20result.%20Read%20that%20job%20type's%20schema%20first%2C%20its%20parameters%20are%20not%20the%20same%20as%20every%20other%20type.%20Show%20me%20the%20one%20command%20that%20runs%20it.%20On%20a%20401%2C%20check%20both%20causes%20before%20reporting%3A%20the%20key%20may%20not%20be%20reaching%20the%20process%20env%2C%20or%20the%20key%20itself%20may%20be%20invalid%20for%20this%20API%20(revoked%2C%20mistyped%2C%20or%20issued%20for%20a%20different%20environment%20such%20as%20staging).%20Tell%20me%20which%20one%20it%20is.%0A%0AHard%20rules%3A%0A-%20The%20API%20base%20is%20https%3A%2F%2Fapi.rendobar.com%20with%20no%20version%20prefix.%20There%20is%20no%20batch%20endpoint.%20One%20job%20produces%20one%20output.%0A-%20Additive%20changes%20only.%20Do%20not%20refactor%20or%20remove%20unrelated%20code.%0A-%20When%20something%20is%20ambiguous%2C%20choose%20the%20smallest%20default%20that%20keeps%20the%20app%20compiling%20and%20tell%20me%20what%20you%20chose.%20Ask%20me%20only%20when%20it%20is%20a%20product%20decision.%0A%0AIf%20I%20am%20talking%20to%20you%20inside%20an%20MCP-capable%20client%20(Claude%2C%20Cursor%2C%20and%20others)%2C%20also%20offer%20to%20connect%20Rendobar's%20MCP%20server%20for%20running%20jobs%20in%20conversation%3A%20https%3A%2F%2Fapi.rendobar.com%2Fmcp%20over%20OAuth%2C%20or%20npx%20-y%20%40rendobar%2Fmcp%20with%20the%20key%20read%20from%20env.%20That%20is%20separate%20from%20the%20codebase%20integration%20above.%0A%0AFor%20later%20work%20in%20this%20project%2C%20offer%20to%20install%20Rendobar's%20agent%20skills%20so%20future%20sessions%20start%20from%20current%20Rendobar%20knowledge%3A%20npx%20skills%20add%20rendobar%2Fagent-skills%20(in%20Claude%20Code%3A%20%2Fplugin%20marketplace%20add%20rendobar%2Fagent-skills).) loads the prompt into the agent. Review it, then run. Claude has no link that prefills a prompt. In claude.ai or Claude Code, paste the prompt above. To run jobs straight from the conversation, [add Rendobar to Claude](https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Rendobar&connectorUrl=https%3A%2F%2Fapi.rendobar.com%2Fmcp) as a connector, which opens the dialog with the [MCP server](/mcp-server) URL filled in. diff --git a/concepts/credits.mdx b/concepts/credits.mdx index 2a7f3de..96e44dd 100644 --- a/concepts/credits.mdx +++ b/concepts/credits.mdx @@ -1,7 +1,7 @@ --- title: "Credits and billing" sidebarTitle: "Credits" -description: "Get per-job nanodollar billing from a prepaid credit balance. Free includes a signup grant, Pro adds monthly credits, and credits never expire." +description: "Get per-job nanodollar billing from a prepaid credit balance. Free includes a signup grant, Pro and Studio add monthly credits, and credits never expire." icon: "coins" keywords: ["credit-based billing", "nanodollar pricing", "rendobar credits", "video api credits", "prepaid balance"] canonical: "https://rendobar.com/docs/concepts/credits" @@ -15,7 +15,7 @@ canonical: "https://rendobar.com/docs/concepts/credits" "@type": "TechArticle", "@id": "https://rendobar.com/docs/concepts/credits#article", "headline": "Credits and billing", - "description": "Get per-job nanodollar billing from a prepaid credit balance. Free includes a signup grant, Pro adds monthly credits, and credits never expire.", + "description": "Get per-job nanodollar billing from a prepaid credit balance. Free includes a signup grant, Pro and Studio add monthly credits, and credits never expire.", "datePublished": "2026-03-20", "author": { "@type": "Organization", "@id": "https://rendobar.com/#organization" }, "publisher": { "@type": "Organization", "@id": "https://rendobar.com/#organization" } @@ -23,45 +23,47 @@ canonical: "https://rendobar.com/docs/concepts/credits" }} /> -Per-job billing from a prepaid credit balance. New accounts get $5 free. Every terminal job is charged for the compute it consumed, including jobs that fail. +Per-job billing from a prepaid credit balance. New accounts get $5 free. [Compose](/docs/jobs/compose/pricing) bills per minute of the video you get back. Every other job type bills for the compute it consumed, including jobs that fail. ## Plans -| | Free | Pro | -|---|---|---| -| Price | $0/mo | $9/mo | -| Signup credits | $5 (one-time) | - | -| Monthly credits included | - | $5 | -| Credit-purchase bonus | - | +20% | -| Concurrent jobs | 1 | 20 | -| Queued backlog | 50 | 1000 | -| API requests/min | 120 | 600 | -| Max input file | 500 MB | 10 GB | -| Job timeout | 1 hour | 9 hours | -| Output retention | 7 days | 30 days | -| Priority queue | No | Yes | - -`ffmpeg`, MCP, and webhooks are on both plans. Full limits table: [Limits](/support/limits). +| | Free | Pro | Studio | +|---|---|---|---| +| Price | \$0/mo | \$9/mo | \$29/mo | +| Signup credits | $5 (one-time) | - | - | +| Monthly credits included | - | \$5 | \$20 | +| Credit-purchase bonus | - | +25% | +25% | +| Concurrent jobs | 1 | 20 | 50 | +| Queued backlog | 50 | 1000 | 2500 | +| API requests/min | 120 | 600 | 1200 | +| Max input file | 500 MB | 10 GB | 10 GB | +| Job timeout | 1 hour | 9 hours | 9 hours | +| Output retention | 7 days | 30 days | 90 days | +| Compose frame | Up to 1080p at 30 fps | Up to 1440p at 30 fps | Up to 4K at 60 fps | +| Compose with animated graphics | Up to 1080p at 30 fps | Up to 1080p at 30 fps | Up to 1080p at 30 fps | +| GPU FFmpeg (NVENC/CUDA) | No | Yes | Yes | + +`ffmpeg`, MCP, and webhooks are on every plan. Compose costs the same per output minute on every plan. Animated graphics above 1080p or 30 fps need an enterprise plan. Full limits table: [Limits](/docs/support/limits). For a full pricing breakdown and plan comparison, see [rendobar.com/pricing/](https://rendobar.com/pricing/). ## Credit packs -$10 / $25 / $50 / $100 (or custom, $10 minimum). Pro adds **+20%** to every purchase. Buy $25, get $30. Credits never expire. +\$10 / \$25 / \$50 / \$100 (or custom, \$10 minimum). Pro and Studio add **+25%** to every purchase. Buy \$25, get \$31.25. Credits never expire. ## How does nanodollar billing work? Every job is billed in nanodollars (one-billionth of a US dollar) drawn from your prepaid balance. This differs from tier-based quotas where you buy a plan with a bucket of minutes: -- **Cost matches resources used.** A 30-second 1080p job shouldn't cost the same as a 10-minute 4K render of a large master. -- **Prepaid means predictable budgets.** You top up when you want; jobs run only if affordable. No end-of-month surprise bill. +- **Cost matches the work.** Compute-billed jobs pay for the seconds they ran, and compose pays for the seconds of video it delivers. A 30-second 1080p job shouldn't cost the same as a 10-minute 4K render of a large master. +- **Prepaid means predictable budgets.** You top up when you want. Jobs run only if affordable. No end-of-month surprise bill. -## When do credits expire? +## When is a job charged? -1. **Submit gate.** Submit is atomic and does not reject on concurrency. If your balance is greater than zero the job is accepted. Jobs run at your plan's concurrency and any extra wait in a queue, starting in order as slots free. We do not estimate cost up front. A zero balance returns `402 INSUFFICIENT_CREDITS`, and a full queue returns `429 QUEUE_FULL`. +1. **Submit gate.** Submit is atomic and does not reject on concurrency. If your balance is greater than zero the job is accepted. Jobs run at your plan's concurrency and any extra wait in a queue, starting in order as slots free. We do not estimate cost at submit. For compose, `POST /compose/validate` returns the price before you submit. A zero balance returns `402 INSUFFICIENT_CREDITS`, and a full queue returns `429 QUEUE_FULL`. 2. **Execution.** Job runs. Balance untouched. -3. **Debit on terminal status.** Every terminal job (`complete`, `failed`, or `cancelled`) is charged for the compute it consumed. The debit is atomic with the status update. -4. **No auto-refund.** Failed jobs are still charged for the compute they consumed. If you believe a job failed due to a platform bug, contact support. Refunds are issued at our discretion via the dispute process. +3. **Debit on terminal status.** Every terminal job (`complete`, `failed`, or `cancelled`) settles its charge here. The debit is atomic with the status update. [How is a job priced?](#how-is-a-job-priced) covers what each job type pays for. +4. **No auto-refund.** Failed compute-billed jobs are still charged for the compute they consumed. A failed compose render follows its own rule, below. If you believe a job failed due to a platform bug, contact support. Refunds are issued at our discretion via the dispute process. ## What happens when a balance goes negative? @@ -69,7 +71,11 @@ Because the submit gate checks `balance > 0` rather than an estimate, a single l ## How is a job priced? -`ffmpeg` bills per compute second, which is the wall-clock time FFmpeg ran your command, excluding upload and download. The same per-second rate applies whether the job completes successfully or fails partway through. +`ffmpeg` bills per compute second, which is the wall-clock time FFmpeg ran your command, excluding upload and download. The same per-second rate applies whether the job completes successfully or fails partway through. Every job type except compose bills this way. + +`compose` bills per second of the video you get back, at \$0.04 per minute of output on every plan, with a 15-second minimum per render. Frame size and animated graphics do not change the rate. Plans differ in what they can render. 1440p needs Pro, 4K and 60 fps need Studio, and a video above your plan returns `403 PLAN_LIMIT` before it renders. An enterprise plan carries its own contract rate. Email `hello@rendobar.com`. + +A compose render that fails on Rendobar's side is free. When the failure may come from your input, such as the render tool exiting on a bad file, it pays for the compute it used at 2x. `POST /compose/validate` returns the price before you render. Full detail: [compose pricing](/docs/jobs/compose/pricing). If your balance is at or below zero when you submit: @@ -110,19 +116,20 @@ Returns daily usage by job type: count, amount charged, and compute seconds. ## Practical advice -- **Start on Free.** $5 signup grant covers many hundreds of small jobs. +- **Start on Free.** The $5 signup grant covers 125 minutes of compose output, or many hundreds of small FFmpeg jobs. - **Store `cost.nanodollars` from every response.** Reconcile against your monthly invoice. ## See also -- [Job lifecycle](/concepts/job): where the debit happens -- [Limits](/support/limits): full quota table -- [FFmpeg reference](/jobs/ffmpeg): the live cost model +- [Job lifecycle](/docs/concepts/job): where the debit happens +- [Limits](/docs/support/limits): full quota table +- [FFmpeg reference](/docs/jobs/ffmpeg): the per-compute-second cost model +- [Compose pricing](/docs/jobs/compose/pricing): the per-output-minute cost model ## Related -- [Plan limits and quotas](/support/limits): exact rate, file, and storage caps per plan -- [Job lifecycle](/concepts/job): when the debit lands and what statuses mean -- [Error codes](/support/errors): `INSUFFICIENT_CREDITS`, `PLAN_LIMIT`, and friends +- [Plan limits and quotas](/docs/support/limits): exact rate, file, and storage caps per plan +- [Job lifecycle](/docs/concepts/job): when the debit lands and what statuses mean +- [Error codes](/docs/support/errors): `INSUFFICIENT_CREDITS`, `PLAN_LIMIT`, and friends - [Pricing](https://rendobar.com/pricing/): plan comparison and credit packs -- [FAQ on cost](/support/faq): common pricing and billing questions +- [FAQ on cost](/docs/support/faq): common pricing and billing questions diff --git a/concepts/job.mdx b/concepts/job.mdx index 61c18c3..4d33b31 100644 --- a/concepts/job.mdx +++ b/concepts/job.mdx @@ -82,7 +82,7 @@ flowchart LR | `failed` | Errored. Read `error.code` and `error.message`. | | `cancelled` | Stopped before it finished. | -On any terminal status the job is billed for the compute it used, and a [webhook](/guides/webhooks) fires if you configured one. A job that never started settles free. Failures carry an `error.code` from the [error catalogue](/support/errors). A job that runs past its plan's time limit fails with `JOB_TIMEOUT` and is billed for the compute it consumed. A job a runner accepted but never started fails with `RUNNER_TIMEOUT` and is not charged. Cancelling a `running` job stops the upstream execution too. +On any terminal status the job is billed for the compute it used ([compose](/docs/jobs/compose/pricing) bills per second of output it delivers, and its failures follow their own rule), and a [webhook](/guides/webhooks) fires if you configured one. A job that never started settles free. Failures carry an `error.code` from the [error catalogue](/support/errors). A job that runs past its plan's time limit fails with `JOB_TIMEOUT` and is billed for the compute it consumed, except a compose render, which is free. A job a runner accepted but never started fails with `RUNNER_TIMEOUT` and is not charged. Cancelling a `running` job stops the upstream execution too. ## What does a job return? {#the-output} @@ -227,11 +227,11 @@ Poll `GET /jobs/{id}` every second or two until the status is terminal, or skip ## See also -- [Webhooks](/guides/webhooks): push status changes instead of polling -- [Credits and billing](/concepts/credits): how the terminal debit works -- [Error codes](/support/errors): every `error.code` a failed job returns -- [FFmpeg](/jobs/ffmpeg): a job type end to end -- [Compose](/jobs/compose): a render described as a JSON timeline -- [Compress](/jobs/compress): a job that searches encodes to hit a budget -- [Animated captions](/jobs/captions/animate): a job that transcribes and renders -- [Generate an image](/jobs/image-generate): the same job shape on a diffusion model +- [Webhooks](/docs/guides/webhooks): push status changes instead of polling +- [Credits and billing](/docs/concepts/credits): how the terminal debit works +- [Error codes](/docs/support/errors): every `error.code` a failed job returns +- [FFmpeg](/docs/jobs/ffmpeg): a job type end to end +- [Compose](/docs/jobs/compose): a render described as a JSON timeline +- [Compress](/docs/jobs/compress): a job that searches encodes to hit a budget +- [Animated captions](/docs/jobs/captions/animate): a job that transcribes and renders +- [Generate an image](/docs/jobs/image-generate): the same job shape on a diffusion model diff --git a/docs.json b/docs.json index 04a736a..d524378 100644 --- a/docs.json +++ b/docs.json @@ -64,15 +64,18 @@ "pages": [ "jobs/compose/index", "jobs/compose/timeline", + "jobs/compose/media", "jobs/compose/framing", - "jobs/compose/transitions", - "jobs/compose/motion", "jobs/compose/text", + "jobs/compose/captions", "jobs/compose/fonts", "jobs/compose/shapes", + "jobs/compose/motion", + "jobs/compose/transitions", "jobs/compose/effects", "jobs/compose/audio", "jobs/compose/output", + "jobs/compose/pricing", "jobs/compose/craft", { "group": "Reference", diff --git a/guides/webhooks.mdx b/guides/webhooks.mdx index 150d4e5..bde1a7c 100644 --- a/guides/webhooks.mdx +++ b/guides/webhooks.mdx @@ -70,7 +70,7 @@ const ok = await verifyWebhook(rawBody, req.headers, process.env.WEBHOOK_SECRET) if (!ok) throw new Error("invalid signature"); ``` -`verifyWebhook` rebuilds the signed string, checks the HMAC, rejects stale deliveries so a captured request cannot be replayed, and accepts either secret during a [rotation](#secret-rotation). It has no dependencies and runs on Node, Deno, Bun, Cloudflare Workers, and the browser. +`verifyWebhook` rebuilds the signed string, checks the HMAC, rejects stale deliveries so a captured request cannot be replayed, and accepts either secret during a [rotation](#how-do-i-rotate-the-signing-secret). It has no dependencies and runs on Node, Deno, Bun, Cloudflare Workers, and the browser. A full receiver on Express. The one rule: verify the raw bytes, before any JSON parser touches them. diff --git a/jobs/captions/animate.mdx b/jobs/captions/animate.mdx index a074aac..4d56625 100644 --- a/jobs/captions/animate.mdx +++ b/jobs/captions/animate.mdx @@ -105,7 +105,7 @@ curl -X POST https://api.rendobar.com/jobs \ Style overrides layered on top of `preset`. Any field set here wins. Unset fields fall through to the preset. Key fields: - - `font`: font family name. A [bundled family](#fonts) or the family name of a custom font you pass via the `font` input. + - `font`: font family name. A [bundled family](#which-fonts-can-i-use) or the family name of a custom font you pass via the `font` input. - `layout`: `phrase` (up to two balanced lines) or `word` (one word at a time). - `position`: `top`, `center`, or `bottom`. - `entrance`: `fade`, `pop`, or `bounce`. Each word reveals at its spoken moment. @@ -136,7 +136,7 @@ curl -X POST https://api.rendobar.com/jobs \ - URL of your own font file (TTF, OTF, TTC, WOFF, WOFF2). Captions render in it, and it takes priority over `style.font`, so you do not need to know the family name inside your own file. See [Fonts](#fonts). + URL of your own font file (TTF, OTF, TTC, WOFF, WOFF2). Captions render in it, and it takes priority over `style.font`, so you do not need to know the family name inside your own file. See [Fonts](#which-fonts-can-i-use). ## Which fonts can I use? diff --git a/jobs/compose/audio.mdx b/jobs/compose/audio.mdx index c6926e8..6b97a31 100644 --- a/jobs/compose/audio.mdx +++ b/jobs/compose/audio.mdx @@ -1,45 +1,115 @@ --- -title: "Audio levels and effects" -sidebarTitle: "Audio" -description: "Set levels and fades, clean up a voice recording, and draw sound onto the picture as a waveform or bars." +title: "Audio levels, mixing and effects" +sidebarTitle: "Audio and mixing" +description: "Set each clip's level, fade and duck music under a voice, pan and mix tracks, clean up a recording, and draw the sound onto the picture." icon: "waveform-lines" -keywords: ["video audio api", "audio normalize api", "audiogram api"] +keywords: ["video audio api", "duck music under voice api", "audio normalize api", "audiogram api", "mix audio json"] canonical: "https://rendobar.com/docs/jobs/compose/audio" --- -Sound is a clip like any other, and a `volume` on any clip that has audio sets its level. Fades sit next to it. Everything past that is an effect on the `sound` medium, and the same effect list works on a clip or on a whole track. +Sound comes from `audio` clips and from the sound in `video` clips. All tracks with sound play at once in one mix. Set each clip's level, then shape the sound with effects on a clip, a track or the whole mix. ```json { - "asset": { "type": "audio", "src": "https://example.com/music.mp3", "volume": 0.35, "fadeIn": 1.5, "fadeOut": 2 }, + "asset": { "type": "audio", "src": "https://example.com/music.mp3", "volume": 0.35, "fadeIn": 1.5, "fadeOut": 3 }, "length": "end" } ``` -## Levels that work +`length: "end"` runs the music to the end of the video, however long it is. +## Levels -`volume` is linear gain. With speech at 1.0: music under speech 0.10 to 0.12, music alone 0.35 to 0.5, sound effects 0.25 to 0.32. Fade music in over 1 to 2 seconds and out over 3 to 5, ending on the last frame. To duck music under speech, keep one music clip and put keyframes on its `volume`: 0.4 before the first word, 0.11 under the speech, back to 0.4 after it. `fadeIn` and `fadeOut` work alongside those keyframes. +`volume` is linear gain on a `video` or `audio` asset. `1` keeps the source level and `0` mutes it. Under speech at `1`, set music to `0.2` to `0.4`. On its own, set it to `0.35` to `0.5`. -## Cleaning up a recording +`fadeIn` and `fadeOut` fade an audio clip in from silence and out to silence, in seconds. Fade music in over 1 to 2 seconds and out over 3 to 5, ending on the last frame. -`loudness` brings a quiet recording to a streaming target. `voiceDenoise` removes steady background noise from under speech. `gate` closes the microphone between phrases, `highPass` cuts rumble below the voice, `eq` shapes it, and `compressor` evens out loud and quiet words. +## Ducking music under a voice -## Shaping and colour +Use one music clip and keyframe its `volume`: up before the first word, down under the speech, up again after. `fadeIn` and `fadeOut` still apply on top. -`reverb`, `echo`, `pitch`, `lowPass` and `limiter`. A limiter makes music louder without letting peaks clip. +```json +{ + "asset": { + "type": "audio", + "src": "https://example.com/music.mp3", + "volume": [ + { "time": 0, "value": 0.4 }, + { "time": 2.5, "value": 0.2, "easing": "easeInOutSine" }, + { "time": 9, "value": 0.2 }, + { "time": 9.6, "value": 0.4 } + ], + "fadeOut": 3 + }, + "length": "end" +} +``` + +## Panning + +`pan` places a clip's sound from `-1` (full left) through `0` (centred) to `1` (full right). It works on any clip with sound. + +```json +{ "asset": { "type": "audio", "src": "https://example.com/door-knock.mp3" }, "start": 4, "pan": -0.6 } +``` + +## The mix + +Music, a voice-over and the footage's own sound need no separate mixing step. An `effects` list works on a clip, a track or the timeline: + +- On a clip, it changes that clip's sound. +- On a track (`track.effects`), it changes everything on the track, such as every line of a voice-over at once. +- On the timeline (`timeline.effects`), it changes the final mix. Put a `limiter` or a `loudness` target here. + +```json +"timeline": { + "tracks": [ + { "clips": [{ "asset": { "type": "video", "src": "https://example.com/interview.mp4" } }] }, + { "clips": [{ "asset": { "type": "audio", "src": "https://example.com/music.mp3", "volume": 0.25 }, "length": "end" }] } + ], + "effects": [{ "type": "loudness" }, { "type": "limiter" }] +} +``` + +## Sound effects + +Each effect is an entry with a `type` and only the settings you change. + +| Effect | What it does | +| --- | --- | +| `loudness` | Sets sound to a standard loudness. Use -16 LUFS for online video and podcasts, -23 for broadcast. | +| `voiceDenoise` | Removes steady background noise from under speech: a river, a fan, a street. Not for music. | +| `gate` | Mutes the sound between phrases, so room noise drops out in the pauses. | +| `highPass` | Cuts everything below a frequency. Wind, traffic and handling noise sit below the voice. | +| `lowPass` | Cuts everything above a frequency: music from the next room, or a voice on the phone. | +| `eq` | Three-band tone control: more bass and treble on music, or less boom on a voice. | +| `compressor` | Evens out a voice so quiet and loud words play at the same level. | +| `limiter` | Stops peaks from clipping, with optional gain to make a track louder. | +| `pitch` | Raises or lowers the pitch without changing the speed. | +| `echo` | Adds a repeat behind the sound. | +| `reverb` | Makes a dry voice sound like it is in a hall. | + +A typical voice chain is `highPass`, then `voiceDenoise`, then `compressor`, then `loudness`. + +```json +"effects": [{ "type": "highPass", "cutoff": 80 }, { "type": "voiceDenoise" }, { "type": "compressor" }, { "type": "loudness" }] +``` ## Sound drawn on the picture -`visualizer` draws the sound onto the frame for an audiogram or a podcast clip, as a waveform, bars or a level meter. +`visualizer` draws the sound over the picture as a `waveform` or a `spectrum`, for an audiogram or a podcast clip. On the timeline, its usual place, it draws the final mix. On a track or a clip, it draws only that sound. + +```json +"effects": [{ "type": "visualizer", "kind": "waveform", "color": "#34D399", "y": "80%", "width": "76%", "height": "20%" }] +``` -Every sound effect and its parameters are in the [effect reference](/docs/jobs/compose/reference/effects). +The [effect reference](/docs/jobs/compose/reference/effects) lists every sound effect and its settings. The [Compose features page](https://rendobar.com/compose/features/#sound) plays each one before and after, with sound. diff --git a/jobs/compose/captions.mdx b/jobs/compose/captions.mdx new file mode 100644 index 0000000..a5e42c1 --- /dev/null +++ b/jobs/compose/captions.mdx @@ -0,0 +1,84 @@ +--- +title: "Subtitles and timers" +sidebarTitle: "Subtitles and timers" +description: "Add every subtitle of a video as one clip, written in the timeline or read from an .srt or .vtt file, and put a countdown or a stopwatch over a clip." +icon: "closed-captioning" +keywords: ["add subtitles to video api", "srt to video api", "countdown timer video api", "burn captions json"] +canonical: "https://rendobar.com/docs/jobs/compose/captions" +--- + +A `subtitles` clip shows every caption of a video, each at its time. A `timer` counts over its own length. Both take the same `style` as a [text clip](/docs/jobs/compose/text): font, size, colour, stroke, shadow and background box. + +## Subtitles + +Each cue has a `start` and an `end`, in seconds from the clip's start, and its `text`. + +```json +{ + "asset": { + "type": "subtitles", + "cues": [ + { "start": 0, "end": 1.8, "text": "Subtitles live in the timeline." }, + { "start": 2, "end": 4, "text": "One clip, every line." } + ], + "style": { "font": "Inter", "size": 44, "color": "#FFFFFF", "background": "#000000B0" } + }, + "transform": { "position": { "x": "50%", "y": "86%" } } +} +``` + + +