Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e3f31d9
docs(compose): price compose by output minute
a-essawy Oct 16, 2026
934ea7e
docs(compose): a render past its time limit is free
a-essawy Oct 16, 2026
81ea0f6
docs(compose): bill frames above 1080p at 2x
a-essawy Oct 16, 2026
f6b287b
docs(compose): use public filter names in the engine effect
a-essawy Oct 16, 2026
39e595a
docs: one compose rate and the plan frame limits
a-essawy Oct 16, 2026
c1362ac
docs(compose): add the Studio plan and Pro's 1440p limit
a-essawy Oct 18, 2026
072b2e0
docs(compose): regenerate the field reference
a-essawy Oct 20, 2026
cbd13a7
docs(compose): revamp the compose docs for the new engine
a-essawy Oct 20, 2026
d725bfc
docs(ai): point the integration prompt at the compose features page
a-essawy Oct 20, 2026
fd96814
docs: correct Studio retention, live job types and stale anchors
a-essawy Oct 20, 2026
086dc8b
docs(compose): regenerate the field reference with the animated-graph…
a-essawy Oct 20, 2026
6763248
docs(compose): scope animated graphics to top-level tracks, fix pricing
a-essawy Oct 20, 2026
1d29374
docs: add FEATURE_NOT_ENABLED, upgradeTo and the missing plan limits
a-essawy Oct 20, 2026
601a1d3
docs(compose): regenerate the field reference from the corrected schema
a-essawy Oct 20, 2026
adf24ba
docs: list ApiError.problems and prefix the job and credits links
a-essawy Oct 20, 2026
5ad38c5
docs: open the compose page descriptions with allowed verbs
a-essawy Oct 20, 2026
77f2acf
docs: state the rate limits in the limits description again
a-essawy Oct 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion automation/activepieces.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion automation/n8n.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions build-with-ai.mdx

Large diffs are not rendered by default.

75 changes: 41 additions & 34 deletions concepts/credits.mdx
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -15,61 +15,67 @@ 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" }
})
}}
/>

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?

Because the submit gate checks `balance > 0` rather than an estimate, a single long-running job can drive your balance briefly negative when the terminal debit lands. When that happens, further submits are blocked with `402 INSUFFICIENT_CREDITS` until you top up. Once your balance is positive again, jobs are accepted immediately. Nothing else on the account changes.

## 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:

Expand Down Expand Up @@ -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
18 changes: 9 additions & 9 deletions concepts/job.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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}

Expand Down Expand Up @@ -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
7 changes: 5 additions & 2 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion guides/webhooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
4 changes: 2 additions & 2 deletions jobs/captions/animate.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ curl -X POST https://api.rendobar.com/jobs \

<ParamField body="style" type="object">
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.
Expand Down Expand Up @@ -136,7 +136,7 @@ curl -X POST https://api.rendobar.com/jobs \
</ParamField>

<ParamField body="font" type="string">
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).
</ParamField>

## Which fonts can I use?
Expand Down
Loading
Loading