Use the Paddle CLI to run Paddle tasks without you at the terminal, like scheduled routines, scripts, and CI/CD pipelines. Commands return results in the same format every time.
For example, an AI agent routine that runs paddle subscriptions list --status past_due --output json every morning gets a list of past-due subscriptions in the same format each time, ready to summarize.
For tasks where you're in the conversation with your agent, checking its work as you go, you can also use the Paddle MCP server.
How it works
You can run the Paddle CLI without being at the terminal in two ways:
- An AI agent runs it for you, using the login you've saved on your computer.
- A CI/CD pipeline or script runs it, using an API key you set as an environment variable.
The CLI adapts when a program runs it instead of a person: it returns JSON rather than tables and returns an exit code for every command. Commands that delete or cancel something need the entity's ID reconfirmed.
The CLI writes results to stdout and everything else to stderr, like errors, the account line, and next-page hints. You can pipe results to another program or save them to a file:
paddle customers list | jq '.data[].id'CLI with AI agents
AI coding agents like Claude Code, Cursor, Codex, and Gemini CLI can run the Paddle CLI using your saved login. You don't need to set anything up in the CLI.
To have your agent use the CLI, mention it in your request. For example:
Use the Paddle CLI to create a monthly price for AeroEdit Pro.To make it the default, add a line like this to your project's CLAUDE.md or AGENTS.md file:
Use the Paddle CLI (`paddle`) for Paddle tasks. Use my sandbox account unless I say otherwise.AI agents can make mistakes
Your agent can do everything your saved login allows. Use a sandbox API key while you're testing, and give live API keys only the permissions your agent needs.
CLI in CI/CD pipelines
In CI/CD pipelines and other places where you can't log in, set your API key and account using environment variables:
export PADDLE_API_KEY=YOUR_API_KEYexport PADDLE_ENVIRONMENT=sandboxpaddle products listStore your API key as a secret in your CI/CD system. Don't commit it to your repository. For more, see API key best practices.
Agent mode
The CLI turns on agent mode on its own when Claude Code, Cursor, Codex, Gemini CLI, OpenCode, Aider, or a CI/CD system runs it. It detects them from environment variables they set, like CLAUDECODE or CI.
Agent mode makes the CLI easier for AI agents to use. In agent mode, the CLI returns compact JSON as the output and turns off colors. It still prints which account it used after each command, like → sandbox.
If the CLI doesn't detect your agent, you can turn on agent mode for it. Set the PADDLE_AGENT environment variable to 1 in your agent's settings, or ask your agent to add --agent to its paddle commands.
If you see JSON instead of tables in your own terminal and didn't ask for it, check whether CI or PADDLE_AGENT is set in your terminal's environment, and unset what you don't need.
Destructive commands
Commands that delete or cancel an entity ask you to confirm the action before they run. In a terminal, you answer a prompt.
In scripts, CI/CD pipelines, and AI agents, you need to pass the entity's Paddle ID a second time with --confirm. Without it, or if the IDs don't match, the command doesn't run and returns exit code 2:
paddle subscriptions cancel sub_01h3h3a9sfpr5syq38tq0sd4sp --confirm sub_01h3h3a9sfpr5syq38tq0sd4spWhen a command takes more than one ID, confirm the last one. That's the entity the command deletes:
paddle payment-methods delete ctm_01hv6y1jedq4p1n0yqn5ba3ky4 paymtd_01hs8zx6x377xfsfrt2bqsevbw --confirm paymtd_01hs8zx6x377xfsfrt2bqsevbwThese commands need confirming:
| Command | What it does |
|---|---|
paddle subscriptions cancel | Cancels a subscription. |
paddle notification-settings delete | Deletes a notification destination. |
paddle payment-methods delete | Deletes a payment method saved for a customer. |
paddle checkout-domains delete | Deletes a checkout domain. |
Exit codes
Every command returns an exit code. Scripts can use it to check what happened without reading the error message. API errors map to an exit code based on their HTTP status code.
| Code | Meaning |
|---|---|
0 | Success. |
1 | General error, like a failed request. |
2 | Usage error, like an unknown command or flag, a missing argument, or a missing --confirm. |
3 | Not found. The API returned 404. |
4 | Authentication error. The API returned 401. Your API key isn't valid. |
5 | Permission error. The API returned 403. You're not logged in, your API key is for the other account, or it doesn't have permission. |
6 | Rate limited. The API returned 429. |
7 | Validation error. The API returned 400 or 422. |
8 | Conflict. The API returned 409. |
9 | Server error. The API returned a 5xx status. |
124 | The request timed out. |
When a script or AI agent runs the CLI, errors are a JSON object on stderr. It has the same fields as an API error, all at the top level, plus the HTTP status and whether the request is retryable:
{ "status": 404, "type": "request_error", "code": "not_found", "detail": "customer ctm_01hv6y1jedq4p1n0yqn5ba3ky4 not found.", "documentation_url": "https://developer.paddle.com/v1/errors/shared/not_found", "request_id": "c0913cb1-ed8b-4050-b740-d810504ed8c4", "retryable": false}