# Installing Webhooks CLI

Webhooks CLI is a monitoring and debugging developer tool for Flute webhooks.

It is a command-line and terminal UI application that can display call statuses, inspect delivery logs, manage endpoints, and forward live webhook payloads.
The tool can initiate and test webhooks calls.
This includes the ability to create new webhooks and use existing ones.
It supports all of Flute webhook endpoints.

## Download and Installation

Download and install the application for your appropriate platform.
This may be any directory convenient for you.
It is not a global installation and, so, will run only in the installed directory.

| Platform | Download Link |
|  --- | --- |
| Apple Silicon macOS Linux (curl + sh) | curl -LsSf https://github.com/getflute/flute-webhooks-cli/releases/latest/download/flute-webhooks-cli-installer.sh | sh |
| # macOS / Linux (Homebrew) | brew install getflute/flute-webhooks-cli/flute-webhooks-cli |
| Windows (x64 Windows 10 or 11, PowerShell) | irm https://github.com/getflute/flute-webhooks-cli/releases/latest/download/flute-webhooks-cli-installer.ps1 | iex |


### Updating

When launched, the application automatically checks for a newer version.
When a newer version exists, a non-blocking notice displays. 
To update, in a terminal window, enter: `flute-webhooks-cli update` 
Then launch the application again.

### Configuration

An optional configuration may be used.
This file is automatically created and named `~/.flute/config.toml`.

The following are the default values.

| Setting String | Description |
|  --- | --- |
| default_profile = sandbox | Specifies the default environment profile. Valid values: `sandbox**` or `production`. |
| auto_update_check = true | Specifies checking for updates on each launch but at most once every 24 hours. |
| poll_interval_seconds = 5 | Specifies the polling interval (in seconds). The valid inclusive range: 5 to 60. Out-of-range values fall back to `5` with a warning. |


### Profiles

The following are the profile settings.

| Profile | API Base | OAuth URL |
|  --- | --- | --- |
| `sandbox` (default) | `https://sandbox.api.flute.com` | `https://sandbox.oauth.api.flute.com/oauth2/token` |
| `production` (alias `prod`) | `https://api.flute.com` | `https://oauth.api.flute.com/oauth2/token` |


Use --profile (global flag, accepted before or after the subcommand).
Active profile is shown in the dashboard title.

## Running Webhooks CLI

Webhooks CLI may be run in one of two modes: **TUI** (terminal user interface) and **command line**.

### TUI (terminal user interface) Mode

The TUI is an interactive user interface that runs entirely in a terminal window in text mode.
The user selects items arranged in rows by selecting arrow keys from the keyboard.
Items may also be expanded or have check boxes selected.

![Webhooks example](/img/webhook-tui-application.png)

To start the application in TUI, in a terminal window from its installation directory, enter: 
`flute-webhook-cli tui`

#### TUI key bindings

Context	Keys

TUI key bindings

| Context | Controls |
|  --- | --- |
| Top level | `Tab` switch tabs `q` quit `Ctrl-C` quit anywhere |
| Endpoints tab | `↑↓` / `jk` navigate  `c` create  `e` / `Enter` edit  `d` delete  `p` ping |
| Delivery Logs tab | `↑↓` / `jk` navigate  `PgUp` / `PgDn` / `Home` / `End` jump  `v` / `Enter` view details  `t` trigger forward  `r` retry (failed deliveries only)  `l` listener config  `1` cycle endpoint filter  `2` cycle event-type filter  `3` cycle status filter  `s` toggle sort  `x` clear filters |
| Form modal (create/edit) | `Tab` / `↑↓` move between fields  `←→` swap Cancel/Submit  `Space` / `Enter` toggle controls  `PgUp` / `PgDn` scroll the event list  `Esc` cancel |
| Listener modal | `Tab` / `↑↓` move between fields  type the URL  `Space` toggle Enabled  `Enter` activate  `Esc` cancel |
| Delete confirm | `y` / `Enter` delete  `n` / `Esc` cancel |
| Details modal | `↑↓` / `jk` scroll  `PgUp` / `PgDn` page  `Esc` / `Enter` / `q` close |
| Error modal | Enter/Esc dismiss (every other key is absorbed). |
| Update-available modal | Enter/Esc dismiss (every other key is absorbed). |


While typing in a text field (URL or Name), single-character keys such as q, c, d, e, p, r, l, t are treated as literal characters.
They will not trigger the corresponding TUI commands.

### Command Line Mode

The CLI (command line interface) mode may be used to issue instructions through a terminal window command line.
It is scriptable.
For example, the following may be included in a script.

```cli
flute-webhooks-cli webhooks endpoints list
flute-webhooks-cli --output json webhooks deliveries list --limit 15 | jq
```

#### CLI Reference

The following endpoints are available.

flute-webhooks-cli webhooks endpoints list 
flute-webhooks-cli webhooks endpoints get <id> 
flute-webhooks-cli webhooks endpoints create --url https://… --events 
     transaction.card.captured,refund.completed [--name "My Hook"] 
flute-webhooks-cli webhooks endpoints update <id> 
     [--url …] [--events …] [--name …] [--status active|inactive] 
flute-webhooks-cli webhooks endpoints delete <id> --yes 
flute-webhooks-cli webhooks endpoints ping <id> \

#### Event-types catalog

flute-webhooks-cli webhooks event-types list

##### Delivery logs

flute-webhooks-cli webhooks deliveries list 
     [--endpoint-id <id>] [--status success|failed] [--limit 50] 
flute-webhooks-cli webhooks deliveries get <id> 
flute-webhooks-cli webhooks deliveries retry <id>

##### Headless listener — POSTs every NEW successful delivery's headers + body

# to a local URL. Runs in the foreground until Ctrl-C.

flute-webhooks-cli listen --forward-to http://127.0.0.1:3000/webhook

##### Global flags (work on every subcommand):

* --profile <sandbox|production>
* --debug
* --output table|json.


## Authenticating

flute-webhooks-cli auth login 
(or: cargo run -- auth login)

You'll be prompted for **client_id** and **client_secret**.
The secret prompt is hidden (no echo).
Credentials are stored in your OS keychain.
It will never be in plaintext on disk.

By default this stores credentials for the sandbox profile.
To set up production:
flute-webhooks-cli --profile production auth login

### Verifying

flute-webhooks-cli auth token
Prints the current bearer JWT (useful for curl smoke tests).

### Listing Commands

Coverage: TUI ↔ CLI
Every documented Webhook API call is reachable from both modes:

### Capabilities

| Action | TUI | CLI |
|  --- | --- | --- |
| List endpoints | Endpoints tab | `webhooks endpoints list` |
| Get one endpoint | implicit (table shows all fields) | `webhooks endpoints get &lt;id&gt;` |
| Create endpoint | `c` → form modal | `webhooks endpoints create` |
| Update endpoint | `e` → `Enter` → form modal | `webhooks endpoints update &lt;id&gt;` |
| Delete endpoint | `d` → confirm modal | `webhooks endpoints delete &lt;id&gt; --yes` |
| Ping endpoint | `p` (toast on result) | `webhooks endpoints ping &lt;id&gt;` |
| List event types | used to populate the form | `webhooks event-types list` |
| List delivery logs | Delivery Logs tab | `webhooks deliveries list` |
| Get delivery log detail | `v` / `Enter` → details modal | `webhooks deliveries get &lt;id&gt;` |
| Retry failed delivery | `r` on a failed row | `webhooks deliveries retry &lt;id&gt;` |
| Listen + forward locally | `l` → listener modal | `flute-webhooks-cli listen --forward-to &lt;url&gt;` |
| Manual one-shot forward | `t` on a successful row | *(listen covers it; manual one-shot deferred)* |


`--output json` works on every CLI subcommand, producing pretty-printed JSON for piping into jq. 
Use `--output json >> output.json` to save the output to a file.

## Debugging HTTP traffic

Pass --debug to log every HTTP request and response (status, URL, body) at debug level:

flute-webhooks-cli --debug auth token        # traces print to STDOUT 
flute-webhooks-cli --debug tui               # TUI: traces go to ~/.flute/flute-webhooks-cli.log

For non-TUI commands, traces print to stdout so you can pipe them through jq / grep.
For the TUI, stdout is owned by ratatui, so traces are appended to `~/.flute/flute-webhooks-cli.log`.
Instead, open a second terminal and tail `-f ~/.flute/flute-webhooks-cli.log` to watch live.
Response bodies are logged in full (no truncation) so server stack traces are captured intact; the bearer token is never logged.

Without --debug, default tracing is INFO/WARN — non-TUI commands write to stderr, the TUI writes to the log file.

## Troubleshooting

The following are troubleshooting solutions.

| Issue | Resolution |
|  --- | --- |
| No credentials for the sandbox | Enter: `flute-webhooks-cli auth login` |
| Terminal looks broken after a crash | The panic hook should restore it automatically.If it didn't, run `reset` or `stty sane`. |
| Busy "try again in a moment | The action queue is briefly saturated by an in-flight API call. The next press will go through. |
| macOS Keychain prompts every time with `cargo run` | Every cargo build produces a new unsigned binary, and macOS Keychain ACLs are tied to the binary's code signature, so "Always Allow" doesn't survive a rebuild.The app stores credentials as a single keychain entry per profile (one prompt instead of two on the legacy layout).For development, install once into `~/.cargo/bin` (`cargo install --path .`) and click "Always Allow" on that stable binary. Re-running it won't re-prompt until you `cargo install` again. |
| The polling cadence seems slow after an error | That's the exponential backoff.On consecutive `401` / `403` / `404` / `5xx` (or transport) failures the poll interval doubles each time, capped at 30 seconds (or your configured base interval if it's larger — backoff never polls faster than your normal cadence).The counter resets to zero on the first successful poll.The error modal stays up so you can monitor the progress. |
| Token refresh | Bearer tokens are cached in memory and proactively refreshed 60 seconds before their advertised expiry.If the server returns a `401` anyway (clock skew, server restart, revocation), the client invalidates the cache, fetches a fresh token, and retries the original request once.Only requests that fail twice in a row are surfaced as errors. |
| POST requests require a `Content-Length` | Fixed: bodyless `POST` / `PUT` / `PATCH` requests now always send `Content-Length: 0` (the Flute gateway requires it on every write-method request). |


## License

MIT.