Skip to main content
The WSAPI CLI wraps every endpoint of the public WSAPI OpenAPI spec under a single wsapi binary. It’s designed for shell pipelines, scripts, and AI agents that want to send messages or manage WhatsApp instances without writing HTTP code.

What you get

  • Full REST coverage — every endpoint across messages, groups, communities, contacts, users, chats, calls, newsletters, status, media, and session management
  • JSON in, JSON out — every command emits JSON to stdout, ready to pipe into jq, xargs, or any other tool
  • Layered configuration — flags, environment variables, and named profiles in ~/.wsapi/config.json. Switch between staging and production with --profile
  • --data escape hatch — every body-bearing command accepts a --data <json> flag that merges arbitrary fields on top of typed flags
  • Local file uploads — pass --data-file ./path for any media command and the CLI will base64-encode it inline

Requirements

  • Node.js 18 or later
  • Active WSAPI subscription with a paired instance
  • WSAPI API key and instance ID

Installation

Configuration

wsapi resolves credentials in this order, first match wins:
  1. CLI flags: --api-key, --instance-id, --base-url
  2. Environment variables: WSAPI_API_KEY, WSAPI_INSTANCE_ID, WSAPI_BASE_URL
  3. The named profile from --profile <name> or WSAPI_PROFILE
  4. The defaultProfile in the config file

Named profiles

Use the built-in wsapi config commands to manage profiles:
The config file is stored at ~/.wsapi/config.json (or $XDG_CONFIG_HOME/wsapi/config.json) with mode 0600.

Environment variables

You can bypass the config file entirely:

Usage

Pair a device

Send messages

Group operations

Download inbound media

Without --output, binary endpoints write to stdout. Pipe it into a file or another command.

Command catalog

Run wsapi <group> --help and wsapi <group> <command> --help for the full list of options on each command.

Escape hatch: --data

Every body-bearing command supports a --data <json> flag whose JSON object is merged on top of the typed flags. Keys in --data win over flags, so it’s both an extension point (for fields the CLI doesn’t expose explicitly) and a full-body override.

Exit codes & error format

  • 0 — success
  • 1 — any error (config, API, network, validation)
API errors are emitted to stderr as JSON:
CLI/config errors are plain text on stderr:

Troubleshooting

Make sure at least one of the resolution sources is populated: --api-key/--instance-id flags, WSAPI_API_KEY/WSAPI_INSTANCE_ID environment variables, or a profile saved with wsapi config set-profile.
Run wsapi session status to confirm the device state, then pair again with wsapi session qr --output qr.png or wsapi session pair-code <phone>.
Save one profile per environment and select with --profile staging (or WSAPI_PROFILE=staging). Use wsapi config use <name> to change the default profile permanently.
Use --data '{"newField":true}' on any body-bearing command, or --data @./body.json to load the entire body from a file.

GitHub

github.com/wsapi-chat/wsapi-cli