License
Report Designer is licensed per render service installation. Your license key says who it is for, until when, and for how many installations. It is one
line of text (RD2.<payload>.<signature>), checked offline by the render service: nothing is sent anywhere.
Licensing never stops anything. Without a valid license, the render service still renders every document, but every page carries a watermark. The designer
(<report-designer>) needs no license at all.
Licenses at a glance#
| Production license | Evaluation (trial) license | |
|---|---|---|
| Comes with | the key you receive when you buy | the release download (built in), or a trial key from us |
| Expiry | always has an expiry date | may have none |
| PDFs from the render API and the CLI | clean | watermarked "TRIAL VERSION" |
| After expiry | every page watermarked "TRIAL VERSION" with a "License expired" note, until you install a renewed key (no grace period) | the same, if it has an expiry date |
How PDFs are watermarked#
The watermark is drawn by the engine on top of every page, from built-in outlines: templates, fonts and render options can't hide, cover or replace it. Rows of "TRIAL VERSION" are tiled diagonally across the page, and a short note at the bottom says why:
| License | X-License-Status | Watermark | Note at the bottom of each page |
|---|---|---|---|
| Valid production license | valid | none | none |
| Trial license (evaluation) | trial | TRIAL VERSION | "Generated with a Report Designer trial license" |
| Expired license (production or trial) | expired | TRIAL VERSION | "License expired — generated with an expired Report Designer license" |
| No license key | missing | TRIAL VERSION | "Unlicensed — generated without a valid Report Designer license" |
Key not accepted (mistyped, truncated, edited, unreadable LICENSE_FILE) | invalid | TRIAL VERSION | "Unlicensed — generated without a valid Report Designer license" |
The render API answers 200 in every case, and rd-render / reportdesigner render exit with status 0. Only the X-License-Status header (and
license / watermark in ?format=json responses, API reference) tells you the PDF is watermarked.
Previews in the designer#
The designer is for authoring templates; the final documents always come from the render service, from template + data. The designer therefore has no
license and checks none. The PDFs its Preview shows (and renderPdf() returns) carry a light "PREVIEW" watermark with the note "Design preview — final
documents are rendered by the Report Designer service". This is the same with or without a license, and never affects the template.
How to get a license#
Email support@bhelabs.com with:
- Company name: the licensee, exactly as it should appear in the license and on the Status page;
- Number of installations: how many render services you will run, including test and staging servers;
- Term and start date: how long the license should run and from when.
We reply with your license key: one line of text that starts with RD2., valid through its expiry date. Install it as described in
Install your license.
Renewals#
Ask for a renewed key before your license expires; the Status page shows the expiry date and the days left. Install the new key the same way and restart the render service: nothing else changes, and your templates and integrations keep working. There is no grace period, so renew in time (see When a license expires).
Changes#
More installations or a new company name need a new key. Email us with your license id (shown on the Status page) and the change; install the new key and restart.
Lost key#
Email us your company name and, if you have it, the license id from the Status page. We keep a record of every key we issue and send it again.
The evaluation license#
The release download (the reportdesigner executable and its Docker image) includes an evaluation license that never expires, so everything works right
away. On it, every page of every PDF carries the "TRIAL VERSION" watermark. A trial key you receive from us works the same way; it may have an end date.
The npm packages (@rd/server, @rd/core) carry no evaluation license: without a license key, their PDFs are watermarked as unlicensed.
Install your license#
Set one of these environment variables for the render service and restart it:
LICENSE_KEY: the license key itself, suited to secret managers and Kubernetes secrets;LICENSE_FILE: the path of a file that holds it, for example a mounted secret.
docker run -d -p 8080:8080 \
-v /opt/reportdesigner/license.txt:/run/secrets/reportdesigner-license:ro \
-e LICENSE_FILE=/run/secrets/reportdesigner-license \
reportdesigner:1.0.0
As soon as one of them is set, that license decides, and the evaluation license is no longer used: a configured key that is expired, not valid or not readable never falls back to it. More examples (Kubernetes, systemd): Deployment.
The Status page and GET /v1/info show the license in use: where it comes from (bundled evaluation license or configured license), whether it is
a trial, the licensee, the license id, the expiry date and days left, the number of installations, and this installation's id. The server also logs one line
about the license when it starts.
With @rd/core directly#
If you call the engine yourself, for example in a Node batch job, pass the license key in the options. Expiry is always checked against the real clock, never
against options.now:
import { readFileSync } from 'node:fs';
import { renderPdf } from '@rd/core';
const template = JSON.parse(readFileSync('bol.template.json', 'utf8'));
const data = JSON.parse(readFileSync('bol.data.json', 'utf8'));
const license = process.env.LICENSE_KEY; // the RD2.… key; undefined → watermarked as unlicensed
const { pdf, pageCount, license: info } = await renderPdf(template, data, { license });
console.log(`${pageCount} pages, license ${info.status}, watermark ${info.watermark ?? 'none'}, ${pdf.length} bytes`);
Installations#
Your key states the number of installations it covers. Each running render service shows its installation id on the Status page and in
GET /v1/info; keep the number of servers you run within your license (it is part of the license terms, not a technical limit).
The id is derived from the host name, so a container that is recreated gets a new one. Set RD_INSTANCE_ID for a fixed id (for example the pod or service
name), or set RD_DATA_DIR to a persistent folder where the server keeps a random seed for it. Without RD_DATA_DIR the server writes nothing.
When a license expires or is not valid#
A license works through the end of its expiry date (UTC). There is no grace period: from the next day on, every page carries the watermark with the
"License expired" note until you install a renewed key. The same happens at once when the configured key is not valid (mistyped, truncated, or a
LICENSE_FILE that cannot be read), with the "Unlicensed" note. Rendering, the portal, the Status page, /v1/info, /health and /sdk/ keep working.
A running server notices the expiry by itself (it checks on every request and at least once an hour) and logs one line when the license status changes.
Before the expiry date there are no warnings in the API, the CLI or the logs: check the Status page or GET /v1/info (license.daysLeft) in your monitoring
(Deployment), and renew in time.
Troubleshooting#
| You see | Check | Fix |
|---|---|---|
| "TRIAL VERSION" with "Generated with a Report Designer trial license" | Status page: source Bundled evaluation license (no LICENSE_KEY / LICENSE_FILE reached the process), or a trial key | Set LICENSE_KEY or LICENSE_FILE with your production key and restart; make sure the variable reaches the container |
"License expired" note, X-License-Status: expired | The expiry date on the Status page | Install your renewed key and restart |
"Unlicensed" note, X-License-Status: invalid | The server log's license line says why: the file can't be read (path or mount), or the key is incomplete or changed (line breaks from email) | Send the key to the server as a file, or ask us to resend it |
"Unlicensed" note, X-License-Status: missing | npm installation without a key | Set LICENSE_KEY or LICENSE_FILE |
| "PREVIEW" on designer previews | By design | Final PDFs come from the render API |
Questions#
- Does the render service contact you to check the license? No. The key is checked offline with a digital signature; nothing is sent anywhere. That also means it works in networks without internet access.
- How do I know when to renew? The Status page and
GET /v1/infoshow the expiry date and the days left (license.daysLeft). There are no reminders in the API or the logs, so add it to your monitoring. - Can I move my license to another server? Yes: install the same key there and stop the old server. The key is not tied to a machine.
- Can I edit the key, e.g. to extend the date? No. Any change breaks the signature and the key is rejected (watermarked as unlicensed).
- Do my template authors need a license? No. The designer needs none; only the render service does.
- What do my users see when it expires? Documents keep coming, with the watermark on every page. Nothing else changes in your application.