CLI

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 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.
  • 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.

FlagDoes
--forward-to <url>POST each event here. Without it, events are printed
--events a,bOnly these event types
--secret whsec_...Sign with this secret instead of a new one each session
--jsonOne 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.

EventWhat it does
message.receivedSimulates an inbound SMS to your sandbox number (POST /v1/test/inbound)
message.delivered, message.sentA sandbox send to +15005550006: message.sent, then message.delivered
message.failedA 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.