# CLI

Source: https://joinsimplesms.com/docs/cli
Index: https://joinsimplesms.com/llms.txt

The CLI ships inside the Node SDK package, so there is nothing to install:

```bash
npx joinsimplesms login
npx joinsimplesms listen --forward-to http://localhost:3000/webhooks
```

Those two commands take you from "signed in" to "webhooks verified on my
machine". Every command works non-interactively and takes `--json`, so an
agent can run them. Installed globally (`npm i -g joinsimplesms`) the
command is `simplesms`.

## Login

```bash
npx joinsimplesms login
```

```text
Open this URL in your browser to approve this login:

  https://joinsimplesms.com/console/cli?code=BCDF-GHJK

Check that the page shows this code:  BCDF-GHJK

Waiting for approval (expires in 10 minutes)...

Logged in to Acme. Test key ssms_sk_test_AbCd... saved to ~/.simplesms.json.
Sandbox number: +15005550123  (sends use it by default)
```

The page shows the code and the name of the machine that asked. Check the code
against your terminal and press **Approve**. The terminal then receives a
**new test key**, named "CLI on your-machine", which appears under
[API keys](/console/keys) like any other and can be revoked there.

- **Test keys only.** A key issued this way is always a sandbox key. For a
  live key, create it in the console and store it with
  `npx joinsimplesms login --key ssms_sk_live_...`.
- **Approve only a login you started.** The link gives whoever started it a
  key on your account. If someone sends you one, press **Deny**.
- A login request lasts 10 minutes, works once, and needs an account admin.
  Approvals and denials are in the [audit log](/docs/audit-logs).
- The key is written to `~/.simplesms.json` (readable only by you) and is
  never printed.
- With `--json`, the first line is
  `{"status":"pending","verification_url":"...","user_code":"..."}` and the
  last is `{"status":"approved","sandbox_number":"...",...}`: an agent
  shows the URL to its user and waits.
- `--no-browser` (or `SIMPLESMS_NO_BROWSER=1`, or `CI`) prints the URL
  without trying to open it.

### Without a browser

```bash
npx joinsimplesms login --key ssms_sk_test_...     # store a key you already have
echo "$KEY" | npx joinsimplesms login              # or pipe it
export SIMPLESMS_API_KEY=ssms_sk_test_...          # or skip the file entirely
```

Which key a command uses, first match wins: `--key`, then
`SIMPLESMS_API_KEY` (then the older `DELIVERED_API_KEY`), then the stored
file.

## Listen

```bash
npx joinsimplesms listen --forward-to http://localhost:3000/webhooks
```

Replays each new event on your account to a local URL, signed like a real
webhook with a secret it prints at startup. No tunnel. Full walkthrough:
[Webhooks: Test locally](/docs/webhooks#test-locally).

| Flag | Does |
| --- | --- |
| `--forward-to <url>` | POST each event here. Without it, events are printed |
| `--events a,b` | Only these event types |
| `--secret whsec_...` | Sign with this secret instead of a new one each session |
| `--json` | One JSON object per line: a `ready` line, then `{"type":"event","event":{...},"forward":{"status":200,"ms":12}}` |

It shows only events that happen after it starts, reconnects by itself if the
connection drops, and stops on Ctrl+C. It reads the event log and nothing
else: your configured endpoints and their delivery logs are not affected.

## Trigger

```bash
npx joinsimplesms trigger message.received
```

Makes a sandbox event happen, so `listen` has something to show. Test keys
only; nothing reaches a carrier.

| Event | What it does |
| --- | --- |
| `message.received` | Simulates an inbound SMS to your sandbox number (`POST /v1/test/inbound`) |
| `message.delivered`, `message.sent` | A sandbox send to `+15005550006`: `message.sent`, then `message.delivered` |
| `message.failed` | A sandbox send to `+15005550002`: `message.sent`, then `message.failed` |

Words after the event name become the message body; `--from` and `--to`
override the numbers. Other events come from doing the thing itself with a
test key, for example `npx joinsimplesms verify +15005550006` for
`verification.sent`.

## Everything else

```bash
npx joinsimplesms send --to +15005550006 "Hello"
npx joinsimplesms verify +14155550132            # send a code
npx joinsimplesms verify +14155550132 482193     # check it
npx joinsimplesms numbers list | search 415 | buy +1... | release +1...
npx joinsimplesms lookup +14155550132
npx joinsimplesms messages --limit 10
npx joinsimplesms events --limit 10
```

Add `--json` to any of them for the raw API object. The commands
`deliveredsms` and `dsms` from before the rename still run.
