Skip to Content
ElectronActivating a license

Activating a license

When the state is MISSING_KEY, or the app is locked for a reason the customer fixes with another key, show an activation screen. When the customer submits their key, pass it to setLicenseKey:

import { LicenseError } from "@licenseman/electron"; try { await license.setLicenseKey(input); // The state is now ACTIVE: unlock the app. } catch (error) { if (error instanceof LicenseError) showError(error.code); else throw error; }
Activation window showing an error message under the license key field

What setLicenseKey does

Cleans the key

Spaces and line breaks around it are removed. Its case is kept: keys are case sensitive. An empty key throws a LicenseError with validation_error, without any request.

Validates it online

It sends the key, the fingerprint, the version, the machine name and the platform to LicenseManager, which registers this computer as a machine of the license. See validating license keys.

Verifies the token

The token LicenseManager answers with is verified like an offline token: its EdDSA signature with your public key, its product, its key, its fingerprint and its expiration.

Stores the key and the token, and activates

Only on success: the key and the token are stored, the state becomes ACTIVE, listeners are called, and the next renewal is scheduled. It resolves with the new state, ACTIVE.

When LicenseManager can’t be reached, or answers 408, 429 or 5xx, it retries for up to 30 seconds before throwing. Usually it resolves in under a second, but show a spinner, and disable the button, while it runs.

On any failure, including the network, it throws a LicenseError, and changes nothing: the stored key, the stored token and the current state stay as they were. A customer whose app is ACTIVE and who types a wrong key keeps their working license.

This is the one place where the SDK reports network errors to you. During background validations, a network error never changes anything visible: the SDK keeps running on the stored token. When the customer activates, there’s no token yet, so you must tell them.

The errors

Branch on error.code, never on error.message, which may change.

CodeWhat happenedWhat to show
not_foundThe key doesn’t exist in this product. Usually a typo, a truncated paste, or a key of another product, like a test key in a release build.“This license key wasn’t recognized. Copy it again from your purchase email.”
license_expiredThe license’s expiration date has passed.“This license expired. Renew it to keep using Acme Photo.”
version_not_allowedThe license doesn’t include this version. error.latestAllowedVersion holds the latest version it allows, or null when it allows none.“Your license includes Acme Photo up to 2.3.1.” With a download link, or an upgrade link when null.
machine_limit_reachedThe license is active on its maximum number of machines, and this computer isn’t one of them.“This license is already used on 2 computers. Deactivate one in your account to use it here.” With a link to the customer portal.
plan_limit_exceededYour organization went over its LicenseManager plan’s limits. Not the customer’s fault.“Activation is temporarily unavailable. Try again later, or contact support.”
validation_errorThe key is empty, or the request was refused as invalid, like a key over 255 characters.“Enter your license key.”
internal_errorSomething went wrong on LicenseManager’s side, still after 30 seconds of retries.“Activation failed. Try again in a few minutes.”
network_errorLicenseManager couldn’t be reached, still after 30 seconds of retries, or the server answered an error the SDK doesn’t know.“Couldn’t reach the license server. Check your connection and try again.”
invalid_responseLicenseManager answered without a token, or with a token that failed verification.“Activation failed. Check your computer’s date and time are correct.” See below.

The first four are the locking codes: error.isLocking is true for them. They say something about the customer’s license, and the customer needs to do something: another key, a renewal, another version, a free machine. The others say nothing about the license: the customer can try the same key again later.

See handling validation errors for each server error in detail.

invalid_response

The server answered, but its token didn’t pass verification. In practice, it means one of:

  • The computer’s clock is wrong. More than 2 hours behind, the token isn’t valid yet; ahead by more than its lifetime, it’s already expired. Ask the customer to set their date and time automatically.
  • The public key doesn’t match, like the key of another organization pasted in your code. Every activation fails: you’ll notice it while testing.
  • The product id doesn’t match the product the token is for.

error.status holds the HTTP status, 200.

The LicenseError

PropertyTypeWhat it holds
codeLicenseErrorCodeOne of the codes above.
messagestringThe server’s message, or one written by the SDK. For logs, not for your customers.
statusnumber | undefinedThe HTTP status, when the server answered. undefined for network errors and timeouts.
latestAllowedVersionstring | null | undefinedFor version_not_allowed: the latest version the license allows, or null when it allows none. undefined for the other codes.
isLockingbooleantrue for not_found, license_expired, version_not_allowed and machine_limit_reached.
causeunknownThe original error, like the fetch failure, when there is one.

Replacing a key

setLicenseKey works in every state, not only MISSING_KEY. Use it when the customer:

  • enters a new key after their license was refused, in INVALID_KEY, EXPIRED or MACHINE_LIMIT_REACHED,
  • upgrades to another license, like from a Personal to a Pro license,
  • buys a license after a trial license.

On success, the new key and its token replace the old ones. The computer stays an active machine of the old license on LicenseManager’s side, and keeps one of its places until you or the customer deactivate it.

The SDK has no method to remove the stored key or deactivate the machine. To sign the customer out, see a new computer.

Edge cases

The customer submits twice. Two calls with the same key while the first one runs share one request: both resolve, or both throw, with the same result.

A key entered while the startup validation still runs. The startup validation’s result is ignored once it comes back: only the new key counts. Simpler: wait for ready() before showing the activation screen.

A key in lower case. It’s sent as typed, so 7kq2m-… answers not_found when the key is 7KQ2M-…. Generated keys only use upper case letters and digits: if all your keys are generated, upper-case what the customer typed before passing it.

A key with spaces in the middle, like one copied across two lines. Only the spaces around it are removed: clean it up before passing it if your keys never contain spaces.

A custom fingerprint function that throws, or a missing version outside Electron. setLicenseKey rejects with that error as is, not a LicenseError: don’t assume every error is one.

Activating offline. It’s impossible: the first activation always needs LicenseManager. It throws network_error, after 30 seconds of retries.