Applying a licence key
After purchase, you receive a JWT in your inbox. To apply it:
In the UI
- Open Bee Flow as an organisation admin.
- Go to Settings → Organisation → Licence & usage.
- Paste the JWT into the Licence key field and click Apply.
The server verifies the signature against the bundled public key (license/bundled-public-key.pem) and updates the active tier immediately. Premium features become available without a restart.
Via env var (self-hosted)
Set BEEFLOW_LICENSE_KEY and restart the server. Useful for IaC / GitOps deploys where you don't want to paste keys through a UI.
echo 'BEEFLOW_LICENSE_KEY=eyJhbG...' >> .env
docker compose up -d beeflow-server
The env var takes precedence over a key applied via UI, so removing it falls back to whatever was last entered in the UI (or Community tier if neither is set).
Verifying the active tier
curl https://beeflow.example.com/api/license/status \
-H "Authorization: Bearer <admin_jwt>"
Returns:
{
"tier": "pro",
"expiresAt": "2027-05-09T00:00:00Z",
"features": [
"automations",
"webpages",
"meeting_notes",
"skills",
"ticket_assistant",
"voice"
],
"limits": {
"users": 25,
"agents": 20,
"messages": 50000,
"knowledgeBases": 100
},
"tenantId": "org_abc",
"issuedAt": "2026-05-09T00:00:00Z",
"lastVerifiedAt": "2026-05-09T12:34:56Z"
}
lastVerifiedAt is updated when the server polls the licence-server for revocation (BEEFLOW_LICENSE_REFRESH_URL, default every 24 h).
JWT structure
The licence is a standard JWT signed with the Bee Flow ECDSA P-256 private key. Header / claims:
{
"alg": "ES256",
"typ": "JWT"
}
.
{
"iss": "license.beeflow.ai",
"sub": "org_abc",
"tenantId": "org_abc",
"tier": "pro",
"limits": { "users": 25, "agents": 20, "messages": 50000 },
"features": ["automations", "..."],
"iat": 1715212800,
"exp": 1746748800
}
Verification logic lives in server/license/verify.js.
Rotating
Paste a new key at any time — it overwrites the old one. Two situations:
- Renewal — same tier, new
exp. Replace and you're done. - Upgrade (Pro → Enterprise) — premium features that were 403 immediately become reachable. Routes that were UI-hidden appear in the nav.
Removing
Clear the field and click Apply. The org reverts to the Community tier. Premium features become unavailable but all data is preserved — automations stop firing, but the definitions stay; vector KBs stay indexed but only local search is available; DLP audit log keeps its existing rows.
Re-applying a valid key restores everything.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
Invalid signature | Key was tampered with, or you pasted a key for a different deployment. | Verify the key matches what you received. |
License expired | exp is in the past. | Renew at https://beeflow.ai/pricing or contact tomkooy@beeflow.nl. |
Public key not found | BEEFLOW_LICENSE_PUBLIC_KEY_PATH set incorrectly. | Unset, or point at license/bundled-public-key.pem. |
Tier limit exceeded (after applying) | The new tier is lower than what you had — usage already exceeds the new limits. | Either upgrade, or trim usage (delete agents, archive automations) until under the limit. |
License revoked | The licence-server marked your key as revoked. | Contact tomkooy@beeflow.nl. |
Refresh failed (network) | BEEFLOW_LICENSE_REFRESH_URL unreachable. | Non-fatal — the key stays valid until exp. Whitelist the licence host. |
Air-gapped deployments
For air-gapped self-hosters:
# Disable the periodic refresh check
echo 'BEEFLOW_LICENSE_REFRESH_URL=' >> .env
# Or: serve a stub from your own host
# echo 'BEEFLOW_LICENSE_REFRESH_URL=https://my-licence-stub.internal/refresh' >> .env
The licence is valid offline through exp. To rotate, ship a new JWT.