Skip to content

Licensing

BroadPaper is free to evaluate and there is nothing to sign up for.

bash
pnpm add @broadpaper/core @broadpaper/blocks @broadpaper/renderer @broadpaper/editor @broadpaper/react
pnpm add @broadpaper/forme

Everything works: every block, both PDF backends, the designer, data binding, themes, custom blocks, the render service and your real data. There is no trial clock, nothing expires, and no feature is behind a wall. Evaluate it for as long as you like; production use needs a licence.

In the software, one thing is different without a licence: generated PDFs carry a BroadPaper evaluation mark. A licence removes it, and under the licence agreement it is also what permits production use.

A licence is twelve months of unwatermarked commercial use, including every update released in those twelve months and support throughout. Renewing buys the next twelve.

What BroadPaper does not do

Worth stating plainly, because most SDKs at this price do at least one of these:

  • No trial period, and nothing that stops working after n days.
  • No feature gates. Both licences unlock exactly the same software.
  • No per-developer seats, no activation, no machine or MAC-address binding.
  • No domain locking.
  • No telemetry, and no call home — not on render, not on start-up, not ever. The SDK makes no network request of its own under any circumstances.
  • No licence server. PDF generation works with no route to the internet, and always will.

Licences are verified locally against a public key compiled into the package. We never see your templates, your data or your documents.

Configuring a licence

Set one environment variable:

bash
BROADPAPER_LICENSE=BP1.eyJzY2hlbWFWZXJzaW9uIjox…

Any package that generates a PDF picks it up. That is the whole integration.

Where an environment variable is not available — a browser bundle, a build-time constant, a configuration file you already have — configure it once at start-up instead:

ts
import { BroadPaper } from "@broadpaper/forme";

BroadPaper.configure({ license: process.env.BROADPAPER_LICENSE });

configure is process-wide and idempotent. Call it once, as early as you can — in your server's entry point, or in your app's bootstrap. It is exported from @broadpaper/forme, @broadpaper/pdf and @broadpaper/server, and they all write to the same place, so it does not matter which one you import it from.

Deliberately, there is no per-render licence argument in normal use. Threading a licence through every export path is how one path ends up forgetting it, and the way you find out is a customer's month-end report arriving stamped "Evaluation Copy".

Multi-tenant hosts

If one process really does render on behalf of several licensed organisations, every render function takes an optional license that overrides the configured one for that call.

The licence is not a secret

It is a signed certificate, not an API key. It says who bought what and until when, and BroadPaper signed it with a private key that only we hold.

That means it is safe in places a credential is not:

  • a browser bundle, where anyone can read it;
  • a container image;
  • a repository, if you want it there;
  • a build log.

Someone who copies your licence cannot change what it says — editing a single character of the payload breaks the signature — and cannot manufacture another one. Use of BroadPaper is governed by the licence agreement; the certificate is how the software knows which agreement applies, not a lock.

What a licence looks like

text
BP1.<base64url payload>.<base64url signature>

The payload is readable — it is base64, not encryption:

json
{
  "schemaVersion": 1,
  "keyId": "bp-2026",
  "licenseId": "lic_7k2m…",
  "organisationId": "org_2abc…",
  "organisationName": "Acme Ltd",
  "product": "broadpaper-sdk",
  "plan": "saas",
  "licenseType": "subscription",
  "issuedAt": 1788000000,
  "validUntil": 1819536000,
  "updatesUntil": 1819536000
}

validUntil is when the right to use the software ends and updatesUntil is when the right to updates ends. For the licences sold today they are the same date, because what you buy is twelve months in which both hold. They are two fields rather than one so that a licence whose two clocks genuinely differ can be issued without changing the format — which would mean reissuing every certificate in the field.

The signature covers all of it, including keyId, so a licence cannot be re-pointed at a different key. BP1 is the string format version and schemaVersion is the payload's, and both move independently: a licence in a format your SDK predates is reported as "needs a newer BroadPaper", not as corrupt. Fields are only ever added, never renumbered — an SDK that meets a field it has never heard of carries it and honours the licence.

Licence states

StatePDFsWhat the SDK does
No licenceWatermarkedLogs once, at start-up, saying so
Malformed or tamperedWatermarkedLogs what is wrong with it
Signed by an untrusted keyWatermarkedLogs that the key is not one this build trusts
For a newer BroadPaperWatermarkedLogs that the SDK needs updating
ValidCleanNothing
Expired, within 30 daysCleanLogs a renewal warning
Expired, beyond 30 daysWatermarkedLogs that it has expired

Two things worth noticing.

Nothing ever fails. A missing, broken or expired licence never throws, never refuses to render and never returns an error. It produces a watermarked PDF and a line in your log. A typo in a configuration file must not be able to take down a payroll run.

There is a 30-day grace period. A licence keeps working for a month after it expires, warning as it goes. A card that expired over a holiday is an accounts-payable problem, not an incident.

Checking the state yourself

Useful in a health check, or to fail your own deployment when production is unlicensed:

ts
import { resolveLicenseStatus } from "@broadpaper/forme";

const status = await resolveLicenseStatus();

status.state;          // "active" | "grace" | "expired" | "unlicensed" | "invalid" | …
status.licensed;       // true when PDFs render clean
status.plan;           // "internal" | "saas" | null
status.validUntil;     // Date | null
status.daysRemaining;  // number | null

The render service reports the same thing on GET /health, so an operator can see what a deployment is producing without generating a document to find out.

Plans

Two licences. They unlock identical software; what differs is what you may build with it.

Internal — BroadPaper may be used in software intended for your own organisation's users: employees, contractors, and other people working for you.

SaaS / OEM — required when BroadPaper's functionality is incorporated into software made available to customers or any other external third party: a SaaS product, an embedded product, something you ship or host for other people.

This is a commercial distinction, not a technical one, and BroadPaper makes no attempt to detect which you are doing — it could not, and trying would mean the telemetry and network calls this product exists to avoid. The plan is recorded in the signed licence, displayed in your account, and defined by the licence agreement.

Renewals

Licences run for a year, expiring when the period you have paid for does.

When a subscription renews, a new licence is issued automatically and appears in your account. Copy it into your configuration in the ordinary course of a deploy — you have a month to do it, because the old one keeps working through its grace period.

Cancelling does not revoke anything. A licence stays valid until the end of the period it was paid for, and then lapses on its own.

When a licence lapses, output goes back to carrying the evaluation mark — a month after expiry, once the grace period has run out. Nothing stops working, nothing is deleted, and your templates and documents are yours whatever the licence says; what a licence buys is a year of clean output, and a lapsed one stops buying it. That is the whole of it, stated plainly here because a surprise about it would arrive on a customer's month-end report rather than in your logs.

Evaluation output

The mark is one line across each page — light, diagonal, and behind the content, so an evaluation PDF is entirely readable and unmistakably not for production. It is applied at the point a PDF is produced, so it is the same through the browserless engine, the Chromium backend, the render service and the designer's print dialog.

The PDF's Producer records which licence produced the file — BroadPaper (lic_7k2m…), or BroadPaper (evaluation). That is a licence id, not an account or a person, and it is the only identifying thing BroadPaper puts in a document.

Development and production keys

Licences we issue for testing are signed with a different key from the one production licences use, and released SDKs do not trust it. A development licence therefore produces watermarked output in a production build, which is the point: nothing signed on a laptop can become a production licence by accident.

To honour a development licence locally, name its key:

bash
BROADPAPER_TRUSTED_KEYS='[{"keyId":"bp-dev-1","publicKey":"s5aZ8HYu…"}]'

or pass trustedKeys to configure. Production licences need none of this.

Buying one

Pricing and both plans are on the pricing page. A licence belongs to your organisation rather than to whoever paid, so anyone you add to it can see and use the same licence.