Licensing Tutorial¶
This tutorial walks you through setting up licensing for your protected application — from creating license keys to delivering your app to paying customers.
Overview¶
PyLocket provides a complete licensing infrastructure:
Developer creates license → End-user purchases → Delivery page shows key + download
→ End-user activates → Runtime validates → App runs
Key concept: PyLocket handles licensing and delivery. You handle payment through your own storefront (Stripe, Gumroad, Paddle, Lemon Squeezy, etc.). PyLocket never processes end-user payments.
1. Understanding the License Flow¶
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Your │ │ PyLocket │ │ End-User │
│ Storefront │ │ Platform │ │ │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ 1. Customer pays │ │
│◄───────────────────┼────────────────────┤
│ │ │
│ 2. Redirect to │ │
│ delivery page │ │
├───────────────────►│ │
│ │ │
│ │ 3. Show license │
│ │ key + download │
│ ├───────────────────►│
│ │ │
│ │ 4. Activate │
│ │◄───────────────────┤
│ │ │
│ │ 5. Issue token │
│ ├───────────────────►│
│ │ │
│ │ App runs ✓ │
2. Create a License Key¶
Via CLI¶
Output:
License created successfully.
License Key: XXXX-XXXX-XXXX-XXXX
Status: ACTIVE
Device Limit: 2
Email: customer@example.com
Via REST API¶
curl -X POST https://api.pylocket.com/v1/licenses \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"app_id": "app_abc123",
"email": "customer@example.com",
"device_limit": 2
}'
Via Developer Portal¶
- Go to Developer Portal → Licenses
- Click Create License
- Select the app, enter the customer email, and set the device limit
- Click Create
3. License Key Format¶
PyLocket license keys follow the format:
- 16 alphanumeric characters in 4 groups of 4
- Human-readable and easy to type
- Each key is globally unique
- Keys are not tied to a specific platform — they work across all platforms for the same app
4. Connect Your Storefront¶
To automate license delivery after a purchase, configure your storefront to redirect buyers to the PyLocket delivery page.
Stripe Checkout¶
When creating a Stripe Checkout session, set the success URL and metadata:
import stripe
session = stripe.checkout.Session.create(
mode="payment",
line_items=[{"price": "price_abc123", "quantity": 1}],
success_url="https://api.pylocket.com/download"
"?session_id={CHECKOUT_SESSION_ID}"
"&app_id=YOUR_APP_ID",
metadata={
"pylocket_app_id": "YOUR_APP_ID"
}
)
Gumroad¶
Set the Post-Purchase Redirect URL in your Gumroad product settings:
Other Storefronts¶
Any storefront that supports a post-purchase redirect URL works. The URL format is:
Tip: Find your exact redirect URL template pre-filled in the Developer Portal under your app's Post-Purchase Delivery card.
5. The Delivery Page¶
After purchase, the buyer is redirected to a PyLocket-hosted delivery page that displays:
- License key — shown prominently with a copy button
- Download button — links to a signed, time-limited (7-day) download URL
- Getting started instructions — tells the buyer to install the app and enter their key
PyLocket also sends a confirmation email to the buyer with the same information.
The delivery page is idempotent — refreshing the page shows the same license key and download link.
6. End-User Activation¶
When the end-user runs the protected application and enters their license key, the following happens:
- The application sends an activation request to PyLocket containing the license key and a hardware-based device fingerprint
- PyLocket validates:
- The license exists and is
ACTIVE - The device limit has not been exceeded
- Anti-abuse velocity checks pass
- On success, PyLocket returns a cryptographically signed runtime token and a policy object (device limit, offline grace period)
- The runtime caches the token securely in protected memory
Device Fingerprinting¶
PyLocket generates a unique hardware-based fingerprint for each device. The fingerprint is derived from multiple hardware identifiers and uses a per-app salt, so the same physical device produces different fingerprints for different apps. PyLocket stores only the fingerprint — never the raw hardware identifiers.
7. Offline Use¶
After a successful online activation, the application works offline for up to 72 hours (configurable). The runtime:
- Caches the signed token in protected memory
- Checks the token validity on each function invocation
- Attempts a background token refresh when online
- After the offline grace period expires, requires a network connection to re-validate
8. Device Limits¶
Each license has a configurable device limit (default: 2). When a customer activates on a new device:
- If the device limit has not been reached, the activation succeeds
- If the limit is reached, the activation fails with a clear error message
Resetting Activations¶
If a customer gets a new computer or reinstalls their OS:
Via CLI:
Via Developer Portal:
- Go to Licenses → find the license
- Click Reset Devices
This clears all device activations, allowing the customer to re-activate.
9. Revoking a License¶
If you need to revoke a license (refund, abuse, etc.):
Via CLI:
Via REST API:
curl -X POST https://api.pylocket.com/v1/licenses/<LICENSE_ID>/revoke \
-H "Authorization: Bearer <YOUR_TOKEN>"
Revoked licenses immediately stop working. The next time the application checks the license (at startup or token refresh), it will fail activation.
10. License Statuses¶
| Status | Meaning |
|---|---|
ACTIVE |
License is valid and can be activated |
REVOKED |
License has been revoked by the developer |
EXPIRED |
License has passed its expiration date (if set) |
DEMO |
Trial/demo license with limited functionality |
11. Monitoring Licenses¶
Developer Portal¶
The Licenses page in the Developer Portal shows:
- All licenses for each app
- Status, activation count, and device count
- The Stripe session that created each license (if applicable)
- Activation history with timestamps
CLI¶
# List all licenses for an app
pylocket licenses list --app app_abc123
# Get details for a specific license
pylocket licenses get --license <LICENSE_KEY>
Example: Complete Integration with Stripe¶
Here is a complete example of selling a protected Python app using Stripe:
1. Protect your app¶
2. Create a Stripe product and price¶
import stripe
product = stripe.Product.create(name="MyApp Professional")
price = stripe.Price.create(
product=product.id,
unit_amount=4999, # $49.99
currency="usd",
)
3. Create a checkout session with PyLocket redirect¶
session = stripe.checkout.Session.create(
mode="payment",
line_items=[{"price": price.id, "quantity": 1}],
success_url="https://api.pylocket.com/download"
"?session_id={CHECKOUT_SESSION_ID}"
"&app_id=app_abc123",
metadata={"pylocket_app_id": "app_abc123"},
)
4. Customer completes purchase¶
The buyer pays through Stripe → gets redirected to the PyLocket delivery page → receives their license key and download link → installs and activates the app.
No additional code or infrastructure required on your end.
Summary¶
In this tutorial you learned how to:
- Create license keys for end-users
- Connect your storefront to PyLocket's delivery system
- Understand the activation flow (device fingerprinting, signed tokens)
- Configure offline use and device limits
- Monitor and manage licenses
- Build a complete sales flow with Stripe
Next Steps¶
| Goal | Guide |
|---|---|
| Format-specific protection | How-To Guides |
| Advanced licensing configuration | Configure Licensing |
| Distribution best practices | Distribute Your App |
| Deep dive into the licensing system | Licensing System |