# FAQ

Short answers to common integration questions: offline use, virtual machines, reinstalls, trials, upgrades and more.

## Does my app need internet access?

Once, to activate. After that the certificate is verified locally at every launch. The SDK refreshes it silently when the network is available, and it stays valid offline for `offlineDays` (30 by default, set per product).

## What happens when a customer reinstalls the OS or replaces the disk?

A clean install usually regenerates the machine identifier (`MachineGuid` on Windows, `/etc/machine-id` on Linux), so the machine looks new and activating it uses another seat. Updates and app reinstalls don’t change it. The customer frees the old machine from the [customer portal](/docs/customer-portal/), or you do it from the license page of the dashboard (**Free this machine**).

## What about virtual machines and cloned images?

A cloned image keeps the machine identifier of its source, so clones share one fingerprint and one activation. If that matters for your product, lower `maxActivations` (**Machines per seat** on the plan) and watch the **Machines** of each license in the dashboard.

## Can one key be used on several computers?

Yes, up to the activation limit: `plan.maxActivations × license.seats`, or a per-license override. For example, a plan with `maxActivations: 2` lets a customer use a desktop and a laptop.

## Can I offer a trial?

Create a plan with `kind: "trial"` and `trialDays`. The license is `active` until `paidUntil` (now + `trialDays`) plus the grace period, then `expired`. A purchase can then create the paid license.

## How do I sell upgrades for perpetual licenses?

Set `maxMajor` on the perpetual plan (for example `1`). Version 2 of your app reports `version_not_covered` for those licenses. When a customer buys the upgrade, raise `maxMajor` on their license with `PATCH /v1/licenses/{id}`, or sell a new plan.

## What does the customer see when a subscription is canceled?

Nothing changes until the end of the paid period plus the grace period (`validUntil`). Then the license is `expired`: certificates never outlive `validUntil`, so the app stops validating at that date, and the next refresh fails with `license_expired` and clears the cached certificate.

## Do refunds disable the app immediately?

The next refresh is refused with `license_refunded` and the SDK clears its cached certificate, so the app loses access at its next refresh once online, and at the latest when its current certificate expires if it stays offline. A new payment for the same license lifts the refund.

## Can I use Keyrail without Paddle or Lemon Squeezy?

Yes. Create licenses from the dashboard (**Licenses → New license**) or with `POST /v1/licenses` from your own checkout. Stripe support is planned.

## Which platforms are supported?

Windows, macOS and Linux. Tauri 2, Electron and native Rust apps have SDKs today; .NET is next. Any other stack can use the [client API](/docs/client-api/) and the [certificate format](/docs/offline-certificates/).

## Where can I see what happened to a license?

In the **History** of the license page in the dashboard, in [Events](/docs/dashboard/#events), or with `GET /v1/events?license=lic_…`: webhooks received, status changes and activations. Something went wrong? See [troubleshooting](/docs/troubleshooting/).

## What if Keyrail shuts down, or I want to leave?

Nothing locks you in: certificates already issued keep verifying offline until they expire, the account owner can download every license key and every private signing key, the certificate format and the SDKs are open, and the SDKs take any API base URL. We commit to at least 90 days' notice before discontinuing the service. The details, including what is **not** covered, are on the [security page](/security/#continuity).
