Getting started
SoftLicense issues license keys for your software, validates them from your app, and keeps them in sync with your billing. This page walks through the four concepts and the ten-minute integration.
Concepts
| Concept | What it is |
|---|---|
| Product | One of your applications. Has a key prefix (e.g. ACME-…) and an Ed25519 signing key for offline certificates. |
| Policy | A reusable rule set: duration, machine limit, node-locked vs floating, grace period, what happens after expiry, and the entitlements returned to your app. |
| License | A key issued from a policy to a customer. Can be suspended, reinstated, extended, renewed or revoked. |
| Activation | A machine (identified by a fingerprint you choose) that holds one of a license's seats. |
Integrate in ten minutes
- Create a product and a policy in the dashboard (onboarding does this for you).
- Issue a license, or map a Stripe price so checkouts issue them automatically.
- In your app, call
POST /api/v1/licenses/activateonce with a stable machine fingerprint, thenPOST /api/v1/licenses/validateon launch. Readdata.valid,data.codeanddata.entitlements. - Optionally download an offline certificate for air-gapped installs and verify it with the product public key.
curl -X POST http://localhost:3000/api/v1/licenses/validate \
-H "Content-Type: application/json" \
-d '{"key":"ACME-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX","fingerprint":"<machine-id>","nonce":"<random>"}'Two APIs
Public license API (/api/v1/licenses/*): called from end-user machines, authenticated by the license key itself, rate limited, and every response is signed. Management API (/api/v1/* with Authorization: Bearer sl_live_…): called from your backend to create and manage licenses, customers, products, policies and webhooks. See the API reference.
Response envelope
{ "ok": true, "data": { ... } }
{ "ok": false, "error": { "code": "NO_SEATS", "message": "All activation seats for this license are in use." } }Validation codes
| Code | valid | Meaning |
|---|---|---|
VALID | true | Everything checks out. |
IN_GRACE | true | Expired, but inside the policy grace period. |
EXPIRED_RESTRICTED | true | Expired; policy says keep running with the restricted entitlements. |
EXPIRED, SUSPENDED, REVOKED | false | Stop or degrade the app. |
NO_SEATS | false | Activation refused: all machines are in use. |
FINGERPRINT_REQUIRED, FINGERPRINT_NOT_ACTIVATED | false | Activate this machine first. |
LEASE_EXPIRED, HEARTBEAT_EXPIRED | false | The seat lapsed; activate again. |
NOT_FOUND, MALFORMED_KEY, PRODUCT_MISMATCH | false | Wrong key or wrong product. |