Licensing
In short
Section titled “In short”A self-hosted installation needs a licence file from SpeculaPro. It is a small signed document that SpeculaPro checks offline, against keys built into the program. Nothing is sent anywhere to check it, and SpeculaPro never phones home unless you switch that on.
Licensing is designed so that it can never put your monitoring at risk. Whatever happens to the licence (it expires, it is missing, it fails verification, you go over a limit), the parts of SpeculaPro that watch your customers’ money keep working.
SaaS workspaces, which SpeculaPro operates, have no licence: SP_DEPLOYMENT=saas switches
licensing off entirely. Everything on this page is about self-hosted installations
(SP_DEPLOYMENT=selfhost, the default).
What a licence contains
Section titled “What a licence contains”| Part | Meaning |
|---|---|
| Licensee and licence ID | Who it was issued to, and its unique reference |
| Issued and expires | Its term |
| Grace period | How many days after expiry it keeps working without restrictions. 30 days unless the licence says otherwise |
| Edition and add-ons | What you bought, for example standard or enterprise |
| Limits | Workspaces; people (active and invited, across every workspace); transactions a month; a contracted peak of decisions a second. Each is optional: no limit means unlimited |
| Installation (optional) | The installation it is bound to. A licence without one works on any installation |
The file is a JSON envelope with four fields (format, key_id, payload, signature). The
signature is Ed25519, made by SpeculaPro over the format name and the payload together. It is
deliberately not a JWT: there is no choice of algorithm to get wrong, and the key_id lets
SpeculaPro rotate its signing keys without invalidating licences already issued.
Every licence you install is kept in the database exactly as issued, and its signature is checked again every time it is read. Editing the stored row can’t extend a licence.
The licence states
Section titled “The licence states”| State | When | What happens |
|---|---|---|
| Evaluation | No licence installed, for the first 30 days after installation | Everything works. Administrators see a banner in the last 7 days and are notified |
| Valid | A licence within its term | Everything works |
| Expiring | The last 30 days before the expiry date | Everything works. Administrators see a banner and are notified weekly |
| Grace | After the expiry date, for the grace period (normally 30 days) | Everything works. Administrators see a prominent banner and are notified weekly |
| Expired | After the grace period | Administrative growth is paused |
| Unlicensed (shown as No license) | No licence installed, and the evaluation period has ended | Administrative growth is paused |
| Invalid (shown as Not valid) | A licence is present but fails verification, or was issued for another installation | Administrative growth is paused |
The installation’s “installed” date, which starts the evaluation period, is the moment migration
00021_license ran: the first install for a new installation, or the upgrade that brought
licensing for an existing one. It lives in the database, so restarting or rescheduling SpeculaPro
doesn’t restart the evaluation.
When several licences are installed, SpeculaPro uses the one that verifies, belongs to this installation and runs longest. So you can install a renewal before the current licence expires: it takes over automatically on the right day.
What a lapsed licence pauses
Section titled “What a lapsed licence pauses”In the Expired, Unlicensed and Invalid states, and only then:
| Paused | Message the person sees |
|---|---|
Creating a workspace (speculapro tenant create). The first workspace is always allowed, so a new installation can be set up |
New workspaces are paused until a valid license is installed. Existing workspaces keep working. |
| Creating a rule, or drafting a new version of one, including from the visual builder | New rules and rule versions are paused until a valid license is installed (Settings → License). Monitoring continues; you can still enable, disable, approve and deploy existing versions. |
| Installing or upgrading a rule pack, including a signed pack update | Installing and upgrading rule packs is paused until a valid license is installed (Settings → License). Monitoring continues. |
The web app answers these with 403 and the message, which begins with the state, for example
License expired: ….
Everything else carries on, including:
- switching rules on and off, approving and rejecting versions already drafted, deploying them and running them in shadow, so your compliance team can still respond to a problem with an existing rule;
- inviting people (only the people limit below applies);
- every monitoring, case and reporting activity listed in the box at the top.
If SpeculaPro can’t work out the licence state at all, for example because the database didn’t
answer, it allows the action and logs license: state unknown; allowing. A licensing fault
never locks anyone out.
Limits
Section titled “Limits”| Limit | What it does |
|---|---|
| Workspaces | Creating a workspace beyond the limit is refused: The license allows N workspaces and this installation has N. |
| People | Inviting someone beyond the limit is refused. Active and invited people across every workspace count; disabled people don’t. Disable someone who no longer needs access to free a place |
| Transactions a month | Never enforced. Transactions are counted for your true-up report. Going over is shown on Settings → License and in the report, and nothing else happens |
| Contracted peak (decisions a second) | Never enforced. Shown for information |
The workspace and people limits only stop you going over them. Nothing already in place is removed or switched off.
How to get a licence
Section titled “How to get a licence”-
Get your installation’s fingerprint, if SpeculaPro will bind the licence to this installation. An administrator can copy it from Settings → License, or an operator can run:
Terminal window # Docker Composedocker compose run --rm cli license fingerprint# Kuberneteskubectl -n speculapro exec deploy/speculapro-api -- speculapro license fingerprint{"installation_id": "0199d4a2-6f1e-7c3b-9a52-3f0e8d2b1c47","installed_at": "2026-10-09T08:12:44Z","usage_public_key": "kY2l…"}The
installation_idis created once, in the database. It survives restarts and upgrades, and it moves with a database restore, so restoring a backup onto new servers keeps the licence valid. Theusage_public_keylets SpeculaPro check your usage reports. -
Send the fingerprint to SpeculaPro. Write to [email protected].
-
Install the licence file you receive, by one of the methods below.
How to install a licence
Section titled “How to install a licence”Use whichever suits your installation. They can be combined: SpeculaPro considers every licence it has and uses the one that runs longest.
In the web app
Section titled “In the web app”An administrator opens Settings → License, chooses the file under Install a license (or pastes its contents), and selects Install license. See Licence.
From the command line
Section titled “From the command line”# Docker Compose: put the file in deploy/compose/production/license/ firstdocker compose run --rm cli license install /etc/speculapro/license/license.jsonlicense LIC-2026-0042 for Acme Bank installed; expires 2027-10-31As a file the program reads
Section titled “As a file the program reads”Set SP_LICENSE_FILE to the file’s path. With the Helm chart, create a Secret holding the file and
name it in license.existingSecret; the chart mounts it read-only at /etc/speculapro/license and
sets SP_LICENSE_FILE for you:
kubectl -n speculapro create secret generic speculapro-license --from-file=license.jsonlicense: existingSecret: speculapro-licenseAn installed licence is checked before it is stored. These are refused, and nothing changes:
| Problem | Message |
|---|---|
| The signature doesn’t verify, or the file isn’t a SpeculaPro licence | license is not valid: … with the reason |
| The licence is for another installation | license is not valid: issued for installation <id>, this is <id> |
| The licence is past its grace period already | license is not valid: expired on <date> |
A licence file set with SP_LICENSE_FILE that can’t be read is skipped with the log line
license: cannot read SP_LICENSE_FILE; the other licences still count.
How to check the state
Section titled “How to check the state”docker compose run --rm cli license status # Composekubectl -n speculapro exec deploy/speculapro-api -- speculapro license status # KubernetesIt prints the state, the message administrators see, the dates, the licence details and the current
usage, as JSON. The same information is on Settings → License, in the
speculapro_license_state and speculapro_license_expiry_timestamp_seconds
metrics, and in the Helm chart’s licence
alerts.
Usage reports and true-up
Section titled “Usage reports and true-up”The worker counts transactions per workspace per day (by the date each transaction happened, in UTC), and recounts the last three days on every pass, so late-arriving transactions are included.
When SpeculaPro asks for a usage report, produce one for whole calendar months:
speculapro license usage-report --from 2026-07 --to 2026-09 --out usage.jsonWithout --from and --to, it covers the last three months and the current one. Administrators
can also download it from Settings → License, under Usage report.
The report lists, for each month, the transactions and the busiest day, in total and per workspace, plus the current number of workspaces and people. It is signed with your installation’s own key, so SpeculaPro can tell if it was changed after it left your network. It contains counts only: no customer data.
How administrators are told
Section titled “How administrators are told”| Where | When |
|---|---|
| A banner across the web app, linking to Settings → License | For people who can manage workspace settings, in every state except Valid. During evaluation, only in its last 7 days |
| A notification (email or text message, as each person chose) | To the same people in every workspace, at most once a week per state, from the last week of evaluation onwards. The link opens Settings → License |
The license: administrators notified warning in the worker’s log |
Each time those notifications go out |
Air-gapped installations
Section titled “Air-gapped installations”Licensing works entirely offline:
- Run
speculapro license fingerprintinside the network and carry the output out. - Carry the licence file back in and install it as above.
- For a true-up, run
speculapro license usage-reportinside, and carry the file out. Its signature shows if it was altered on the way.
Development and SaaS
Section titled “Development and SaaS”| Setting | Effect |
|---|---|
SP_DEPLOYMENT=saas |
Licensing doesn’t apply. Settings → License says Licensing does not apply to SpeculaPro-operated workspaces. |
SP_ENV=development |
States are worked out and shown, but nothing is paused. Messages end with (Not enforced: SP_ENV=development.) |