- Reference
- Command line reference
Reference
Command line reference
Every wb command and every argument it accepts.
Command line reference
wb is the WhooshBang command line. It ships inside the SDK package, so it
arrives with @whooshbang/sdk rather than as a separate install.
npm install @whooshbang/sdk
npx wb login
npx wb finds the command once the package is installed in the current
project. Running it in a directory that does not depend on
@whooshbang/sdk makes npx look for a package literally called wb and
report could not determine executable to run, which says nothing about
what is wrong. Install first, or use npm install -g @whooshbang/sdk for a
wb on your path everywhere.
The short path
Three commands take an empty organization to a message on a phone.
npx wb project create "My App" # project, connection and route
npx wb subscriber create me # prints an invitation to open on a phone
npx wb send me "Hello" # …or: npx wb ask me "Ship it?" --wait
Conventions that apply everywhere
Global options
| Option | Meaning |
|---|---|
--api-url <origin> | Which deployment to talk to. Defaults to WHOOSHBANG_API_URL, then https://api.whooshbang.com. |
--json | Machine-readable output. Every command prints the API resource verbatim. |
--key <value> | The idempotency key for a side-effecting command. Generated per invocation when omitted, so a retried command is a replay rather than a second message. |
--help | Usage, then exit. |
--version | The installed version, then exit. |
Short forms
Every short form has a long form, and error messages always name the long one, so nothing has to be memorised to recover from a mistake.
| Short | Long |
|---|---|
-p | --project |
-e, --env | --environment |
-s | --subscriber |
-t | --text |
-c | --connection |
-m | --mode |
-n | --name |
-k | --key |
-w | --wait |
-y | --yes |
Naming a project and an environment
A project is named by its id or its slug. An environment is named by its id, or
by test or live — whichever the output in front of you shows.
Both are remembered per deployment after the first use, in
~/.config/whooshbang/context.json. So --project and --environment are
overrides rather than things to retype, and a project id belonging to staging can
never be used against production. wb where shows the current pair and wb use
changes it.
The environment defaults to test, which is where somebody trying the product
belongs and the only default under which a mistake is harmless.
Credentials decide which routes are reachable
A project credential — what wb credential create issues — already names one
project and one environment, so the message commands need neither and use the
flat routes. An organization credential — what wb credential create --organization
issues — belongs to the whole organization and names its project per call, so
--project is a real selector rather than a flag that works only for signed-in
people. An OAuth session — what wb login creates — covers the whole organization
the same way. The commands choose the right route for whichever authority is
present; you do not.
Organization-scoped commands (whoami, project create, and every connection
command) need an OAuth session. Credential commands use that login to select the
organization, then require a separate browser confirmation for each operation. project list also accepts an
organization credential carrying both organization:read and projects:read, which is
what lets a script name a project by slug.
Presenting a key instead of signing in
A CI job, a cron entry or an agent has nobody to open a browser, so it presents a key. There are three places to put one, consulted in this order:
| Source | For |
|---|---|
WHOOSHBANG_API_KEY | A value your scheduler injects. Never written to disk, so it does not outlive the run. |
WHOOSHBANG_API_KEY_FILE | A path. Kubernetes, systemd and Docker secrets hand you a file rather than a value, and this reads it without a wrapper script that would leave the secret in shell history. |
wb login --credential-stdin | A key you keep. Stored per deployment alongside an OAuth session, so you stop retyping it at a terminal. |
export WHOOSHBANG_API_KEY=...
npx wb message send --project my-app --subscriber me --text "Build 41 is out"
# …or point at a mounted secret
export WHOOSHBANG_API_KEY_FILE=/run/secrets/whooshbang
# …or keep one for this deployment
printf %s "$KEY" | npx wb login --credential-stdin
A file that is named but cannot be read is an error rather than a quiet fall back
to whatever wb login stored — falling back would run your command as a
different identity than you asked for. The key goes in on standard input rather
than as a flag value because anything in a flag is visible in a process listing
and lands in your shell history.
wb logout forgets a stored key exactly as it forgets a session. It tells no
authorization server, because none issued the key: it stays valid until somebody
revokes it.
An organization key can name any project in its own organization; a project key can only ever name its own, and says so if you try.
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | The service refused the request, or failed. |
2 | The command was written wrongly. |
3 | Not signed in to this deployment. |
Session
wb login
Signs in through your browser using OAuth with PKCE, and stores the result
owner-only in ~/.config/whooshbang/cli-credentials.json, keyed by deployment —
so signing in to staging never overwrites production.
| Argument | Meaning |
|---|---|
--scope <scope> | Repeatable. Ask for narrower authority than the default set. |
--credential-stdin | Skip the browser and store a key read from standard input instead. |
On a machine with no browser the URL is printed instead of opened, so wb login
over SSH is an ordinary thing to do.
wb logout
Ends the session for this deployment and forgets the token, or the key. It does not forget which project you were working in; signing back in puts you where you left off.
wb whoami
Shows the signed-in organization. Needs an OAuth session.
wb where
Prints the project and environment currently in use for this deployment, or says that nothing has been used yet.
wb use <project> [test|live]
Points subsequent commands at a different project or environment, and records the choice. The environment argument is optional.
npx wb use my-app live
Projects
wb project create <name>
Creates the project, its test and live environments, and a default notifier in each. It then connects the shared WhooshBang channel in test and routes it, because a project with no way to send is not a thing anybody wanted. The new project becomes the remembered one.
| Argument | Meaning |
|---|---|
<name> | Positional. What the project is called for humans. |
--slug <slug> | Its URL-safe short name. Derived from the name when omitted. |
--no-connection | Create the project alone, and connect a channel later. |
If the channel cannot be created the project is still reported, along with the reason — the project exists and is what was asked for, and one command recovers the rest.
wb project update --privacy-mode <mode>
Choose minimal (the default for new and existing projects), standard, or
private. minimal keeps recipient language only. standard permits messenger
profile data. private retains routing and your subscriber identifier, with no
profile data. Use --project <id-or-slug> to choose a project or omit it to use
the current project. This setting applies to both test and live environments.
Moving from standard to minimal erases existing identifying profile fields.
Moving to private also erases recipient language. Raising collection later
does not restore erased data. You can also set the initial mode with
wb project create "My App" --privacy-mode private.
wb project list
Lists the projects in the organization.
Credentials
Availability: the browser-confirmed credential flow below is included in repository builds. The current npm release does not yet include it; use the dashboard’s credential controls until the next client package release.
Each credential command opens a browser confirmation. Sign in to the same organization as your CLI login, review the action, target and permissions, and choose Confirm operation. After completion, choose Send result to CLI. Keep the original page open until the terminal receives the result; it also offers the one-time key for copying if the connection fails. Cancel makes no change.
Confirmation expires after five minutes. The browser and CLI must be on the same computer. These commands cannot run unattended or over an unforwarded SSH session; use the dashboard’s credential controls in that situation. If the terminal times out after you confirmed a mutation, inspect the browser result and dashboard before running it again. The operation may already have succeeded.
wb credential create
Issues a project credential for one environment. The complete secret is printed
once and never again; it goes to standard output while its warning goes to
standard error, so wb credential create > secret.txt captures the value and
still shows you the warning.
| Argument | Meaning |
|---|---|
--label <text> | Required. How the credential is identified afterwards. |
--scope <scope> | Repeatable. What it may do. |
--organization | Issue an organization credential instead: it belongs to the organization, names its project per call, and takes no --project or --environment. |
--project, --environment | Which environment it belongs to. Project credentials only. |
An organization credential is never wider than a project credential would have been
for the same project: on the routes that name a project, it can do exactly what a
project key with the same scopes could do there, and no more. The one thing it
can do that no project key can is organization:read — which, together with
projects:read, lists the organization’s projects, and is how --project my-app
resolves without a browser.
wb credential list
Lists credentials, when each was last used, and whether it is still active.
Defaults to the resolved project environment; --organization lists the organization’s own
keys instead.
| Argument | Meaning |
|---|---|
--organization | List organization credentials rather than one environment’s. |
wb credential rotate <id>
Issues a replacement with the same label and scopes, and starts a countdown on the one it replaces. The new secret is printed once; the deadline on the old one is printed with it, because that is the part you have to act on.
| Argument | Meaning |
|---|---|
--overlap <seconds> | How long the replaced credential keeps working, 0 through 86400. Defaults to 3600. |
--organization | Rotate an organization credential. |
wb credential revoke <id>
Ends the credential immediately. Repeating it is safe and says the same thing, so running it twice when you are not sure the first one landed costs nothing.
| Argument | Meaning |
|---|---|
--organization | Revoke an organization credential. |
All four require browser confirmation. A key cannot manage keys — presenting one is refused before the request, with a message saying so, rather than failing as though the key were bad. That is deliberate: a credential able to mint or kill another would make every scope on it a scope on all of them. The same reasoning keeps credential lifecycle off the MCP tool surface entirely.
Connections
A connection is the identity your subscribers see. Creating one attaches it to the environment’s default notifier, because somebody creating a connection means to send through it.
wb connection create
| Argument | Meaning |
|---|---|
--mode <mode> | whooshbang_shared, customer_managed, or customer_byok. Defaults to whooshbang_shared. |
--name <text> | What to call it. Named after the mode when omitted. |
--shared-identity <id> | For whooshbang_shared. Defaults to the only identity offered; required only when more than one is. |
--credential-stdin | For customer_byok. Reads the bot token from standard input. |
--username <name> | For customer_managed. The @username prefilled in Telegram’s dialog. |
--no-route | Create it without attaching it to the default notifier. |
A customer-owned bot token must arrive on standard input. A token passed as a
command argument is visible to every process on the machine and lands in your
shell history, so --credential-stdin is required rather than offered.
printf '%s' "$BOT_TOKEN" | npx wb connection create --mode customer_byok --credential-stdin
wb connection list
Lists the connections in an environment.
wb connection providers
Lists the providers and the shared identities each offers. Rarely needed now that
connection create selects the only one on offer by itself.
wb connection route
Attaches a connection to a notifier, which is what makes it the destination a send reaches.
| Argument | Meaning |
|---|---|
--connection <id> | Required. The connection to route through. |
--notifier <id> | The notifier to attach it to. Defaults to the environment’s own default notifier, which is the only one a new project has. |
Subscribers
wb subscriber create <id>
Invites somebody, under the identifier your own system already uses for them — never a Telegram handle. It prints a link to open where they are; their tap on it is the consent, and until it happens there is nobody to send to.
| Argument | Meaning |
|---|---|
<id> | Positional, or --subscriber. Your own identifier for this person. |
--connection <id> | Which connection to bind them to. Defaults to the routed one. |
npx wb subscriber create me
Subscriber me invited (pending).
Open this where they are:
https://t.me/WhooshBangBot?start=…
Issuing a second invitation for an identifier that has already accepted returns the used link rather than a new one.
wb subscriber export <id>
Writes one complete JSON export for the subscriber across both project environments to standard output. The artifact separates data the subscriber provided from customer-provided and WhooshBang-derived data, so it can answer access and portability requests without a database query.
Redirect stdout to keep the exact machine-readable artifact. Errors remain on standard error and cannot corrupt the file.
npx wb subscriber export me > subscriber-data.json
| Argument | Meaning |
|---|---|
<id> | Positional, or --subscriber. Your own identifier for this person. |
--project | Override the remembered project. |
This project-wide operation needs a signed-in session or an organization credential
carrying organization:read, subscriptions:read, messages:read, and
machine-clients:read. A project credential is tied to one environment and is
therefore too narrow to produce a complete export.
wb subscriber erase <id>
Erase one subscriber’s personal data across both project environments while retaining non-identifying delivery and usage history:
npx wb subscriber erase customer-123 \
--project project_123 \
--confirm erase-subscriber
The confirmation must be exactly erase-subscriber. Repeating the command is
safe. Use a signed-in session or an organization credential carrying
subscriptions:write, messages:write, and machine-clients:write; a project
credential is tied to one environment and cannot perform the project-wide
erasure.
Messages
wb send <subscriber> <text>, wb message send
Two spellings of one command. wb message send is what a script should read
like and what every error message names; wb send takes the same arguments
positionally, because the command you type most should be typeable from memory.
| Argument | Meaning |
|---|---|
<subscriber> | Positional, or --subscriber. |
<text> | Positional, or --text. |
npx wb send me "Deploy finished."
accepted means WhooshBang has the message durably. It does not mean
Telegram has it — delivery is asynchronous.
wb ask <subscriber> <text>, wb message ask
Sends a message that carries a question. The text is both the message body and the prompt, so the question is written once.
The kind of question follows from what you asked for rather than from a type
flag: choices make it a single-select, --free-text makes it a typed reply, and
a bare question is a yes/no confirm.
| Argument | Meaning |
|---|---|
<subscriber> | Positional, or --subscriber. |
<text> | Positional, or --text. The question. |
--choice <a=Label,b=Label> | Repeatable, and comma-separated within one flag. Two to six options. A bare word with no = is its own label. |
--free-text | Ask them to type a reply instead of picking. |
--confirm-label <text> | The yes button’s words, for a confirm. |
--deny-label <text> | The no button’s words, for a confirm. |
--expires-in <seconds> | 30 through 86400. Defaults to one hour. |
--correlation <id> | Your own opaque correlation, returned with the answer. |
--wait [seconds] | Block until they answer, or until the wait runs out. |
npx wb ask me "Deploy build 41 to production?" --wait 120
npx wb ask me "Which environment?" --choice 'staging=Staging,prod=Production'
npx wb ask me "Name the release?" --free-text
wb message get <message-id>
Reads a message’s state and delivery attempts.
wb interaction get <interaction-id>
Reads a question’s state and, once given, its answer.
| Argument | Meaning |
|---|---|
--wait [seconds] | Block until it is answered, expired or cancelled. |
An answered question stays answered, but the answer itself leaves after its retention window. Reading late tells you they replied and not what they said, which is a retention rule rather than a lost answer.
Guided setup
wb init
The same path, asked one question at a time, in the shape of npm init: the
project name, whether to invite somebody and whom, and whether to finish by
sending something. It prints every identifier it made.
| Argument | Meaning |
|---|---|
--name <text> | The project name. |
--slug <slug> | Its short name. |
--subscriber <id> | Who to invite. Supplying it answers the invite question too. |
--invite / --no-invite | Answer the invitation question in advance. |
--send / --no-send | Answer the send question in advance. |
--text <text> | What to send. Supplying it answers the send question too. |
--ask | Make that a question rather than a plain message. |
--yes | Accept every default without asking. |
Every question is also an argument. Supply them all and nothing is asked, so the same command runs unchanged in a script. With no terminal attached the commands refuse by naming the argument you left out, rather than blocking on a prompt nothing will ever read.