Skip to content

CLI Reference

Complete reference for the pylocket command-line tool (v1.1.19).

Install: pip install pylocket


Global Options

These options apply to all commands:

Option Description Default
--api-url <URL> Override the PyLocket API base URL https://api.pylocket.com
--token <TOKEN> Override the session token (the JWT from pylocket login) Read from ~/.pylocket/credentials
--help, -h Show help for any command
--version Show the CLI version

The PYLOCKET_TOKEN environment variable can also be used instead of --token. The PYLOCKET_API_URL environment variable can be used instead of --api-url.

--token is not your API key

It takes the session token issued by pylocket login, which expires after 30 minutes. An API key passed here is rejected with 401, because the CLI sends it as a Bearer credential and the server cannot decode it as a JWT. API keys are for calling the REST API with the X-API-Key header; see CI/CD Integration.


pylocket login

Authenticate with the PyLocket API.

pylocket login [OPTIONS]

Options

Option Description
--email <EMAIL> Account email (prompted interactively if omitted)
--password <PASSWORD> Account password (prompted interactively if omitted)
--token <TOKEN> Authenticate directly with an existing session token, not an API key (skips interactive login)
--sso Authenticate via browser (opens your default browser to the PyLocket portal)

Behavior

  • On success, stores credentials at ~/.pylocket/credentials
  • If 2FA is enabled, prompts for a TOTP code after password (or handles it in the browser with --sso)
  • The stored token is reused for subsequent commands until it expires

Not for CI/CD

Every option here yields a session token that expires after 30 minutes, and the password form stops working once 2FA is enabled. For pipelines, use an API key against the REST API instead; see CI/CD Integration.

Browser-Based Login (--sso)

The --sso flag opens your default browser to the PyLocket portal for authentication. This is recommended if you:

  • Have 2FA enabled and prefer entering your TOTP code in a browser
  • Use a password manager that auto-fills browser forms
  • Are on a shared machine and prefer not to type credentials in a terminal

After you sign in (including 2FA if enabled), the browser redirects back to the CLI automatically — no copy-pasting required. The CLI stores the credentials the same way as interactive login.

If the browser can't be opened (e.g., SSH session), the CLI prints the URL for you to open manually in any browser on the same machine.

Examples

# Interactive login (email/password in terminal)
pylocket login

# Browser-based login (recommended for 2FA users)
pylocket login --sso

# Non-interactive login (local scripts; fails once 2FA is enabled)
pylocket login --email dev@example.com --password "s3cret"

# Reuse a session token you already hold (expires after 30 minutes)
pylocket login --token "eyJhbGc..."

pylocket apps

Manage registered applications.

pylocket apps create

Register a new application.

pylocket apps create --name <NAME> [--description <TEXT>] [--platform <PLATFORM>]
Option Description Required Default
--name <NAME>, -n Application display name Yes
--description <TEXT>, -d Application description No None
--platform <PLATFORM>, -p Target platform No python
pylocket apps create --name "MyApp" --platform win-x64

pylocket apps list

List all registered applications.

pylocket apps list [OPTIONS]
Option Description Default
--page <N> Page number 1
--page-size <N> Items per page 20
pylocket apps list
pylocket apps list --page 2 --page-size 50

pylocket apps update

Update an existing application.

pylocket apps update --app <APP_ID> [OPTIONS]
Option Description
--app <APP_ID> Application ID (required)
--name <NAME> New display name
--description <TEXT> New description
pylocket apps update --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114 --name "MyApp Pro"

Platform targets are fixed at creation time. The offline grace period and device limit live in the app's license policy, which is edited in the Developer Portal — updating it through the API replaces the whole policy object, so it is not exposed as a CLI flag.

pylocket apps delete

Delete a registered application.

pylocket apps delete --app <APP_ID>

Warning: Deleting an app revokes all associated licenses and removes all builds. This action cannot be undone.


pylocket protect

Upload and protect an application artifact.

pylocket protect --app <APP_ID> --artifact <PATH> [OPTIONS]

Options

Option Description Required Default
--app <APP_ID> Application ID Yes
--artifact <PATH> Path to the artifact to protect Yes
--platform <PLATFORM> Target platform (e.g. win-x64, linux-x64, darwin-arm64) No Auto-detected from your OS
--python <VERSION> Python version used to build the artifact No Engine-detected from the artifact
--version <LABEL> Build version label No 1.0.0
--wait / --no-wait Wait for the protection build to complete No --wait
--out <DIR> Auto-download to this directory when ready (implies --wait) No

Valid Python versions: 3.12, 3.13, 3.14

Platform auto-detection

If --platform is not specified, the CLI reads your current platform from sysconfig.get_platform() and maps it to a PyLocket platform token: win-amd64 becomes win-x64, linux-x86_64 becomes linux-x64, and Apple Silicon Macs become darwin-arm64. You only need to specify --platform when cross-protecting for a different OS.

Python version auto-detection

If --python is not specified, the protection engine detects the Python version from the uploaded artifact itself (for example the PyInstaller archive header or embedded interpreter markers). Pass --python only as a hint when that detection fails.

Supported Artifact Types

Extension Description
.py, .pyz, .pyw Python scripts
.whl, .egg Python packages (wheels, eggs)
.zip ZIP archives (must contain Python files)
.tar.gz, .tgz, .tar.bz2 Compressed tar archives
.exe Windows executables (PyInstaller, cx_Freeze)
.elf Linux ELF executables (PyInstaller onefile)
.app macOS application bundles (zipped .app directory)

Note

PyInstaller onefile builds on Linux and macOS emit an extensionless binary. Rename it to .elf before running pylocket protect (the engine reads the real format from the bytes; for macOS GUI apps, upload the .app bundle instead).

Examples

# Protect an application (platform and Python version auto-detected)
pylocket protect \
  --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114 \
  --artifact dist/myapp.exe

# Protect with explicit platform and Python version
pylocket protect \
  --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114 \
  --artifact dist/myapp.exe \
  --platform win-x64 \
  --python 3.13

# Protect and auto-download when ready
pylocket protect \
  --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114 \
  --artifact dist/myapp.exe \
  --out dist/protected/

# Protect without waiting (check status later)
pylocket protect \
  --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114 \
  --artifact dist/myapp.exe \
  --no-wait

pylocket status

Check the status of a protection build.

pylocket status --build <BUILD_ID> [OPTIONS]

Options

Option Description
--build <BUILD_ID> Build ID to check
--app <APP_ID> App ID (used with --latest)
--latest Show the most recent build for the app
--format <FORMAT> Output format: table (default), json

Build Statuses

Status Description
pending Build created and waiting for the protection worker
processing Protection in progress
ready Protection complete and ready for download
failed An error occurred during protection
rejected Artifact was flagged by the malware scan; the developer account is automatically suspended pending review

Fine-grained progress (extraction, encryption, packaging) is reported in the separate processing_stage field of the build payload, not in status.

Examples

# Check a specific build
pylocket status --build 7c2d5e91-0a36-4b8f-9e14-8d63f2a70c55

# Check the latest build for an app (JSON output)
pylocket status --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114 --latest --format json

pylocket fetch

Download a protected artifact.

pylocket fetch --build <BUILD_ID> --out <DIR> [--app <APP_ID>]

Options

Option Description Required
--build <BUILD_ID> Build ID to download Yes
--out <DIR> Output directory Yes
--app <APP_ID> App ID (optional, improves lookup speed) No

Example

pylocket fetch --build 7c2d5e91-0a36-4b8f-9e14-8d63f2a70c55 --out dist/protected/

The command creates the output directory if it does not exist.

Tip

The --app flag is optional. You can use just --build and the server will look up the build automatically.


pylocket distribute

Generate a one-time direct download link for your application.

pylocket distribute --app <APP_ID>

Options

Option Description Required
--app <APP_ID> Application ID Yes

Example

pylocket distribute --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114
# Returns: https://get.pylocket.com/a1b2c3

The generated link is single-use and expires after 30 days. When an end user visits the link, they enter their details, download the app, and receive an auto-generated license. The first 10 downloads per app are free.

See Distribute Your App for the full distribution workflow.


pylocket licenses

Manage end-user licenses.

pylocket licenses create

Create a new license key.

pylocket licenses create --app <APP_ID> [OPTIONS]

This creates a billable license

Each license you create is charged the per-license fee on your next invoice. The command asks for confirmation first; pass --yes to skip the prompt in scripts.

On the Free plan you are not charged, but every license is issued as a trial regardless of --type, and counts against your free-tier allowance. Without --expires it expires in 30 days; an explicit --expires is honored.

Option Description Default
--app <APP_ID> Application ID (required)
--email <EMAIL> End-user email (optional)
--device-limit <N> Max devices 2
--expires <DATE> Expiration date (YYYY-MM-DD) None (no expiry on Pro; 30 days on the Free plan)
--type <TYPE> License type: standard, demo standard
--channel <CHANNEL> Sales channel recorded on the license, used for billing reconciliation: manual, api, stripe, appsumo, gumroad, paddle, lemonsqueezy manual
--yes, -y Skip the billing confirmation prompt off

pylocket licenses list

List licenses. Omit --app to list across every app you own.

pylocket licenses list [OPTIONS]
Option Description
--app <APP_ID> Filter to one application (optional)
--type <TYPE> Filter by type: trial, paid
--format <FORMAT> Output format: table, json

pylocket licenses get

Get details for a specific license.

pylocket licenses get --license <LICENSE_KEY>

pylocket licenses revoke

Revoke a license.

pylocket licenses revoke --license <LICENSE_KEY>

pylocket licenses reset-devices

Clear all device activations for a license.

pylocket licenses reset-devices --license <LICENSE_KEY>

pylocket licenses extend

Extend a license expiration date. Requires an active Pro subscription — on the Free plan this returns "Active Pro subscription required to edit license expiry dates or download caps".

pylocket licenses extend --license <LICENSE_KEY> --expires <DATE>

pylocket auth

Manage authentication and security settings.

pylocket auth api-keys rotate

Generate a new API key and invalidate the old one.

pylocket auth api-keys rotate

pylocket auth 2fa setup

Start 2FA setup. Returns a QR code URI for your authenticator app.

pylocket auth 2fa setup

pylocket auth 2fa confirm

Confirm 2FA setup with a TOTP code.

pylocket auth 2fa confirm --code <CODE>

pylocket auth 2fa status

Check 2FA status and remaining backup codes.

pylocket auth 2fa status

pylocket auth 2fa disable

Disable 2FA.

pylocket auth 2fa disable --code <CODE>

pylocket webhook

Configure build event webhooks for CI/CD integration.

pylocket webhook set

Configure a webhook URL to receive build event notifications.

pylocket webhook set --app <APP_ID> --url <HTTPS_URL>

Returns a webhook secret that must be saved immediately — it cannot be retrieved again. PyLocket will POST a signed JSON payload to this URL when a build completes, fails, or is rejected.

pylocket webhook remove

Remove the webhook configuration for an app.

pylocket webhook remove --app <APP_ID>

pylocket webhook test

Send a test ping event to verify the webhook URL is reachable.

pylocket webhook test --app <APP_ID>

pylocket webhook status

Show webhook configuration and recent delivery attempts.

pylocket webhook status --app <APP_ID>

Environment Variables

Variable Description Equivalent Option
PYLOCKET_TOKEN Authentication token --token
PYLOCKET_API_URL API base URL --api-url
PYLOCKET_LICENSE_KEY License key for protected apps (used at runtime)
PYLOCKET_FORCE_INCLUDE Comma-separated module names to always protect
PYLOCKET_FORCE_EXCLUDE Comma-separated module names to never protect
PYLOCKET_DEBUG Set to 1 to enable verbose bootstrap debug logging

Exit Codes

Code Meaning
0 Success
1 General error
2 Timeout waiting for build completion
130 User abort (Ctrl+C)

Credential Storage

Credentials are stored at ~/.pylocket/credentials in JSON format. The file contains:

  • Access token (JWT, expires after the configured TTL)
  • Refresh token
  • API URL

The file permissions are set to 600 (owner read/write only).

To clear stored credentials:

rm ~/.pylocket/credentials