CLI workflow — push, versions, rollback
Iterating on templates locally with renduo push, versioning, and pinning an older version.
The renduo CLI is the primary loop for developing templates: write a React
component, push it, generate test PDFs, and iterate. This guide covers the
version lifecycle — creating versions, understanding what "active" means, and
recovering when a new version is wrong.
Setup
npm install -g @renduo/cli
export RENDUO_API_KEY=rnd_live_your_key_hereSee the CLI reference for the full command surface.
Push a template
renduo push Invoice.tsx --slug invoice --name "Invoice"The CLI bundles Invoice.tsx locally with esbuild (platform: browser,
format: iife, React as external), validates it, and registers it:
Template ID: 5f0c2e3a-…
Version: 1
Slug: invoiceYou can attach extra metadata and assets:
renduo push Invoice.tsx --slug invoice \
--sample-payload ./sample.json \
--schema ./schema.json \
--assets acme-sans,company-logo--sample-payload and --schema help the dashboard render a preview; --assets
declares which uploaded fonts/images this template uses (see the
custom fonts guide).
Versions: push the same slug again
Pushing the same slug creates a new version, it doesn't overwrite:
renduo push Invoice.tsx --slug invoice # → version 1
# …edit the component…
renduo push Invoice.tsx --slug invoice # → version 2 (now active)Each version is baked and immutable. The newest becomes active; the
previous is marked disabled. List your templates to see the state:
renduo templates list invoice v2 Invoice (2 days ago)Generate a test PDF
renduo generate 5f0c2e3a-… \
--props-file ./props.json \
--output out.pdfRollback after a bad push
Nothing here is destructive — versions are immutable by design, so reverting never loses anything. You have two options, and they answer different questions.
Make the previous version the default again
This is what you usually want after a bad push: one call, and every client goes back to the previous version, without changing any of their code.
curl -X POST https://api.renduo.dev/v1/templates/5f0c2e3a-…/versions/1/activate \
-H "Authorization: Bearer $RENDUO_API_KEY"Version 1 becomes active and version 2 becomes disabled, in a single
transaction. The call is idempotent, so it is safe as a step in a deploy
pipeline. It needs the templates:write scope — see
Templates & versions
for the full behavior, or templates.activate() in the
Node SDK.
The CLI has no command for this yet; use the endpoint above, the SDK, or the dashboard (Templates → your template → Reactivate).
Pin an older version for one call
If you only want some traffic on the old version — comparing output, or
regenerating a historical document — pin it per request instead of changing what
is active. A disabled version is still fully resolvable:
curl -X POST https://api.renduo.dev/v1/generate \
-H "Authorization: Bearer $RENDUO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "5f0c2e3a-…",
"version": 1,
"mode": "sync",
"payload": { "…": "…" }
}'The CLI itself always generates against the active version; to pin a specific version from the CLI, use the raw endpoint (as above) or pass the version to your own HTTP client.
Because versions are immutable, you never lose the old behavior — version: 1
renders exactly as it did when you pushed it, even after version 2 is active.
Tips
renduo whoamishows your organization, plan, current usage, environment, and key prefix — useful to confirm which key you're using.- If a push fails with
ASSET_NOT_FOUND, the declared asset doesn't exist yet:renduo assets listshows what you have.
See also
- Templates & versions — the model behind this guide.
- First PDF in 5 minutes — the minimal path.
- CLI reference — every command and flag.