Validating Licenses

Use Keygen's API and your code to validate licenses for your product. If you need help after reading this, can reach out to us anytime at [email protected].

This tutorial is written in JavaScript, but you can follow along in any other language that you're comfortable in. Throughout this tutorial, you will see placeholders e.g. {ACCOUNT} within the code examples that will need to be replaced with your account's slug (or ID), or other resource information.

Before getting started, you will either need to log into your Dashboard and generate a product token, or generate an authentication token via the API. To create a token directly through the API, check out the code examples in the API reference or check out our guide on authenticating users.

If you are using product tokens, the code for this tutorial should not be written client-side. If you are wanting to allow users to create licenses for themselves client-side, then you should authenticate them and use an authentication token which belongs to them; otherwise, all code should be server-side.

Your admin and product tokens carry many privileges and should always be kept secret. Do not share your secret API tokens in publicly accessible areas such GitHub, embed them in client-facing code e.g. inside of your product, and so forth. Learn more.


For simplicity, we're going to be requesting a single license while authenticated as a user. When you list all licenses while authenticated as a user, the response will be automatically scoped to the user you're authenticated as—that is, it will only respond with a list of licenses that the user is associated with.

const licenses = await fetch(`https://api.keygen.sh/v1/accounts/{ACCOUNT}/licenses?limit=1`, {
  method: "GET",
  headers: {
    "Content-Type": "application/vnd.api+json",
    "Accept": "application/vnd.api+json",
    "Authorization": "Bearer {USER_TOKEN}"
  }
})

const { data: [license] } = await response.json()
if (!license) {
  // User has no licenses
}
In a real product, you may want to request and validate every license that a user owns to determine what the user is allowed to do within your product, and then save that in some type of storage so that it can easily be queried without additional network requests.

Validate by license

To validate a license directly, send a POST request to the license's validate action. Validating a license requires an authentication token. We recommend using a token that belongs to one of your users, but if you're validating licenses server-side, then using an admin or product token also works.

The response of the validation request will be a meta object containing the result of the validation: a meta.valid boolean, a meta.constant machine-readable constant, and a meta.detail human-readable description of the validation result.

// … above code

const validation = await fetch(`https://api.keygen.sh/v1/accounts/{ACCOUNT}/licenses/${license.id}/actions/validate`, {
  method: "GET",
  headers: {
    "Content-Type": "application/vnd.api+json",
    "Accept": "application/vnd.api+json",
    "Authorization": "Bearer {USER_TOKEN}"
  }
})

const { meta } = await validation.json()
if (meta.valid) {
  // … do something
} else {
  // … do something else
}

Validate by key

If you would rather validate a license by key, you can use the validate-key action. Unlike the earlier validate action, this one does not require an authentication token. This action is especially useful if you aren't using Keygen to manage users, and would rather generate and validate license keys directly. This is the simplest form of licensing, but is also the least flexible—making it difficult for users to have multiple related licenses—and it also requires your users to keep track of their keys, rather than an email and password.

The response of the validation request will be a meta object containing the result of the validation: a meta.valid boolean, and a meta.detail human-readable description of the validation result.

// … above code to request a license

const validation = await fetch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/licenses/actions/validate-key", {
  method: "POST",
  headers: {
    "Content-Type": "application/vnd.api+json",
    "Accept": "application/vnd.api+json"
  },
  body: JSON.stringify({
    "meta": {
      "key": "B8A5-91D7-CB9A-DAE4-4F6E-1128"
    }
  })
})

const { meta } = await validation.json()
if (meta.valid) {
  // … do something
} else {
  // … do something else
}

Handling failures

Depending on your product and business requirements, you may want to implement additional logic when, for example, your user does not have an active internet connection, or their license fails validation for some reason or another. Below are a few license validation failure scenarios:

Validation request was successful, but license is not valid

License validation failures are innevitable, and how you handle them will differ based on your business requirements. Here are a few ideas for handling such a situation:

  1. Immediately show a dialog detailing the validation failure (you can find out the reason using the meta.constant key within the validation response).
  2. Depending on how you're licensing your product (e.g. user accounts with associated licenses vs. only license keys), you can prompt the user to purchase a new license, resolve the invalid license, etc.

Alternatively, you could disallow access to the product, or implement a grace period while prompting the user to resolve the validation failure—though ideally, this should be communicated beforehand by listening for upcoming license expiration and overdue check-in events (e.g. license.expiring-soon and license.check-in-required-soon) so that the potential for validation failures i.e. license churn is diminished.

Validation request failed e.g. timeout

The failure could be for a number of reasons, but the most likely culprit is that your user doesn't have an active internet connection. You could handle this in a variety of ways, but here are a few ideas:

  1. Begin a grace period (e.g. 30 days or 5 additional product usages), where you disallow access to the product if a license validation has not been successful after that timeframe. You should clearly tell your users that they should connect to the internet when possible and be upfront about the grace period.
  2. Immediately disallow access to the product. This should be used with care, and is not recommended unless your product relies on an active internet connection.

Next steps

Congrats! You've validated your first license using Keygen. Next up you could start associating machines with your users and their licenses, so that you can get a better understanding of how your users operate and where they use your product. If you have any questions about what you've learned today, be sure to reach out!