Licers

← All articles

PythonLicensingTutorial

How to Add License Key Validation to a Python App

Licers Team · 2026-07-06

Sending a key to a server and trusting the reply is the first thing most developers try. It is also the first thing a cracker breaks. Anyone who can run your program can watch that network call, point it at a local server that always answers "valid", and move on with their day. The check itself was never the hard part. Making the check impossible to fake is.

This guide walks through adding real license validation to a Python app — not just an on/off flag, but a signed response that a fake server cannot forge.

What you will need

Step 1: Install the SDK

pip install pylicensify

The SDK handles the three things that are easy to get wrong by hand: sending a one-time nonce with every request, verifying the Ed25519 signature on the response, and rejecting replayed or stale replies.

Step 2: Validate a key

from pylicensify import LicenseClient

client = LicenseClient(public_key="YOUR_PUBLIC_KEY")

result = client.validate("PY-XXXXXXXXXXXXXXXX")
if not result:
    print("License is not valid:", result.error)
    raise SystemExit(1)

print("Licensed. Entitlements:", result.features)

If the key is real, active, and within its limits, result is truthy. If it is not, result.error tells you exactly why — expired, revoked, device limit reached, and so on. You can show that message to the user or log it.

Step 3: Gate your features

Entitlements travel inside the signed response, so you can ship one build and unlock features per key:

if result.feature("pro"):
    enable_pro_features()

seats = result.feature("seats", 1)

Because those flags are part of the signed payload, a user cannot flip pro to true by editing a config file. If the value is not signed by your private key, the SDK will not trust it.

Why the signature matters

This is the part that naive licensing skips, and it is the whole game. When Licers answers a validation request, it signs the response with a private key that never leaves the server. Your app verifies that signature using the public key you embedded at build time.

A cracker who redirects your API to a server they control cannot produce a valid signature, because they do not have your private key. The best they can manage is a response your app rejects. Without this step, a five-line fake server defeats your licensing in about ten minutes.

The SDK verifies the signature for you. If you decide to integrate by hand instead, you must verify it yourself — otherwise the whole exercise is theatre.

Step 4: Support users who are offline

Some customers run your software on machines that never touch the internet. For them, issue a signed offline license file from the dashboard and verify it locally, with zero network calls:

from pylicensify import verify_offline_license

data = verify_offline_license("YOUR_PUBLIC_KEY", "license.lic")
print("Valid for:", data.get("customer"))

The file carries its own signature, expiry, and optional device binding, so it is just as hard to forge as an online check.

A note on obfuscation

Signature verification stops fake servers. It does not stop someone from opening your bytecode and deleting the check entirely. For that, ship your code obfuscated so the validation logic cannot be located and patched in five minutes. Tools such as PyObfuscate exist for exactly this, and they pair naturally with signed licensing: one raises the cost of faking the server, the other raises the cost of removing the client.

Wrapping up

A license check is only as strong as its weakest assumption. The naive version assumes the server is honest and the client is untouched — and both assumptions are wrong the moment your software is on someone else machine. Signed responses fix the first. Obfuscation raises the bar on the second. Together they are enough to make cracking more expensive than simply paying, which is the only realistic goal any licensing system can have.

Ready to try it? Create a free account, grab your public key, and you can have this working before your coffee gets cold.

Related guides

Frequently asked questions

How do I validate a license key in Python?

Install the SDK with pip install pylicensify, create a LicenseClient with your Ed25519 public key, then call client.validate(key). The SDK sends the key and a hardware id to the validation API, verifies the signed response against your public key, and returns a result you can branch on.

Can someone bypass the check by blocking the network?

They can stop the request, but they cannot fake a successful one. A valid response must carry an Ed25519 signature produced by a private key that never leaves the server, so an offline or redirected client fails the signature check rather than passing it.

Does validation slow down my application's start-up?

A single validation is one HTTPS round trip, typically well under a second. Most applications validate once at start-up and cache the result for the session rather than validating on every action.

Protect your software with Licers

Signed validation, floating licenses, offline files, and more — free to start.

Get started free