Designing Trial License Systems That Convert Users
A well-designed trial is the highest-leverage growth tool for a desktop app. Yet most developers either give away the full product with no time limit (and wonder why nobody buys) or make the trial so restrictive that users uninstall before they can evaluate.
The goal is simple: let the user experience the value of your software, then create a natural moment to pay.
Trial Strategies That Work
Time-Limited Full Access
The most effective model. Give users the full product for 14 or 30 days. When the trial ends, the app locks until they enter a paid key. Create a key with expiryDate and let the API handle enforcement — no custom expiration logic needed.
curl -X POST "https://api.keymint.dev/key" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"productId": "prod_100",
"maxActivations": "3",
"expiryDate": "2026-07-04T00:00:00Z",
"metadata": { "type": "trial", "email": "user@example.com" }
}'On every launch, call activate_key. If the key is expired or fully consumed, it returns a non-zero code.
If you issue anonymous trials first, collect the user's name and email during activation and pass them as licensee. Keymint can attach the currently activated license to that customer without exposing broader customer-management APIs to the client key.
Feature-Gated Trials
Keep the trial running indefinitely but restrict premium features. One binary, multiple tiers. Create a key with metadata flags your app reads at startup:
| Tier | Features | Price |
|---|---|---|
| Free | Basic export, single device | Free |
| Pro | Bulk export, unlimited devices | $29/mo |
| Enterprise | SSO, audit logs, floating seats | Custom |
Your backend can fetch key metadata via the get_key endpoint using a read-only or admin key, then return only the feature flags your app needs. Client-side client keys should use activation/check-in flows instead of detailed key lookup.
Usage-Limited Trials
Cap usage instead of time. Track consumption in your backend and update the key's metadata with PATCH /key using an admin API key.
Converting Trial Users
The conversion funnel has three stages:
- Day 1 — Welcome email with setup guide. Show them a win in the first session.
- Day 7 — In-app nudge: "7 days left. Upgrade to keep full access."
- Day 13 — Final reminder with an optional discount.
Anti-Abuse Protections
Trials get abused. Protect yourself:
- Require email verification before issuing the key. Pass the email in
metadataso you can audit duplicates. - Set
maxActivationslow (1-3) to prevent sharing. - Use
expiryDateso keys auto-expire even if the user never activates. - Check for existing trials server-side by fetching key info with a
read-onlyoradminkey and inspecting the metadata.
# Server-side only: requires a read-only or admin API key.
info = client.get_key({
"productId": "prod_100",
"licenseKey": "T8XTR-AI21B-2990H-85SB5",
})
if info["data"]["license"].get("expirationDate"):
expires = datetime.fromisoformat(
info["data"]["license"]["expirationDate"].replace("Z", "+00:00")
)
if datetime.utcnow() > expires:
print("Trial expired")Summary
The right trial strategy depends on your product. Keymint's expiryDate, maxActivations, and metadata fields give you everything you need to build trials without writing custom validation logic.
Start issuing trials from your dashboard or via the API docs. Compare pricing when you're ready to pick a plan.