Testing your integration

Exercise a KeyGrant integration without real customers, before you ship.

There is no separate test environment: a test license is signed with your product's real signing key, so it works in the build you are developing, and its lease carries test: true.

A test license

Lasts
No later than 30 days after it is created
Grace period
None
Active at once
25 test licenses an account, across all products
Your plan
Does not count toward your plan's active licenses
Current version
Not changed by a test license
Emails
No renewal, trial-ending or device-limit email

Warning

A test license licenses the app like any other, in a release build too, unless the app refuses it (see Keep test licenses out of release builds).

From the dashboard

  1. On a product's Licenses tab, choose Create test license.
  2. Pick a Scenario.
  3. When the product has more than one license model that is not archived, pick the model too.

Pick the scenario for the screen you want to see:

  • Valid: activates and checks in as licensed until it expires.
  • Trial ending: a trial that ends 24 hours from now. It ignores the model choice and uses the product's trial model, if it has one.
  • Expired: expired an hour ago, so a check-in is refused.
  • Revoked: revoked when it is created, so a check-in is refused.
  • At its device limit: one device allowed and already taken, so activating is refused.
  • Used up: a metered license whose first meter has no uses left, so use() is refused. Offered only on a product with a license model that counts uses, and it asks only among those models (see Metered uses).

Test licenses created here send no delivery email. A test license carries its model's meters and spends them as a live key does.

From your server

On API keys, choose Create secret key with the type Test. Its secret starts with kg_test_.

  • Every license it issues is a test license.
  • It can see and change only test licenses: a request for a live license gets the same response as an unknown license.
  • Use one in development and CI, and a kg_live_ key in production. See Managing licenses from your server.

The scenarios above can be created from your server too, with either kind of secret key:

  • POST /v1/test-licenses: see Server endpoints. Its request limits are in Rate limits.
  • The CLI's keygrant licenses test, which offers Used up from version 0.5.0: see CLI.

From a Stripe checkout

A paid checkout in Stripe's test mode, on your linked account, creates a test license, so you can rehearse a sale end to end.

  1. Map a license model to the test-mode price, as described in Selling through Stripe. Test-mode and live prices have different IDs, and a model maps to only one price.
  2. Buy it through a checkout in Stripe's test mode.
  • It gets the delivery email only when the product's License delivery tab is set to KeyGrant sends them and its Key delivery email is on (see Key delivery email).
  • Once your account has 25 active test licenses, a test checkout creates no key.

From a Paddle sandbox checkout

A checkout in your Paddle sandbox, on the sandbox you linked, creates a test license (see Selling through Paddle). The sandbox price has its own ID, so name the product and model in the price's custom data, or map the model to the sandbox price. Once your account has 25 active test licenses, a test checkout creates no key.

Webhook events

An endpoint receives events for test licenses only when Send test license events is turned on for it. See Webhooks.

  • Those events carry a top-level test: true, so your handler can tell them apart; events about real customers are unchanged.
  • Send a test event on an endpoint's page sends one fixed sample request regardless of that setting.

Keep test licenses out of release builds

status() returns a licensed status with test: true for a test license, so refuse it in release builds:

Main process
import { app } from "electron";
const status = await license.status();// status.test is true on a licensed status from a test license.if (status.test && app.isPackaged) showActivationWindow();