Skip to main content
Good licensing UX is invisible when things work and helpful when they don’t. These patterns ensure your customers have a smooth experience.

First-run experience

The first time a user launches your app, they need to enter a license key. Make this frictionless:

Desktop apps

Show a clean, focused dialog. Don’t overwhelm with options; just a single input field and an activate button.

Welcome to YourApp

Enter your license key to get started

XXXX-XXXX-XXXX-XXXX
PurchaseActivate
  • Auto-format the input as the user types (add dashes automatically).
  • Accept keys with or without dashes.
  • Show a “Purchase” link for users who don’t have a key yet.
  • Trim whitespace; users often copy keys with trailing spaces.

CLI tools

Support multiple input methods to minimize friction:

Storing the key locally

After successful validation, save the key locally so users don’t re-enter it on every launch.
On subsequent launches, load the stored key and authenticate silently:

Settings page

Provide a settings or “About” page where users can see their license status:
  • Mask the license key (show first and last groups only).
  • Show the expiry date prominently.
  • Include a “Deactivate” button that clears the stored key and returns to the license dialog.
  • If using license variables, show the plan tier.

Expiration and renewal

When a license is approaching expiration, show gentle reminders:
When the license has expired, show a clear message with a path to renewal:

Your license has expired

Your license expired on December 31, 2026.
Renew to continue using YourApp.

Enter New KeyRenew

Trial mode

Use the Developer API to issue time-limited trial licenses:
In the app, show the remaining trial period:

Upgrade prompts

When a user on a lower tier tries to use a gated feature, show a helpful prompt instead of silently failing:

Graceful degradation

If your app has a free tier or limited mode, fall back to it instead of killing the app entirely:

Error messages

Always show user-friendly messages. Map internal error codes to helpful text: Never show internal error codes like no_credits or invalid_app to end users.

Offline first launch

The initial authentication always requires a network connection. Make this clear:

Connection Required

YourApp needs an internet connection to activate. After that, it keeps working without a connection for up to 24 hours before it needs to check in again.

Retry
After initial activation, the app runs through the grace period with no network access needed until the signed session expires (24 hours by default; up to 7 days if the SDK was configured with a longer ttlSeconds). If you enable online check-ins, the app needs connectivity while it runs. Do not describe the grace period to users as “works offline”: it is a temporary window, not offline licensing. Customers whose machines never connect need an offline license file instead, and that flow has its own UX (import a file, show its expiry, show the machine ID on failure).