> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dodo CLI

> Manage Dodo Payments resources, query your account with an AI assistant, create checkout sessions, and test webhooks from your terminal with the Dodo CLI.

The Dodo CLI manages your Dodo Payments resources, answers questions about your account with a built-in AI assistant, creates checkout sessions, and tests webhooks, all from your terminal. Use its interactive TUI, or run direct subcommands from scripts.

<Frame>
  <iframe className="w-full aspect-video rounded-md" src="https://www.youtube.com/embed/gwtvQsANbW4" title="Dodo CLI | Dodo Payments" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
</Frame>

## Features

* **Interactive TUI**: Run `dodo` with no arguments to open the interactive interface, with a command palette, history, and live notifications.
* **Built-in AI assistant**: Ask questions or take actions in plain English with `/ai`. The assistant runs `dodopayments-mcp` locally and needs no extra setup.
* **Encrypted credentials**: API keys are stored in `~/.dodopayments/config.json`, encrypted with AES-256-GCM and a key derived from your machine. No plaintext credentials are stored on disk.
* **Auto update**: The CLI checks for new versions on startup and notifies you in the TUI. For npm and Bun installs, run `/update` to upgrade in place.
* **Webhook tooling**: Forward test mode webhooks to your local server, or send mock webhook payloads offline.
* **Scaffolding**: Add billing routes to Next.js, Express, and Better Auth projects with `dodo init`.

## Installation

On macOS or Linux, install the latest release binary with the install script:

```bash theme={null}
curl -fsSL https://dodopayments.com/install.sh | sh
```

The script verifies the binary against the release's SHA-256 checksums. It installs `dodo` into the first writable directory among `/usr/local/bin`, `~/.local/bin`, and `~/bin`, or into `~/.local/bin` if none of them is writable. To install a specific release, set the `DODO_VERSION` environment variable to its tag. To choose the directory, set `DODO_INSTALL_DIR`.

### Install with NPM or Bun

If you have Node.js or Bun, install the `dodopayments-cli` package globally. Package manager installs pull the latest published version:

<CodeGroup>
  ```bash npm theme={null}
  npm install -g dodopayments-cli
  ```

  ```bash Bun theme={null}
  bun install -g dodopayments-cli
  ```
</CodeGroup>

<Info>
  Direct subcommands such as `dodo login` run on Node.js 18 or later. When you install through a package manager, the interactive TUI also needs Bun. Release binaries need neither runtime.
</Info>

### Manual Installation (No Node / Bun Required)

To install without running a remote script, download the binary yourself.

<Steps>
  <Step title="Download the Binary">
    Download the binary for your platform from the latest [GitHub Release](https://github.com/dodopayments/dodopayments-cli/releases).

    | Platform | Binary |
    | - | - |
    | macOS (Apple Silicon) | `dodo-cli-darwin-arm64` |
    | macOS (Intel) | `dodo-cli-darwin-x64` |
    | Linux (x86\_64) | `dodo-cli-linux-x64` |
    | Linux (arm64) | `dodo-cli-linux-arm64` |
    | Windows (x86\_64) | `dodo-cli-windows-x64.exe` |
  </Step>

  <Step title="Rename the Binary to `dodo`">
    <CodeGroup>
      ```bash Linux / macOS theme={null}
      mv ./dodo-cli-* ./dodo && chmod +x ./dodo
      ```

      ```powershell Windows theme={null}
      ren .\dodo-cli-windows-x64.exe .\dodo.exe
      ```
    </CodeGroup>
  </Step>

  <Step title="Move It to a Directory on Your PATH">
    <Info>
      On Windows, moving the file to `C:\Windows\System32` requires administrator privileges.
    </Info>

    <CodeGroup>
      ```bash Linux / macOS theme={null}
      sudo mv ./dodo /usr/local/bin/
      ```

      ```powershell Windows theme={null}
      move .\dodo.exe C:\Windows\System32\dodo.exe
      ```
    </CodeGroup>
  </Step>

  <Step title="(Optional) Verify the Download">
    Each release publishes a `SHA256SUMS.txt` file. Download it next to the binary, then verify the binary:

    ```bash theme={null}
    shasum -a 256 -c SHA256SUMS.txt
    ```
  </Step>
</Steps>

## Authentication

Log in with an API key before you run commands that read or change your account. To log in with a direct subcommand, pass the key and its mode, `test` or `live`:

```bash theme={null}
dodo login "$DODO_PAYMENTS_API_KEY" test
```

Or, from inside the interactive TUI:

```text theme={null}
/login
```

The TUI login flow:

1. Opens the **Developer → API Keys** page of the dashboard in your browser.
2. Prompts you to paste your API key.
3. Asks you to choose **Test Mode** or **Live Mode**.

Both commands verify the key with a request to the API, then store it encrypted in `~/.dodopayments/config.json`.

<Info>
  The encryption key is derived from your machine, so the stored credentials work only on that machine. If you upgrade from v3.0.x, which stored keys in the OS keychain, run `dodo login` again. Keys in the older plaintext `~/.dodopayments/api-key` file are migrated automatically, and that file is deleted.
</Info>

### Switching Modes and Logging Out

You can keep one test mode key and one live mode key logged in at the same time. To switch the active mode in the TUI, run `/switch`. To remove stored keys:

<CodeGroup>
  ```bash Direct theme={null}
  dodo logout all
  ```

  ```text TUI theme={null}
  /logout
  ```
</CodeGroup>

In direct mode, pass `test`, `live`, or `all`. In the TUI, `/logout` asks you to choose **All accounts**, **Test Mode**, or **Live Mode**, then asks you to confirm.

## Usage

You can use the CLI in two modes.

### 1. Interactive TUI (Recommended)

Run `dodo` with no arguments to open the interactive interface:

```bash theme={null}
dodo
```

Type `/` to open the command palette. Text that doesn't start with `/` goes to the AI assistant.

| Command | Description |
| - | - |
| `/help` | Show the command reference |
| `/update` | Check for and install a CLI update |
| `/login` | Authenticate with an API key |
| `/logout` | Sign out of one or all environments |
| `/switch` | Switch between test mode and live mode |
| `/clear` | Clear the TUI screen |
| `/exit` | Exit the TUI (also: type `exit`, or press `Esc` twice) |

### 2. Direct Subcommands

Run a command without opening the TUI:

```bash theme={null}
dodo <category> <sub-command> [args...]
```

For example:

```bash theme={null}
dodo payments list 1
dodo customers list 1
dodo wh trigger payment.success http://localhost:3000/webhook
```

The reference tables below list every command in direct-mode form. In the TUI, replace `dodo ` with `/`, for example `/payments list 1`. Commands marked **TUI only** are interactive wizards. In direct mode, they print a message that tells you to open the TUI.

## AI Assistant

Ask questions about your account or take actions in plain English. The assistant runs `dodopayments-mcp` on your machine, so it needs no extra setup or OAuth flow. It calls the Dodo Payments API from your machine with your stored key and sends your prompts to the language model.

| Command | Description |
| - | - |
| `/ai <query>` | Ask the AI assistant a question or give it an instruction |
| *(any non-slash text)* | Sent to the AI assistant by default while in the TUI |

In direct mode, run `dodo ai` followed by your question. Examples in the TUI:

```text theme={null}
how much revenue did I make this week?
/ai create a new customer named Acme Inc.
/ai find my last failed payment
```

<Tip>
  The assistant uses your active mode (test mode or live mode) and works only with that mode's data.
</Tip>

## Project Scaffolding

`dodo init` adds Dodo Payments billing routes to an existing project. It writes the route files, installs the matching `@dodopayments/*` adapter package, and appends any missing `DODO_PAYMENTS_*` variables to your `.env` file with placeholder values. It skips files and variables that already exist, and it runs **without logging in**.

```bash theme={null}
dodo init <framework>
```

| Scaffold | Description |
| - | - |
| `dodo init nextjs` | Scaffold Next.js App Router billing routes (checkout, customer portal, and webhook handlers) using `@dodopayments/nextjs` |
| `dodo init express` | Scaffold Express server billing routes using `@dodopayments/express` |
| `dodo init better-auth` | Scaffold a Better-Auth plugin configuration using `@dodopayments/better-auth` |

For the Better-Auth scaffold, you can pass a comma-separated list of plugins to generate: `checkout`, `portal`, `usage`, and `webhooks`. Without a list, it generates all four.

```bash theme={null}
# Scaffold every Better-Auth plugin (default)
dodo init better-auth

# Scaffold only specific plugins
dodo init better-auth checkout,portal
```

<Info>
  If your project has a `src/` directory, the scaffolder writes files inside it. It picks the install command from your project's lock file (`bun`, `pnpm`, or `yarn`) and uses `npm` when it finds none.
</Info>

## Command Reference

These commands need a logged-in API key. List commands take an optional page number, which defaults to 1, and show up to 100 items per page.

### Products

Manage your product catalog.

| Command | Description |
| - | - |
| `dodo products list <page>` | List products |
| `dodo products create` | Open the dashboard to create a product |
| `dodo products info <id>` | View details for a specific product |

### Payments

View payment transactions.

| Command | Description |
| - | - |
| `dodo payments list <page>` | List payments |
| `dodo payments info <id>` | Get information about a specific payment |

### Customers

Manage your customers.

| Command | Description |
| - | - |
| `dodo customers list <page>` | List customers |
| `dodo customers create` | Create a new customer (**TUI only**) |
| `dodo customers update <id>` | Update an existing customer (**TUI only**) |
| `dodo customers portal <id>` | Create a temporary Customer Portal session for a customer |

### Discounts

Manage discount codes.

| Command | Description |
| - | - |
| `dodo discounts list <page>` | List discounts |
| `dodo discounts create` | Create a new percentage-based discount (**TUI only**) |
| `dodo discounts delete <id>` | Remove a discount by ID (**TUI only**) |

### Licenses

View license keys. The command is spelled `licences`.

| Command | Description |
| - | - |
| `dodo licences list <page>` | List licenses |

### Addons

Manage product add-ons.

| Command | Description |
| - | - |
| `dodo addons list <page>` | List addons |
| `dodo addons create` | Open the dashboard to create an addon |
| `dodo addons info <id>` | View details for a specific addon |

### Refunds

View refund information.

| Command | Description |
| - | - |
| `dodo refunds list <page>` | List refunds |
| `dodo refunds info <id>` | View details for a specific refund |

### Checkout

Create hosted checkout sessions.

| Command | Description |
| - | - |
| `dodo checkout new` | Interactively create a hosted checkout session and get a payment link (**TUI only**) |

## Webhooks

The CLI has two webhook tools for development: a **listener** that forwards test mode webhooks to your local server, and a **trigger** that sends mock webhook payloads to any endpoint.

| Command | Description |
| - | - |
| `dodo wh listen <url>` | Listen for webhooks in real time and forward them to your local dev server |
| `dodo wh trigger <event> <url>` | Send a mock webhook event, even while logged out |

In direct mode, the arguments are required. In the TUI, run `/wh listen` or `/wh trigger` without arguments to open an interactive wizard.

### Listen for Webhooks

Forward webhooks from your Dodo Payments account to your local development server in real time.

<Warning>
  `dodo wh listen` requires a **Test Mode** API key. Live Mode keys are not supported by the listen flow.
</Warning>

```bash theme={null}
dodo wh listen http://localhost:3000/webhook
```

<Steps>
  <Step title="Enter Your Local Endpoint URL">
    Pass the local URL that should receive webhooks, for example `http://localhost:3000/webhook`. In the TUI wizard, the CLI prompts you for it.
  </Step>

  <Step title="Automatic Setup">
    If your account has no webhook endpoint for the CLI's relay server, the CLI creates one. The endpoint appears in **Developer → Webhooks**. The CLI then opens a WebSocket connection to the relay to receive events in real time.
  </Step>

  <Step title="Receive and Forward">
    When a webhook event fires, for example from a test payment or a subscription change, the CLI forwards the payload and headers to your local endpoint as a `POST` request. It logs the event type and your endpoint's response, and sends the response back to the relay.
  </Step>
</Steps>

<Tip>
  The listener preserves the original webhook headers (`webhook-id`, `webhook-signature`, `webhook-timestamp`) when forwarding to your local endpoint, so you can test your signature verification logic.
</Tip>

<Note>
  The relay and the CLI parse the JSON body and serialize it again before forwarding. If the forwarded body differs byte for byte from the original, for example in number formatting, signature verification fails even though the headers are intact.
</Note>

### Trigger Test Webhooks

Send a mock webhook payload to any endpoint, without creating real transactions.

<Warning>
  Triggered events are **not signed**: the request carries no `webhook-id`, `webhook-signature`, or `webhook-timestamp` header. While testing, parse them with the unverified method (`unsafeUnwrap` in TypeScript, `unsafe_unwrap` in Python, `UnsafeUnwrap` in Go) instead of `unwrap`, and switch back to `unwrap` before you go live.
</Warning>

```bash theme={null}
dodo wh trigger payment.success http://localhost:3000/webhook
```

In direct mode, the payload uses placeholder IDs and customer details. The `/wh trigger` wizard in the TUI guides you through:

1. Setting a destination **endpoint URL**.
2. Optionally entering a **Business ID**, **Product ID**, **Metadata** (a JSON object), **Customer email**, and **Customer ID** for the payload. Blank fields use placeholder values.
3. Selecting an **event** to send from an interactive menu. You can send several events in a row. Choose **exit** to finish.

<Info>
  `dodo wh trigger` does **not** require login. It works as a local, offline webhook payload generator.
</Info>

### Supported Webhook Events

`dodo wh trigger` can send mock payloads for 46 of the 48 event types Dodo Payments delivers. It doesn't support `subscription.past_due` or `subscription.unpaused`. Pass the event name exactly as listed:

| Category | Events |
| - | - |
| **Subscription** | `subscription.active`, `subscription.updated`, `subscription.on_hold`, `subscription.renewed`, `subscription.plan_changed`, `subscription.cancelled`, `subscription.failed`, `subscription.expired`, `subscription.paused`, `subscription.update_payment_method` |
| **Payment** | `payment.success`, `payment.failed`, `payment.processing`, `payment.cancelled` |
| **Refund** | `refund.success`, `refund.failed` |
| **Dispute** | `dispute.opened`, `dispute.expired`, `dispute.accepted`, `dispute.cancelled`, `dispute.challenged`, `dispute.won`, `dispute.lost` |
| **License Key** | `licence.created` |
| **Payout** | `payout.created`, `payout.in_progress`, `payout.on_hold`, `payout.failed`, `payout.success` |
| **Credit** | `credit.added`, `credit.deducted`, `credit.expired`, `credit.rolled_over`, `credit.rollover_forfeited`, `credit.overage_charged`, `credit.overage_reset`, `credit.manual_adjustment`, `credit.balance_low` |
| **Abandoned Checkout** | `abandoned_checkout.detected`, `abandoned_checkout.recovered` |
| **Dunning** | `dunning.started`, `dunning.recovered` |
| **Entitlement Grant** | `entitlement_grant.created`, `entitlement_grant.delivered`, `entitlement_grant.failed`, `entitlement_grant.revoked` |

Three trigger names differ from the event `type` in the payload they send: `payment.success` sends `payment.succeeded`, `refund.success` sends `refund.succeeded`, and `licence.created` sends `license_key.created`.

<Note>
  Mock payload shapes follow the corresponding schemas in the API reference. See [Webhook Events](/developer-resources/webhooks/intents/webhook-events-guide) for what each event means and when Dodo Payments emits it in production.
</Note>

<Tip>
  `payout.created` is emitted while the payout still reports a `not_initiated` status, so the mock payload reflects that too. See [Payout Events](/developer-resources/webhooks/intents/payout) for the full payout lifecycle.
</Tip>

### Environment Variables

This variable changes how `dodo wh listen` connects:

| Variable | Description |
| - | - |
| `DODO_WH_TEST_SERVER_URL` | Override the default webhook relay server used by `dodo wh listen`. Set a host name without a scheme. |

## Updates

The CLI checks for a newer version on startup and shows a notification in the status bar when one is available. To upgrade an npm or Bun install from the TUI, run:

```text theme={null}
/update
```

`/update` can't upgrade a release binary. For binary installs, including the install script's, it links to the latest GitHub release instead. To upgrade from your shell, re-run the command you installed with:

<CodeGroup>
  ```bash install.sh theme={null}
  curl -fsSL https://dodopayments.com/install.sh | sh
  ```

  ```bash npm theme={null}
  npm install -g dodopayments-cli
  ```

  ```bash Bun theme={null}
  bun install -g dodopayments-cli
  ```
</CodeGroup>

## Resources

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodopayments-cli">
    Source code and releases.
  </Card>

  <Card title="npm Package" icon="npm" href="https://www.npmjs.com/package/dodopayments-cli">
    The `dodopayments-cli` package on the npm registry.
  </Card>
</CardGroup>

## Support

* **Discord**: Join the [community server](https://discord.gg/bYqAp4ayYh).
* **GitHub**: Open an issue on the [repository](https://github.com/dodopayments/dodopayments-cli/issues).
* **Email**: Contact [support@dodopayments.com](mailto:support@dodopayments.com).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.