How To: Distribute Your Protected App¶
This guide covers the end-to-end distribution workflow — from connecting your payment provider to delivering the protected app to your customers.
Which distribution path should I use?¶
PyLocket gives you several ways to get your protected app into the hands of paying end-users. All of them bill the $4 License Fee to you (the developer), never to the end-user — but they differ in how you collect the end-user's payment.
Use this decision tree to pick the right path:
- Am I selling the app for money (not free/beta)?
- No → use Direct Distribution (free downloads up to 10 per app) or Redemption Codes for a closed beta.
-
Yes → continue.
-
Do I already have a storefront set up (Gumroad, Paddle, Lemon Squeezy, my own Stripe account, AppSumo, etc.)?
- Yes → use Marketplace Distribution (Path 1) — your storefront collects end-user payment and calls PyLocket's API to issue a license. See Marketplace Distribution.
-
No → continue.
-
Am I OK with a Stripe-hosted checkout page that shows my business name on the receipt but not my own custom UI?
- Yes → use PyLocket Stripe Connect (Path 2) — PyLocket generates the Stripe checkout on your own connected account, with zero integration work. See Stripe Connect Setup.
- No → set up a storefront on Gumroad, Paddle, Lemon Squeezy, or your own Stripe account, then go back to question 2.
Summary table¶
| Method | Best For | End-user payment goes to | Collection of the $4 License Fee |
|---|---|---|---|
| Direct Distribution | Free apps, beta testing, individual sharing | N/A (no sale) | N/A (free tier) or monthly PyLocket invoice |
| Redemption Codes | AppSumo / launch campaigns | Your launch partner | Monthly PyLocket invoice (only when code is redeemed) |
| Marketplace Distribution (Path 1) | Already have a storefront | Your storefront | Monthly PyLocket invoice |
| PyLocket Stripe Connect (Path 2) | Just want a checkout page with no integration | Your connected Stripe account | Extracted from each sale at payment time (no monthly invoice) |
In all cases, end-users never see PyLocket branding on their receipt. The PyLocket delivery page (where they get the license key and download) shows your app's branding.
Method 1: Direct Distribution¶
Direct Distribution lets you share your protected app without setting up a storefront. Generate a unique one-time download link, send it to your end user, and PyLocket handles the rest — license creation, download tracking, and activation.
How It Works¶
Developer generates link → End user opens link → Fills out form → Downloads app → License auto-activated
- Generate a link: In the Developer Portal, go to your App → Direct Distribution → Generate Download Link
- Share the link: Send the unique URL to your end user via email, chat, or any channel
- End user redeems: They visit
get.pylocket.com/<code>, enter their name and email, and download the app - License created: A license is automatically created and appears on your Licenses page
- One-time use: The link expires after a single download — it cannot be reused or shared further
Pricing¶
- First 10 downloads: Free (per app)
- After 10 downloads: $4 per download, billed to your account
Generating a Download Link¶
From the Developer Portal¶
- Navigate to Apps → select your app
- Scroll to the Direct Distribution section
- Click Generate Download Link
- Copy the generated URL (e.g.,
https://get.pylocket.com/a1b2c3) - Share the URL with your end user
From the CLI¶
From the API¶
curl -X POST https://api.pylocket.com/v1/apps/<APP_ID>/distribute \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json"
# Response:
# {
# "download_url": "https://get.pylocket.com/a1b2c3",
# "code": "a1b2c3",
# "expires_at": "2026-04-18T00:00:00Z"
# }
What the End User Sees¶
When an end user opens the download link:
- Landing page at
get.pylocket.com/<code>with your app name and icon - Registration form — they enter their name and email address
- Download button — appears after form submission
- Automatic license — a license key is created and associated with their email
- Confirmation — they receive the license key on-screen (and optionally via email)
Managing Direct Distribution Links¶
View all generated links and their status in Apps → Direct Distribution:
| Status | Meaning |
|---|---|
| Active | Link is available and waiting for download |
| Redeemed | End user has downloaded the app |
| Expired | Link expired before being used (30-day default) |
Use Cases¶
- Beta testing: Generate links for a handful of testers
- Free distribution: Share your app without charging
- Individual sharing: Send a download link directly to a specific person
- Demo/evaluation: Let prospects try your app before purchasing
Using Direct Distribution for Free Trials¶
Direct Distribution is the simplest way to offer a free trial of your protected application. Here's how the trial flow works:
- Generate a download link from the Developer Portal, CLI, or API
- Share the link with a prospect via email or chat
- Prospect downloads — a license is automatically created on download
- License auto-expires — free-tier licenses expire after 30 days, giving prospects a built-in evaluation window
Key details:
- The first 10 downloads per app are free — no credit card required
- Each download link is single-use and expires after 30 days if not redeemed
- Free-tier licenses automatically expire after 30 days, making them ideal for time-limited trials
- After the free tier, each additional download costs $4
For custom trial periods, create licenses with a specific expiration date:
# A 14-day free trial (never charged)
pylocket licenses create \
--app <APP_ID> \
--email prospect@example.com \
--type demo
Each paid license you create is charged the per-license fee on your next
invoice, so the command asks for confirmation first — add --yes in scripts.
A --type demo license is a free trial and is never charged: it lasts up to 14
days, one trial per computer per app, and the app must have Allow free
trials turned on. On the Free plan you are not charged at all, and every
license becomes a 30-day trial regardless of --type.
Your application can check the license type at runtime and enable or disable features accordingly. See Configure Licensing for the full expiration and device-limit options.
Method 2: Storefront Distribution¶
For commercial distribution, connect your own payment provider. PyLocket handles license creation and delivery after payment.
Distribution Architecture¶
PyLocket provides: - License generation: Automatic license key creation on purchase - Delivery page: Hosted page showing the license key and download button - Expiring download links: Time-limited download URLs (7-day expiry) that cannot be altered. These links are not a code signature on your app; you sign your app yourself (see Step 1) - Email confirmation: Automated email to the buyer with license key and download link
You provide: - Payment processing: Through your own storefront (Stripe, Gumroad, Paddle, etc.) - Product page: Your website or marketplace listing
Step 1: Protect Your Application¶
Before distributing, ensure you have a protected build in READY status. On Windows and macOS, sign it with your own certificate and upload the signed copy with Replace with Signed Package; PyLocket does not sign your app, and an unsigned app meets SmartScreen and Gatekeeper warnings (see Code Signing):
pylocket protect \
--app <APP_ID> \
--artifact dist/myapp.exe \
--platform win-x64 \
--python 3.12
# Wait for completion
pylocket status --build <BUILD_ID>
Step 2: Configure Your Storefront¶
Stripe Checkout¶
import stripe
session = stripe.checkout.Session.create(
mode="payment",
line_items=[{"price": "price_xxx", "quantity": 1}],
success_url=(
"https://api.pylocket.com/download"
"?session_id={CHECKOUT_SESSION_ID}"
"&app_id=<APP_ID>"
),
metadata={"pylocket_app_id": "<APP_ID>"},
)
Gumroad¶
In your Gumroad product settings:
- Go to Advanced → Post-Purchase Redirect
- Set the URL to:
Paddle¶
In your Paddle checkout:
Paddle.Checkout.open({
product: 12345,
successCallback: function(data) {
window.location.href =
`https://api.pylocket.com/download?app_id=<APP_ID>&email=${data.user.email}`;
}
});
Lemon Squeezy¶
Set the Thank You Page URL in your product settings:
Custom Storefront¶
For any payment provider, redirect the buyer to:
Tip: The exact redirect URL for your app is pre-filled in the Developer Portal under Post-Purchase Delivery.
Step 3: What the Customer Sees¶
After payment, the customer lands on the PyLocket delivery page:
- License key displayed prominently with a one-click copy button
- Download button for the protected application
- Getting started instructions:
- Install the application
- Run it and enter the license key when prompted
- The app activates and is ready to use
- Confirmation email sent to the buyer's address
The delivery page is idempotent — bookmarking or refreshing shows the same information.
Step 4: Multi-Platform Distribution¶
If you offer your app on multiple platforms, upload a separate protected build for each platform. The delivery page automatically shows labeled download buttons for each available platform:
Build and protect each platform's artifact separately:
# Windows — upload the PyInstaller .exe
pylocket protect --app <APP_ID> --artifact dist/myapp.exe --platform win-x64 --python 3.12
# Linux — rename the extensionless PyInstaller binary to .elf, then upload
mv dist/myapp dist/myapp.elf
pylocket protect --app <APP_ID> --artifact dist/myapp.elf --platform linux-x64 --python 3.12
# macOS — upload the .app bundle (NOT the .dmg/.pkg installer)
pylocket protect --app <APP_ID> --artifact dist/MyApp.app --platform macos-arm64 --python 3.12
Note: PyInstaller's Linux onefile output has no file extension, and the upload validator rejects extensionless files. Rename it to
.elfbefore uploading; the name is only a transport convention, and the engine reads the real format from the file contents.Important: Upload the raw build output from your build tool (PyInstaller binary, cx_Freeze directory, etc.), not installer packages like
.dmg,.msi, or.deb. You can optionally wrap the protected output in an installer for distribution afterward.
For a complete walkthrough, see the Multi-OS Publishing Tutorial.
Step 5: Customer Support¶
Common Customer Issues¶
| Issue | Resolution |
|---|---|
| Lost license key | Look up the license in the Developer Portal by customer email |
| Activation fails | Check device limit; reset devices if needed |
| New device | Reset device activations: pylocket licenses reset-devices --license <KEY> |
| Refund request | Revoke the license: pylocket licenses revoke --license <KEY> |
| Download link expired | The customer can revisit the delivery page — the download link regenerates |
Providing End-User Documentation¶
Consider including a brief guide with your application:
- System requirements (OS, any dependencies)
- How to enter the license key
- Offline use expectations (up to 14 days since the app last reached PyLocket)
- How to contact you for support
Free Tier¶
Every app gets 10 free build downloads — no credit card required. This lets you test the full distribution flow before committing to a paid plan.
After the 10th download, PyLocket activates billing. See Billing & Pricing for details.
Third-Party Marketplaces¶
If you sell through AppSumo, Gumroad, Paddle, LemonSqueezy, or other third-party marketplaces where the marketplace (not your own Stripe) processes payments, see the Marketplace Distribution Guide. That guide covers:
- Redemption codes — Generate batches of codes, upload to the marketplace, customers redeem for a license
- API provisioning — Your backend receives marketplace webhooks and calls the PyLocket API to create licenses in real time
See Also¶
- Licensing Tutorial — Full licensing walkthrough
- Configure Licensing — Device limits, expiration, offline use
- Marketplace Distribution — AppSumo, Gumroad, Paddle, and more
- Billing & Pricing — How PyLocket charges work