What this means
Your app can have a desktop version and a web version under the same public App ID. The same customer key can activate both when the license includes both. This works for monthly/annual subscriptions, one-time purchases and lifetime access; it does not create a new payment schedule.
| Your KDPika workspace plan | What you can offer |
|---|---|
| Starter / Pro | One key works for both desktop and web under the same App ID. You cannot restrict individual software plans to one app family. |
| Business | Choose Desktop only, Web only or Desktop + Web for each software plan. |
| Free | Basic testing in Sandbox only; no Live sales. Per-plan app restrictions are not included. |
Authorized internal unlimited/special access keeps the Business-equivalent capabilities granted by its platform settings. An expired workspace follows its effective access plan.
One license means one shared allowance. If a key allows 3 devices, a desktop installation and a PHP server normally use two of those slots. Floating seats and usage credits also remain shared. A browser tab is not a separate licensed machine in this server-side PHP example.
1. Choose where your software plan works
- Open Plans & features, then New plan or Edit plan.
- In Available applications, choose Desktop + Web · one key, Desktop only or Web only.
- Save. When editing, select New licenses only (default) or New and existing licenses, review the impact and confirm if required.
- Issue the customer a license normally. No second App ID or duplicate customer key is required.
Business is enforced in server-side writes, not just by disabling a field. Reserved feature JSON application_access can contain only both, desktop or web. It cannot bypass the platform plan through an API, WooCommerce editor, or per-license feature override. Starter/Pro use both on effective signed responses, including after a downgrade; saved feature/limit data and credit balances are preserved.
Extra feature values on one license can override application_access on Business using the existing audited feature override editor. Reset features returns to that license plan's default. Product/environment/tenant checks still apply.
2. Configure each app once
This is publisher configuration in your application code, not a dropdown for your end customers to claim another app type.
| SDK current source | Desktop | Web backend |
|---|---|---|
| Python 2.1.0 | application_type="desktop" | application_type="web" |
| PHP 2.1.0 | applicationType: 'desktop' | applicationType: 'web' |
| JavaScript 2.1.0, Node/Electron main | applicationType: "desktop" | applicationType: "web" |
| C# 2.1.0, .NET 10 | applicationType: "desktop" | applicationType: "web" |
| Rust 0.3.0 | .application_type("desktop") | .application_type("web") |
Defaults are web for PHP and desktop for the other SDKs. Always select explicitly in a web backend. The same App ID/key works in both apps; each has its own private installation state. Context is now included in the SDK storage namespace. Updating from earlier sources can create a new installation: release the old activation using the old app first or remove the old machine through your authorized dashboard/portal. Do not delete state as a substitute for deactivation.
These source versions are available as SDK ZIP downloads. They are not yet published to PyPI, crates.io, Packagist, npm or NuGet. Earlier registry packages do not expose this constructor setting; use the current source ZIP for restricted plans.
3. Install the source you need
Download and extract the SDK for your language. Compare SHA-256 against the download table. Keep normal supported runtime requirements.
- Python: create a supported Python 3.11–3.14 virtual environment, then run its Python with
-m pip install /path/to/extracted/python-sdk. This installs the local 2.1.0 source, not the older PyPI version. Run the same environment Python for your app. See beginner Python setup for OS-specific interpreter commands. - PHP: in the extracted PHP SDK folder run
composer install --no-plugins --no-scripts, then require itsvendor/autoload.phpfrom your app. Do not put credentials or activation state in the public web folder. The License Lab uses the same current source directly on its server. - JavaScript: in your app run
npm install --ignore-scripts /path/to/extracted/javascript-sdk. Use Node.js 22+ or Electron's main process; no browser fingerprint fallback. - Rust: add
kdpika-licensing = { path = "/path/to/extracted/rust-sdk" }to your app's Cargo dependencies. Use Rust 1.90+. - C#: reference the extracted
KDPika.LicenseSdk/KDPika.LicenseSdk.csprojfrom your application usingdotnet add reference /path/to/extracted/csharp-sdk/KDPika.LicenseSdk/KDPika.LicenseSdk.csproj. Use .NET 10 LTS. Do not request version 2.1.0 from NuGet before it is published.
4. Use a verified result before protected work
from pathlib import Path
from kdpika_licensing import LicenseClient
client = LicenseClient(
product="YOUR_PUBLIC_APP_ID",
environment="SANDBOX",
application_type="web",
storage_dir=Path("/private/your-web-license-state"),
)
result = client.check()
if not result.valid or not result.signature_valid:
raise SystemExit("Access is unavailable. Check your license and app type.")
if result.feature("csv_export"):
# Run your actual authorized export here.
pass
The server checks X-Application-Type before consuming an activation/seat/credit. The context is bound to the activation and included with application_access in the Ed25519-signed payload. Validation, heartbeat, checkout and credit operations use that same bound context. A token from the desktop app cannot be relabelled as web. SDKs check the signed policy again for network and cached decisions.
| Error | What to do |
|---|---|
| APPLICATION_NOT_ALLOWED | This license does not include this app family. Use the matching license or change its plan with the required Business permission. |
| APPLICATION_TYPE_REQUIRED | A restricted license was used without context. Use the current source SDK and configure desktop or web. |
| APPLICATION_TYPE_MISMATCH | An activation token belongs to another app family. Keep separate installation state and activate the matching app. |
| INVALID_APPLICATION_TYPE | Configure exactly desktop or web. Do not send an OS name such as Windows as the application type. |
Returning a shared seat or deactivating an old installation remains possible when its access scope changes. A lower limit does not silently remove other active devices/seats. A changed restriction is learned at the next online check; offline clients must still obey the signed access deadline they already received.
5. Try the real demo
- Open License Lab publisher controls. Its dedicated sign-in stays inside the demo and uses your publisher account's password/MFA, with a separate session.
- Choose Prepare test licenses. On Business it adds Desktop only, Web only and Desktop + Web licenses alongside the existing standard/seats/credits tests.
- Use App context = Web and try the Desktop only test: activation is refused by the actual API.
- Use App context = Desktop in the server SDK test runner and activate Desktop only: it succeeds. A Web only license is refused in that context.
- Use the Desktop + Web test in each context. Both succeed with the same key, using separate installation identities and a shared allowance. No new payment is taken.
- For the customer website, open Demo sign-in. That site is always configured as web; customer requests cannot select desktop or unlock publisher management.
The publisher runner labelled Desktop still runs PHP on the hosting server. It verifies context enforcement; it is not proof of running on your laptop. Test a real desktop client separately before distributing it.
Security boundary
An application type is a claim from trusted publisher code, not remote attestation that a program is a desktop binary or browser. Someone who can modify executable code can change the claim or bypass local application checks. Protect valuable online operations on your own authenticated backend too. Browser-only/WASM hardware fingerprint fallback is unsupported. Do not embed management API keys in a distributed app. Ed25519 signing, raw-serial hashing, tenant isolation, atomic seat reservations and idempotent credit operations remain in place.