Trials

Let people try your app before they buy. KeyGrant has two kinds of trial: one your app starts on a device with no key, and a key you issue under a trial license model.

KindStarted byLength set by
A device trial The app, with no key; one per device The product's Trial length
A trial key You: a license key issued under a trial license model The model's Trial length, days

Device trials

The product's Trial length, on its Settings tab, sets how many days a device trial lasts.

At a glance

Trial length
0 to 3,650 days; 0 means no trial
A new product
14 days
Trials per device
One for each product
Its lease
Runs to the trial's end, licenses one device, covers every version

Your app starts the trial:

Main process
const status = await license.status();
if (status.state === "unlicensed") { const trial = await license.startTrial(); if (trial.state === "trial") { showTrialBanner(trial.trialDaysLeft); } else { // Trials are off, KeyGrant could not be reached, or this device's trial is over. showActivationWindow(); }} else if (status.state === "trial") { showTrialBanner(status.trialDaysLeft);}
  • KeyGrant keeps one trial per device for each product, identified by the device's fingerprint. Starting a trial again on the same device resumes the same trial, and its start date can only move earlier.
  • The trial ends Trial length days after it started. Its lease carries the product's Trial entitlements (see Editions & entitlements).
  • A device trial is not a license: it does not count toward your plan, and no webhooks are sent for it.

What startTrial() returns

startTrial() has no error result. It returns a status:

SituationResult
Trials are off (Trial length 0) or the product is archived, and the device has no trial on record It does not get one: unlicensed
The device already has a trial, on an archived product It gets the trial back, which runs to its end
The device already has a trial, and Trial length is 0 It gets the trial back, over: expired with reason trial
KeyGrant cannot be reached The status the device already has

Buying from the trial

Give the app a Buy button that opens your Stripe Payment Link.

Main process
import { shell } from "electron";
// The Buy button, while the app holds no key.shell.openExternal("https://buy.stripe.com/your-payment-link");
// The customer types the key from the delivery email:const result = await license.activate(enteredKey);if (result.ok) showThanks();
  1. The customer chooses Buy and pays.
  2. The checkout creates the key and delivers it (see Key delivery email).
  3. The customer types the key into the app, which activates it with activate(key).
  • The checkout must create a key, so the link's price is mapped to a model (see Map prices to license models).
  • For a customer who already holds a key, open upgradeUrl(link) instead, so the sale finds their key (see Sell an upgrade).
  • How a purchase counts in Analytics: see Analytics.

Device trial details

Changing the trial while trials run

status() and refresh() do not request a new trial lease while the device's trial lease is valid. A shorter Trial length ends a trial already past it once startTrial() runs again.

Note

If you change Trial length or Trial entitlements while trials run, also call startTrial() on a launch in a trial: the example above calls it only on a device with nothing stored.

Analytics

  • Analytics counts a device trial as Came back after day one when KeyGrant hears from it 24 hours or more after the trial started. A trial started less than 24 hours ago is left out of that step.
  • The SDK reports a launch in a trial itself. When status() answers trial and neither a report nor a startTrial() has been made in the last day, it tells KeyGrant the app ran, in the background.
  • status() neither waits for that request nor reads its answer, and does not fail offline, so your app needs no extra call. An app left running for days is counted again when it calls status() a day later.
  • A trial bought in its first day stops reporting once it holds a key, so it counts as bought but not as come back.
  • The trial funnel counts a trial under Bought a license once a key a checkout created is activated on the device that ran it, when the trial started before the purchase.
  • Each trial and each purchase counts once: a second key bought on the same device, or another key of the same purchase, is not counted again. A key an upgrade offer creates, or one you issue by hand, from your server or by import, is never counted.

The launch report is in @keygrant/electron 0.3.1, .NET and Rust 0.2.1, Swift and C++ 0.2.0, and Dart 0.1.0, its first version. An app on an earlier SDK is counted as come back only when it calls startTrial() again.

Keeping a trial through a reinstall

KeyGrant ties the trial to the device, so reinstalling the app resumes it. An SDK can also store the trial's start date somewhere that survives an uninstall, using a registry stash. The SDK sends the earliest trial start recorded on the device with each trial request.

  • .NET, Rust and C++: include a Windows registry stash.
  • Swift: includes a Keychain stash.
  • Dart: uses a Keychain stash on iOS and iPadOS by default.
  • Otherwise: the default stash stores nothing.

Each SDK's page shows how to set its stash (see SDKs).

Trial keys

A license model of type Trial issues trial keys, by hand or from your server. A trial key is activated like any key, and its status is licensed.

  • Length: the model's Trial length, days, from the day it is issued.
  • Devices and versions: the model's device limit and versions (every version unless set otherwise).
  • Entitlements: the model's, or the product's Trial entitlements when the model grants none.

A checkout never creates a trial key

A paid checkout on a trial model's Processor price it maps to creates a paid key of that model:

  • A perpetual key for a one-time price, and a subscription key when the price recurs.
  • It takes the model's device limit, versions and Offline days.
  • It takes only the model's own entitlements, never the product's Trial entitlements.

When a trial key ends

  • KeyGrant sends a trial.ending webhook within a day of the key having 3 days or fewer left (see Events).
  • The customer also gets the Trial ending email when the product's License delivery tab is set to KeyGrant sends them, its Trial ending email is on, and the key has an email address and is not a test license.