# Flute CLI

Flute CLI is a cross-platform command-line interface for the Flute payments platform.

It covers the full transaction lifecycle for both card and ACH payments, including the customer vault, POS transactions, terminals and devices, settlement batches, subscriptions, and ISV API key management.

It ships as one self-contained executable, and every command can be scripted.
Each one supports a structured JSON output mode with consistent exit codes and error envelopes, making Flute CLI well-suited to a shell script, CI pipeline, or AI agent rather than manual, interactive use.

## Common Use Cases

Flute CLI is best suited to workflows where payments logic needs to run outside a browser session.
The following are representative use cases.

**Automation and CI/CD pipelines** 
Because every invocation is single-shot and non-interactive, flute commands integrate directly into shell scripts, deployment pipelines, and scheduled jobs.
Combined with structured JSON output and semantic exit codes, this allows payment operations to be embedded in existing automation without a custom API integration.

**Pre-production testing** 
During development, flute transactions sale and related commands let a developer validate card behavior, error handling, and webhook delivery against the sandbox environment directly from a terminal, ahead of writing SDK-based integration code.

**Operational diagnostics** 
Support and operations engineers can inspect individual transactions, settlement batches, or terminal and device status without navigating a dashboard UI.
The --debug flag surfaces the underlying HTTP request and response for cases requiring lower-level troubleshooting.

**Reconciliation and reporting** 
Finance and operations teams can incorporate settlement batch data into scheduled reconciliation scripts, piping --output json results into downstream tooling such as jq for further processing.

**Bulk account administration** 
For ISVs managing multiple merchants, the CLI supports scripted API key issuance and rotation, customer vault maintenance, and subscription lifecycle management at scale, in place of manual, one-at-a-time dashboard operations.

**Agent and automation integration** 
The structured output envelope and semantic exit codes are designed to be consumed programmatically, allowing AI agents and other automated systems to invoke flute directly for tasks such as transaction lookups or refund issuance.

In general, flute is the appropriate tool where payments functionality must be driven by automation or scripting rather than interactive use; the dashboard remains the more direct path for one-off, manual operations.

## Installing Flute CLI

Download and install the application for your platform. 
The latest installer can always be found at:
https://github.com/getflute/flute-cli/releases/latest

### Installing for macOS or Linux (Homebrew)

Use the following command to install the application for macOS or Linux using Homebrew.

```bash
brew install getflute/flute-cli/flute
```

### Installing for macOS or Linux (Shell Script, Maps to GitHub Releases)

Use the following command to install the application for macOS or Linux using cURL.

```bash
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/getflute/flute-cli/releases/latest/download/flute-installer.sh | sh
```

### Installing for Windows

Use the following command from any location with either a Windows command window or a PowerShell window.
This does not require elevated permissions.

```bash
powershell -ExecutionPolicy Bypass -c "irm https://github.com/getflute/flute-cli/releases/download/v1.1.3/flute-installer.ps1 | iex"
```

Close the command window and open a new one to verify the installation.

### Verifying Flute CLI Installation

To verify that the installation was successful, run either:

* `flute version`
* `flute --version`


### Checking the Application Version

To check the installed version, at any time, run:

* `flute version'


This displays Flute CLI version and active profile.

### Seeing Help for Flute CLI

To get a list of general help commands, run:

* `flute --help`


To get a list of help commands for any command group, run:

* `flute <group> --help`


For help with specific command groups, see [Displaying available commands](#displaying-available-commands)

### Updating Flute CLI

When launched, the application automatically checks for a newer version.
If a newer version exists, a non-blocking notice displays.

To explicitly update the application, run:

* `flute update`


This downloads and installs the latest GitHub Release binary in place.
If the CLI was built from source, this command prints a no-op message instead.

### Checking the Application Health and Version

Before checking the status, you must be logged in. 
To log in, see [Authenticating the User](#authenticating-the-user)

To check the status and functioning condition of the application, run:

* `flute ping`


### Configuring Flute CLI Settings

For configuration options and saving them, see [Configuring Flute CLI](#configuring-flute-cli).

## Authenticating the User

Before using this application, you must be logged in using authentication.
Use your merchant or partner API key credentials

To authenticate interactively, use:

* `flute auth login`


You will be prompted for your `client_id` and `client_secret`.
The secret prompt is hidden.

We recommend immediately checking the login status.
Run: 
`flute auth status`

Once entered, the credentials are stored in the OS keychain, keyed for each profile.
There is no need to run this command again unless the credentials have changed or you logout.
For example, this may be because of routine API key rotation or because the API key was compromised.

The `auth` command group also includes:

| Command | Description |
|  --- | --- |
| `flute auth login` | Authenticates interactively and stores credentials in the OS keychain |
| `flute auth logout` | Removes stored credentials for the active profile |
| `flute auth status` | Displays the active profile and authentication status |
| `flute auth switch` | Switches the active profile |
| `flute auth token` | Prints the current bearer token |


## Running Flute CLI

Flute CLI runs in a single, non-interactive mode.
Each invocation is a single command with arguments and flags that runs once, displays output, and exits.
This is intended for scripting, automation, and one-off lookups.
Use a command window for all commands.
Elevated permissions are not required.

### Example

The following example demonstrates charging a card.
This example call uses the endpoint `POST /pay-api/v1/transactions/sale`.
Use the following command. Of course, the card information must be valid. 
`flute transactions sale --amount 10.00 --card 4111111111111111 --exp 12/27 --cvv 123 --lineAddress1 "35 S. North Street" --zipCode "12345"`

### Displaying Available Commands

Flute CLI groups its functionality into command groups.
Each covers one area of the payments platform, such as API endpoint groups.
These range from authentication and card transactions to ACH, subscriptions, and API key management.

The table below lists each group alongside the subcommands it supports and a brief description of what it does.
A complete, current list of groups and their available flags can be seen using: 
`flute --help`

Groups that touch cardholder or bank data, such as `transactions` and `customers`, also accept AVS `--billing-*` flags for address verification.

The following is a list of available groups.

| Group | Available commands |
|  --- | --- |
| ach | `debit`, `credit`, `void`, `refund` — ACH bank-transfer payments |
| auth | `login`, `logout`, `status`, `switch`, `token` — credential and profile management |
| completion | Prints shell completion script |
| customers | `create`, `get`, `list`, `update`, `delete`, `add-card`, `add-ach`, `methods`, `remove-method` — customer vault. `create`/`update` accept AVS `--billing-*` flags |
| devices | `list`, `get`, `register`, `ttp-jwt`, `ttp-activate` — mobile payment device management |
| keys | `create`, `list`, `revoke` — ISV API key management (`tokens` is a deprecated alias) |
| ping | Displays the API health check |
| pos | `create` (with `--wait` long-poll), `get`, `list`, `cancel` — POS transactions |
| settlements | `list`, `get` — settlement batch queries |
| subscriptions | `create`, `get`, `list`, `payments`, `terminate` — recurring billing |
| terminals | `list`, `status` — POS terminal management |
| transactions | `sale`, `auth`, `capture`, `void`, `refund`, `settle`, `tip-adjust`, `get`, `list`, `inspect` — card payment lifecycle. `sale`/`auth` accept AVS `--billing-*` flags |
| update | Self-updates to the latest GitHub release |
| version | Prints CLI version and active profile |


### Displaying Commands Help

Every command group and subcommand in Flute CLI ships with its own contextual help.
To see help for a specific command, run: 
`flute <group> --help` 
For example: 
`flute customers --help` 
This lists the subcommands available under that group, along with a short description of each.

More detailed help is also available for those subcommands.
To see help for a specific subcommand, run: 
`flute <group> <subcommand> --help` 
For example: 
`flute customers create --help` 
This shows the exact flags, defaults, and examples for that specific action.
This holds for every group in the command overview above, including any newly added to the API suite.

## Displaying Output

Output modes may be specified.
They are controlled by:

* The command flag `--output table|json|quiet`
* The `FLUTE_OUTPUT` environment variable
* The `output` key in `~/.flute/config.toml`


The format of the output is specified with:

| Mode | Description |
|  --- | --- |
| table | This is an abbreviated table intended as a quick review. This is the default. |
| json | Structured envelope, suitable for scripts and agents. This displays the complete response body as returned by the API call. It is in JSON format. |
| quiet | Resource ID only, one per line. This is ideal for shell capture. For example: `TXN=$(flute --output quiet transactions sale --amount 10.00 …)` |


For example: 
`flute transactions sale --amount 10.00 --card 4111111111111111 --exp 12/27 --cvv 123 --output json`

`--output json` wraps every success response in a consistent envelope.
The following is a snippet of the response.

```json
{
  "object": "transaction_list",
  "data": {
    "filtered_count": 4,
    "items": [
      {
        "amount": {
          "baseAmount": 10.00,
          "cashDiscountAmount": 0,
          "cashDiscountRate": 0,
          "percentageOffAmount": 0.00,
  ...
```

Errors (non-zero exit codes) are also written to stdout as structured JSON when `--output json` is active.
One of the response fields, `kind`, is any of `api`, `transport`, `auth`, `decode`, or `client`.
The example below shows a typical response line:

```json
{ "kind": "api", "message": "<error message>", "status": 422, "correlation_id": "<uuid>" }
```

Data always goes to stdout.
Tracing, the production banner, and update notices always go to stderr. Parse one stream, never both.

### Semantic Exit Codes

Every flute invocation exits with one of five status codes.
A script or CI pipeline can branch on the outcome without parsing the rest of the output.
The code distinguishes a clean success from:

* An unexpected failure
* An authentication problem
* A validation or input error
* A not-found result


Each is mapped consistently regardless of which command produced it.

Under `--output json`, that same code also matches the `kind` reported in the error envelope.
This allows callers reading structured output and callers checking `$?` to reach the same conclusion.

The following is a list of the exit codes.

| Code | Meaning |
|  --- | --- |
| 0 | Success |
| 1 | General / unexpected (transport, decode, server 5xx) |
| 2 | Auth failure (401/403 or missing credentials) |
| 3 | Validation / bad input — server 400/422, client-side validation, or CLI usage/parse errors |
| 4 | Not found (404) |


Under `--output json`, CLI usage/parse errors are also written to stdout as a `{ "kind": "client", "message": … }` envelope (exit `3`).
A machine consumer never gets an empty stdout on a bad invocation.

## Logging and Debugging

Flute CLI writes all logs to stderr.
Command output goes to stdout.
That split holds even with `--debug`.
This means a `flute --debug --output json …` still emits a clean, parseable JSON document on stdout.

By default, only warnings and a few brief notices are logged.
For example, a one-line note appears when a stale token triggers the automatic single 401 retry.
Successful commands are otherwise quiet on stderr apart from the production banner.

### Understanding the `--debug` Flag

The global `--debug` flag displays the full HTTP request/response traces (method, URL, status, and body) to stderr:

```bash
flute --debug ping
flute --debug transactions get <txn-id>
```

Sensitive fields are masked before anything is logged:

| Field | How it appears in logs |
|  --- | --- |
| Card / bank account numbers (`cardNumber`, `accountNumber`, `routingNumber`, `pan`) | Masked to the last four digits. For example, `************1111`. |
| CVV / security code (`securityCode`, `cvv`, `cvc`) | Removed entirely. For example, `***`. |
| Bearer token | Never logged. It is sent as a header, never part of the body trace. |


Masking lowers the risk but does not eliminate it: a `--debug` trace still reveals amounts, the last 4 digits, and request metadata. Avoid capturing `--debug` output into shared or long-lived logs when operating on `production`.

### `RUST_LOG`

Setting `RUST_LOG` overrides the built-in filters entirely and accepts the standard `EnvFilter` syntax. The same field masking is applied to `flute`'s own traces no matter how the level is set.

```bash
# Only flute's own HTTP traces, nothing from dependency crates
RUST_LOG=flute_cli=debug flute ping

# Add connection / TLS / DNS detail from the HTTP stack
RUST_LOG=flute_cli=debug,reqwest=debug,hyper=debug flute ping
```

#### Filter Presets

| Mode | Effective filter |
|  --- | --- |
| Default | `warn,flute_cli=info` |
| `--debug` | `debug,flute_cli=debug,reqwest=debug,hyper=info` |
| `RUST_LOG` set | Your value (overrides both of the above) |


#### Quick Reference

| Goal | Command |
|  --- | --- |
| See the API's response when a command fails | flute --debug <cmd> — read the HTTP response line on stderr |
| Get a structured error for a script | `--output json` — error envelope (`kind` / `message` / `status` / `correlation_id`) on stdout |
| Diagnose TLS / DNS / connection problems | `RUST_LOG=flute_cli=debug,reqwest=debug,hyper=debug flute ping` |
| Confirm which environment/URL is being hit | `flute --debug ping` (the request URL is in the trace) |


Command errors are always printed to stderr (and to stdout as JSON under `--output json`) regardless of the log level.

## Shell Completions

Flute CLI's logging verbosity follows one of three presets, depending on how it's invoked.

* A plain command uses the quiet default
* Warnings only. Adding `--debug` switches to a much noisier preset that includes HTTP traces from flute itself and its underlying connection libraries;
* Setting `RUST_LOG` directly overrides both, giving full control over exactly which modules log at which level.


The table below shows the effective filter string each of these resolves to.

| Shell | Notes |
|  --- | --- |
| bash | Sourced from a directory such as `/etc/bash_completion.d/` |
| zsh | Sourced from a directory on `$fpath`. For example, `/usr/local/share/zsh/site-functions` |
| fish | Sourced from `~/.config/fish/completions/` |
| powershell | Appended to your PowerShell `$PROFILE` script |
| elvish | Appended to `~/.config/elvish/rc.elv` |


Generate and install a completion script:

```bash
# Bash
flute completion bash > /etc/bash_completion.d/flute

# Zsh (add to a directory on $fpath; for example, /usr/local/share/zsh/site-functions)
flute completion zsh > /usr/local/share/zsh/site-functions/_flute

# Fish
flute completion fish > ~/.config/fish/completions/flute.fish

# PowerShell
flute completion powershell >> $PROFILE

# Elvish
flute completion elvish >> ~/.config/elvish/rc.elv
```

## Configuring Flute CLI

An optional configuration file may be manually created at: `~/.flute/config.toml`.
It stores non-secret settings such as `default_profile` and `output`; credentials are always kept in the OS keychain, keyed per profile, never in the config file.

Precedence for all settings: flag > environment variable > profile config > global `config.toml` default.

### Profiles for Flute CLI

| Profile | Alias | API Base URL |
|  --- | --- | --- |
| `sandbox` (default) | — | `https://sandbox.api.flute.com` |
| `production` | `prod` | `https://api.flute.com` |


Running any command against `production` prints a red warning banner to stderr.

To select a profile, in order of highest precedence first:

1. Flag: `--profile production`
2. Environment variable: `FLUTE_PROFILE=production`
3. Config file default: `~/.flute/config.toml` → `default_profile = "production"`


## For AI Agents and MCP

Every non-interactive command supports the structured `--output json` envelope described above, which makes Flute CLI straightforward to drive from scripts and agents.

For the full machine-readable contract, that is, structured output format, error JSON schema, exit codes, an idempotency table, and copy-pasteable command recipes for common agent intents.
See `agents.md` in the [flute-cli repository](https://github.com/getflute/flute-cli).

## License

MIT.