# Anytime CLI (preview)

> The anytime CLI preview: forward test webhook events to localhost, signed like real deliveries, and trigger payment, refund and dispute test events.

Source: https://anytime-capital.com/docs/cli · Markdown: https://anytime-capital.com/docs/cli.md · All docs: https://anytime-capital.com/docs/llms-full.txt

> **Not on npm yet:** `@anytimecapital/cli` is a preview: it isn't published, so you can't install it yet. This page documents how it works. Until it's out, send events to a deployed endpoint with **Send test event** in test mode, or sign a test event yourself as in [Test your handler](https://anytime-capital.com/docs/webhook-signatures.md#test-your-handler).

The `anytime` command line tool makes webhook work local. `anytime listen` forwards your business's events to a server on your own machine, signed exactly as our webhooks sign them, so the verification code you ship is the code you test. `anytime trigger` sends a test event on demand. It needs Node.js 18 or later and nothing else.

## Install

**Once it's published**

```bash
npm install -g @anytimecapital/cli
anytime --help
```

## Log in with a test key

Turn on test mode in the dashboard, create a key in **Settings → Developers** and paste it when `anytime login` asks. The CLI checks it with the API and saves it in your config directory, readable only by you (`0600`). It saves test keys only: a live key is refused, so one never sits on disk.

```bash
anytime login
# or, from a secret manager:
echo "$ANYTIME_TEST_KEY" | anytime login
```

| System | Config file |
| --- | --- |
| macOS and Linux | `~/.config/anytime/config.json` (or `$XDG_CONFIG_HOME/anytime/`) |
| Windows | `%APPDATA%\anytime\config.json` |
| Anywhere | `$ANYTIME_CONFIG_DIR/config.json` when it's set |

The key needs **Events (read)** for `listen` and **Webhook endpoints (write)** for `trigger`; a Full access test key has both. `anytime logout` forgets the key; `anytime logout --all` deletes the file.

## Forward events to localhost

Webhook endpoints must be public `https://` URLs, so a laptop can't be one. `anytime listen` closes that gap from your side: it reads the [Events API](https://anytime-capital.com/docs/events.md) every two seconds and POSTs each new event to the URL you give it, printing the status your server answered.

```text
$ anytime listen --forward-to http://localhost:3000/api/webhooks
Ready. Forwarding test events to http://localhost:3000/api/webhooks
Signing secret: whsec_…
  Set it as your app's webhook secret (e.g. ANYTIME_WEBHOOK_SECRET); every request carries Anytime-Signature.
  Events: all. Checking every 2s with ak_test_Nw4x…9QzA. Ctrl+C to stop.

17:00:20  payment.succeeded        evt_b88d883077c9592700664bd6ffe508e0  → 200 OK (7 ms)
17:00:20  refund.created           evt_a4c3cf027345ff32992cea8804aba126  → 200 OK (3 ms)
17:00:24  invoice.paid             evt_817e0b1fe9b62b9626450752e9f44650  → 500 Internal Server Error (12 ms)
^C
Stopped. 2 delivered, 1 failed.
```

- **The same request as a real delivery:** a JSON POST of the event (`id`, `type`, `created`, `livemode`, `data`) with the `Anytime-Signature`, `Anytime-Event-Id`, `Anytime-Event-Type` and `Anytime-Delivery-Attempt` headers. A `2xx` within 10 seconds counts as delivered; redirects aren't followed.
- **Signed with a local secret:** `listen` makes a `whsec_…` secret the first time and keeps it in your config, so it stays the same between runs. Set it as your app's webhook secret while you develop: `export ANYTIME_WEBHOOK_SECRET=$(anytime listen --print-secret)`.
- **Only new events:** anything that happened before `listen` started is skipped. Each event is forwarded once; a failed one isn't retried, so fix your handler and trigger another.
- **Only what you ask for:** `--events payment.succeeded,refund.*` takes event types and families, as the Events API's `type` filter does.
- **Only your events, never your key:** the key goes to the API; your server gets the event and nothing else.
- **Test mode by default:** a live key is refused unless you pass `--live` with it (`anytime listen --live --api-key ak_live_…`). Live events then go only to an `https://` URL or one on your own machine.
- **Light on your rate limit:** one request every two seconds is 30 of your key's 100 a minute. When the API asks it to slow down it waits the `Retry-After` it gives, and it backs off while the network is down.

Without `--forward-to`, `listen` just prints each event as it happens. With `--json` it prints one JSON object per line, for scripts.

## Trigger test events

`anytime trigger <event>` sends one test event through the [test helpers](https://anytime-capital.com/docs/test-helpers.md), built from your own test data exactly as the real event would be, with `livemode: false`. It goes to your test webhook endpoints and the Events API, so a running `anytime listen` forwards it too. Nothing else changes and no money moves.

```text
$ anytime trigger payment.succeeded
✓ Sent payment.succeeded evt_9b2c4d6e8f0a1b3c5d7e9f1a2b4c6d8e about pay_7Hq2LmX9cR4tVb.
  Queued for 1 test webhook endpoint; a running `anytime listen` forwards it too.
```

| Event | What it carries |
| --- | --- |
| `payment.succeeded` | Payment succeeded |
| `payment.failed` | Payment failed |
| `refund.created` | Refund created |
| `dispute.opened` | Dispute opened |
| `invoice.paid` | Invoice paid |
| `subscription.updated` | Subscription updated |

Each is about your newest test object that fits, or the one `--object pay_…` names. With nothing to send it about yet, it says so: pay a test link with a [test card](https://anytime-capital.com/docs/test-mode.md#test-cards) or load sample data first.

## Check your key

```text
$ anytime whoami
Key:             ak_test_Nw4x…9QzA (test mode)
From:            /home/you/.config/anytime/config.json
API:             https://anytime-capital.com/api/v1
Signing secret:  whsec_…rEAL
Status:          works, and can read events
```

## Open the dashboard and docs

| Command | Opens |
| --- | --- |
| `anytime open dashboard` | Your business dashboard |
| `anytime open developers` | API keys and webhook endpoints |
| `anytime open events` | The event log, with each delivery |
| `anytime open logs` | The API request log |
| `anytime open docs` | These docs |
| `anytime open cli` | This page |
| `anytime open postman` | The [Postman collection](https://anytime-capital.com/docs/postman.md) |
| `anytime open test-mode` | [Test mode](https://anytime-capital.com/docs/test-mode.md) |

## Commands and options

| Command | Does |
| --- | --- |
| `anytime login` | Checks a test key and saves it. `--api-key`, `--base-url`, `--no-verify`. |
| `anytime logout` | Forgets the key; `--all` deletes the config file. |
| `anytime whoami` | The key in use (masked), where it comes from, and whether it works. |
| `anytime listen` | `--forward-to <url>`, `--events <types>`, `--interval <seconds>`, `--live`, `--print-secret`. |
| `anytime trigger <event>` | `--object <id>`; `--list` lists the events. |
| `anytime open <page>` | `--print` prints the URL instead. |

- Every command takes `--help`, `--json` (one JSON object per line) and `--no-color` (or `NO_COLOR=1`).
- `--api-key` or `ANYTIME_CLI_API_KEY` use a key without saving it; `ANYTIME_BASE_URL` points the CLI at another copy of the site.
- Exit codes: `0` done, `1` failed (the message says why, with the API's request id), `2` typed wrong.

## What it doesn't do yet

- **Stream the request log.** The API request log can't be read with a key yet; see it in **Settings → Developers → Request log** (`anytime open logs`).
- **Retry a failed forward.** Trigger the event again, or resend it to a deployed endpoint from the event log.
- **Send events that need a real payment.** `trigger` offers only the events the test helpers can build; the rest come from using test mode, such as paying a link with a test card.

- [Verify signatures](https://anytime-capital.com/docs/webhook-signatures.md): The handler `anytime listen` forwards to, in Node.js, Python and PHP.
- [Test mode](https://anytime-capital.com/docs/test-mode.md): Test keys, test cards, sample data and test events.
- [Events API](https://anytime-capital.com/docs/events.md): What `anytime listen` reads: every event from the last 30 days.

---

Anytime Capital is a fintech company, not a bank. Payment processing, banking and payout services are provided by Anytime Capital's licensed partners. Rates shown are for US card payments; international cards, currency conversion and disputes may carry additional fees shown in your dashboard before you accept a payment.
