A secure, spec-driven CLI for Paddle Billing
Project description
Paddle CLI
A fast, agent-native CLI for the complete Paddle Billing API.
Built for agents
2× faster agent runs. 39% fewer input tokens. 46× smaller discovery payload.
| Measured task | Paddle CLI | Paddle MCP |
|---|---|---|
| Repeated API read | 9.2s | 18.5s |
| Input tokens | 35.5k | 58.5k |
| Operation discovery | 541 chars | 24.8k chars |
Paddle CLI keeps discovery local, turns every action into an inspectable command, and works anywhere an agent has a shell. It reads Paddle's official OpenAPI specification, supports raw paths for new endpoints, stores credentials in the system credential manager, and gates live writes.
Measured on August 5, 2026 with fresh Codex sessions, the same sandbox account, and three successful read-only runs per path. Timing varies by model and network.
Install
Paddle CLI is installed with uv:
uv tool install paddle-api-cli
paddle login
macOS with Homebrew
brew install omshejul/tap/paddle-api-cli
paddle login
Windows with WinGet
winget install --id astral-sh.uv --exact
uv tool install paddle-api-cli
paddle login
Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
uv tool install paddle-api-cli
paddle login
Upgrade or uninstall a uv installation with:
uv tool upgrade paddle-api-cli
uv tool uninstall paddle-api-cli
For a Homebrew installation, use:
brew upgrade paddle-api-cli
brew uninstall paddle-api-cli
To install the latest development version directly from the public repository:
uv tool install --force-reinstall \
"git+https://github.com/omshejul/paddle-cli.git@main"
During local development:
uv sync
uv run paddle
Get started
paddle login
paddle login prompts for a key using masked input, verifies it with Paddle's
permissionless GET /event-types endpoint, and saves it in macOS Keychain,
Windows Credential Locker, or a supported Linux Secret Service. The CLI never
displays the secret or writes it to a plain-text configuration file.
Running paddle without a command shows help and examples. It never prompts or
makes a network request.
paddle
paddle whoami
paddle doctor
paddle whoamireports the local credential source without calling Paddle.paddle doctorvalidates the credential and Paddle API connectivity.
Modern keys select their own environment:
pdl_sdbx_...useshttps://sandbox-api.paddle.compdl_live_...useshttps://api.paddle.com
Legacy keys do not encode an environment, so the CLI asks you to choose one.
Paddle does not expose the current key's dashboard name, description, permissions, or expiration through the API. The validator labels those fields as dashboard-only instead of guessing.
Replace or remove the saved key explicitly:
paddle login
paddle skill install
paddle logout
For noninteractive setup, paddle login --key ... is available, but the masked
prompt is safer because command arguments may be retained in shell history.
Automation can avoid process arguments by sending the key on standard input:
security find-generic-password -w -s your-paddle-key | paddle login --key-stdin
Authentication precedence
API commands resolve credentials in this order:
PADDLE_API_KEYfor the current process.- The API key saved by
paddle login.
An environment variable is a temporary override and is never saved. If neither
source exists, authenticated commands return an error directing the user to
paddle login; they do not open a surprise prompt.
Configuration and storage
paddle config
This reports the secure credential backend, Keychain service and account names, whether a saved credential exists, and the OpenAPI cache path. It never prints the API key. There is no plaintext credential configuration file.
Interactive API navigator
paddle interactive
The API reference is downloaded from
PaddleHQ/paddle-openapi and cached
under the operating system's user cache directory. The cache contains only the
public API specification, never credentials or responses.
Scripted requests
The request command uses the saved key by default. PADDLE_API_KEY overrides it
for one process:
PADDLE_API_KEY='pdl_sdbx_...' paddle request GET /products
PADDLE_API_KEY='pdl_sdbx_...' paddle request GET /prices \
--query '{"status":"active","per_page":20}'
PADDLE_API_KEY='pdl_sdbx_...' paddle request POST /customers \
--body '{"email":"sam@example.com","name":"Sam Miller"}'
Use --body @request.json to read a JSON body from a file. Writes ask for
confirmation unless --yes is explicitly passed.
Do not put API keys directly in command arguments, checked-in .env files,
shell history, or chat messages.
Other commands
paddle interactive
paddle login
paddle logout
paddle whoami
paddle doctor
paddle config
paddle help request
paddle operations
paddle operations --search subscription
paddle spec update
paddle --version
API permissions
Paddle enforces the permissions assigned to the API key. A read-only key can browse resources but cannot create or update them. Start with the smallest set of permissions needed, especially for live accounts.
AI agent skill
The package includes a compact, reusable agent skill at
skills/paddle-cli/SKILL.md. It teaches AI agents
how to discover operations, use noninteractive commands, protect credentials,
and handle sandbox and live writes safely without copying the full API reference
into their context.
After an interactive login, Paddle CLI offers to install the skill and lets you
select Codex, Claude Code, Cursor, Gemini CLI, GitHub Copilot, OpenCode, or a
compatible agent-skills directory. Run paddle skill install to change the
selection later. Updates never overwrite a skill that you edited.
Development
uv sync
uv run ruff check .
uv run pytest
The test suite uses mocked HTTP transports and does not require or call a real Paddle account.
Maintainers can route-check the current cached Paddle specification against a logged-in sandbox account. The harness forces sandbox, uses deliberately invalid IDs and bodies, suppresses response content, and stops immediately if a write unexpectedly succeeds:
uv run python scripts/e2e_sandbox.py
uv run python scripts/e2e_sandbox.py --include-write-probes
This proves safe route, authentication, and CLI coverage. It does not prove the business behavior of successful create, update, or delete operations.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file paddle_api_cli-0.3.5.tar.gz.
File metadata
- Download URL: paddle_api_cli-0.3.5.tar.gz
- Upload date:
- Size: 78.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47e70fe77c84123ce70b1cf0951685ec8af769429340013a64fc1e88510344f6
|
|
| MD5 |
a908d83b0404a98898c2d482add607cb
|
|
| BLAKE2b-256 |
cfd49133ab37d21bdbb94415cf9dd2f4ca532da4995393ad7b0b06731bb669ed
|
File details
Details for the file paddle_api_cli-0.3.5-py3-none-any.whl.
File metadata
- Download URL: paddle_api_cli-0.3.5-py3-none-any.whl
- Upload date:
- Size: 26.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d755aaaf70eaa45198cf613f88420af9aa7431f0a662f45aeed03a79b11c8562
|
|
| MD5 |
745fcac8ccd88967f922090bec652c06
|
|
| BLAKE2b-256 |
db4ea56bbd7f0676cf1a966a9cbef845713991014af2a49ba26005eb999af3f7
|