{"_id":"@1msg/cli","_rev":"4-a1e84e78a58e4e904a3852bc22e90a0b","name":"@1msg/cli","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@1msg/cli","version":"0.1.0","license":"MIT","_id":"@1msg/cli@0.1.0","maintainers":[{"name":"tinman321","email":"tinman321@gmail.com"},{"name":"1msg.company","email":"1msg.company@gmail.com"},{"name":"alibek.seksenali","email":"alibek.seksenali@alumni.nu.edu.kz"}],"homepage":"https://github.com/1msg/1msg-cli#readme","bugs":{"url":"https://github.com/1msg/1msg-cli/issues"},"bin":{"1msg":"dist/index.js"},"dist":{"shasum":"78d02a19ce03ee3036f9e29da798fe462d8ef459","tarball":"https://registry.npmjs.org/@1msg/cli/-/cli-0.1.0.tgz","fileCount":76,"integrity":"sha512-9+fmzeeoxJyY+oPv1xODztkheWY7vFo7rVMFje8InA0gZ3eRyLXzm08YxF4SD1U5hjKNYjA+uv6f+TEhHhmpHg==","signatures":[{"sig":"MEYCIQCSw+IVI0AmphsYNBMdOb1I6fQPg5n48DuOgXotL46GEgIhALKy83dUpDA5Yg91iZmOZ2FCj2yuRnHpEVxyO8mRCmBu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":347366},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"c1aba5625f4e8eed15996d2abb8bceebc7d6ef57","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","start":"node dist/index.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"alibek.seksenali","email":"alibek.seksenali@alumni.nu.edu.kz"},"repository":{"url":"git+https://github.com/1msg/1msg-cli.git","type":"git"},"_npmVersion":"10.8.2","description":"Command-line client for the 1msg WhatsApp Business API","directories":{},"_nodeVersion":"20.20.2","dependencies":{"yaml":"^2.3.4","@1msg/sdk":"^1.0.4","commander":"^12.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.1.3","@types/jest":"^29.5.14","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cli_0.1.0_1788787014269_0.9094376693299489","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@1msg/cli","version":"0.1.1","license":"MIT","_id":"@1msg/cli@0.1.1","maintainers":[{"name":"tinman321","email":"tinman321@gmail.com"},{"name":"1msg.company","email":"1msg.company@gmail.com"},{"name":"alibek.seksenali","email":"alibek.seksenali@alumni.nu.edu.kz"}],"homepage":"https://github.com/1msg/1msg-cli#readme","bugs":{"url":"https://github.com/1msg/1msg-cli/issues"},"bin":{"cli":"dist/index.js","1msg":"dist/index.js"},"dist":{"shasum":"f271f8dcf02bd3e9c4b939d0b3f7c816fa80f7e1","tarball":"https://registry.npmjs.org/@1msg/cli/-/cli-0.1.1.tgz","fileCount":76,"integrity":"sha512-NYsxV5j5iymfQtvpVof9XRrtE6N3BWsZTmOKrLoBeLzSeQaIFAdKNb5WM8G343H2+lQdN8cPvctumG0lm6pMow==","signatures":[{"sig":"MEUCIQCZk5etKaZ8AOY6nqox1sdPvrHODxQQcysrCz4LwH5JuwIgNiPNu9xrRwflu2TrM55gC/S/AZwShVOja+I+ngIEOqM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":347396},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"5a29e8c8672391436eb794247f0bd84b3079f485","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","start":"node dist/index.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"alibek.seksenali","email":"alibek.seksenali@alumni.nu.edu.kz"},"repository":{"url":"git+https://github.com/1msg/1msg-cli.git","type":"git"},"_npmVersion":"10.8.2","description":"Command-line client for the 1msg WhatsApp Business API","directories":{},"_nodeVersion":"20.20.2","dependencies":{"yaml":"^2.3.4","@1msg/sdk":"^1.0.4","commander":"^12.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.1.3","@types/jest":"^29.5.14","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cli_0.1.1_1788787726261_0.08231000265317845","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@1msg/cli","version":"0.1.2","license":"MIT","_id":"@1msg/cli@0.1.2","maintainers":[{"name":"tinman321","email":"tinman321@gmail.com"},{"name":"1msg.company","email":"1msg.company@gmail.com"},{"name":"alibek.seksenali","email":"alibek.seksenali@alumni.nu.edu.kz"}],"homepage":"https://github.com/1msg/1msg-cli#readme","bugs":{"url":"https://github.com/1msg/1msg-cli/issues"},"bin":{"cli":"dist/index.js","1msg":"dist/index.js"},"dist":{"shasum":"c5b1cb93d6090d4ba9d79ea046e34f7806f2feba","tarball":"https://registry.npmjs.org/@1msg/cli/-/cli-0.1.2.tgz","fileCount":76,"integrity":"sha512-9NF1ZqSKiO2mTYhnwvT8L/STxfnw5ygY0HJ/HbqkfVHRBiAbmE1vMtTaiArbHv6nRbsYCegFwmwgJS8/TJyP8w==","signatures":[{"sig":"MEUCIQDOZqiDUBvJ25xh8ZRfeMIznEnXguWjhbP1HU8vSsNj2AIgUD3lsqffukeQNAhpekS2LF37YHTUWfOxS9LQOpfHixs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":349113},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"a8922733f76e8f5f586c592470d92d3429e79026","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","start":"node dist/index.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"alibek.seksenali","email":"alibek.seksenali@alumni.nu.edu.kz"},"repository":{"url":"git+https://github.com/1msg/1msg-cli.git","type":"git"},"_npmVersion":"10.8.2","description":"Command-line client for the 1msg WhatsApp Business API","directories":{},"_nodeVersion":"20.20.2","dependencies":{"yaml":"^2.3.4","@1msg/sdk":"^1.0.4","commander":"^12.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.1.3","@types/jest":"^29.5.14","@types/node":"^22.20.1"},"_npmOperationalInternal":{"tmp":"tmp/cli_0.1.2_1788791527128_0.4842955674835294","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"_id":"@1msg/cli@0.1.3","bin":{"cli":"dist/index.js","1msg":"dist/index.js"},"bugs":{"url":"https://github.com/1msg/1msg-cli/issues"},"dist":{"shasum":"ced094ca2aab92c91d5cb70c193b54fd5d73fd95","tarball":"https://registry.npmjs.org/@1msg/cli/-/cli-0.1.3.tgz","fileCount":76,"integrity":"sha512-xQlHJg5KS+JbzsYA696SqI7JVyQtzZFkBfquGZ145pqEuNRqm9hJZBQPvDWtNX/aDcqXCx7XbiTGJwwqPKro/Q==","signatures":[{"sig":"MEQCIDDejybLL3QXrHjY6oEXEtwQ1z3gCETBp9m87nnSUL1IAiBQLWklKr2eiVMf9BsrqGJ3gPpgPAsR/c7RgfDJZiEqHw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEMCIEUw63e8/fwjPJkHTeCXXRkOT1+jNihfpIXwAeLl06BLAh8BbHcEQ3EWugPkQiu+vBp4WSAJGVTJuXo8OxeEKlVc"}],"unpackedSize":371177},"main":"./dist/index.js","name":"@1msg/cli","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"c9d2a55fdfa293b4b2fe4fee9d37446949396adb","license":"MIT","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","start":"node dist/index.js","prepublishOnly":"npm run build"},"version":"0.1.3","_npmUser":{"name":"alibek.seksenali","email":"alibek.seksenali@alumni.nu.edu.kz"},"homepage":"https://github.com/1msg/1msg-cli#readme","repository":{"url":"git+https://github.com/1msg/1msg-cli.git","type":"git"},"_npmVersion":"10.8.2","description":"Command-line client for the 1msg WhatsApp Business API","directories":{},"maintainers":[{"name":"tinman321","email":"tinman321@gmail.com"},{"name":"1msg.company","email":"1msg.company@gmail.com"},{"name":"alibek.seksenali","email":"alibek.seksenali@alumni.nu.edu.kz"}],"_nodeVersion":"20.20.2","dependencies":{"yaml":"^2.3.4","@1msg/sdk":"^1.0.4","commander":"^12.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.1.3","@types/jest":"^29.5.14","@types/node":"^22.20.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cli_0.1.3_1789139130782_0.04095092950378332"}}},"time":{"created":"2026-09-07T13:16:54.075Z","modified":"2026-09-11T15:05:31.063Z","0.1.0":"2026-09-07T13:16:54.421Z","0.1.1":"2026-09-07T13:28:46.393Z","0.1.2":"2026-09-07T14:32:07.288Z","0.1.3":"2026-09-11T15:05:30.864Z"},"bugs":{"url":"https://github.com/1msg/1msg-cli/issues"},"license":"MIT","homepage":"https://github.com/1msg/1msg-cli#readme","repository":{"url":"git+https://github.com/1msg/1msg-cli.git","type":"git"},"description":"Command-line client for the 1msg WhatsApp Business API","maintainers":[{"name":"tinman321","email":"tinman321@gmail.com"},{"name":"1msg.company","email":"1msg.company@gmail.com"},{"name":"alibek.seksenali","email":"alibek.seksenali@alumni.nu.edu.kz"}],"readme":"# @1msg/cli\n\nCommand-line client for the [1MSG](https://1msg.io) WhatsApp Business API.\n\nThe product is the **full public API**, not an MVP: **61 of 62** public operations are commands. Legacy `deleteMediaLegacy` is not exposed (`1msg media delete` uses `DELETE /media/{id}`). Nothing prints `not implemented yet`.\n\nHTTP never goes through `fetch` / `axios`. Every API call uses [`@1msg/sdk`](https://www.npmjs.com/package/@1msg/sdk). Commands are hand-mapped (verb + noun), not generated 1:1 from OpenAPI.\n\n[![npm](https://img.shields.io/npm/v/@1msg/cli.svg)](https://www.npmjs.com/package/@1msg/cli)\n[![node](https://img.shields.io/node/v/@1msg/cli.svg)](https://nodejs.org)\n[![license](https://img.shields.io/npm/l/@1msg/cli.svg)](./LICENSE)\n\n| | |\n|--|--|\n| **npm** | [`@1msg/cli`](https://www.npmjs.com/package/@1msg/cli) |\n| **Binary** | `1msg` (`npx @1msg/cli` is the same program) |\n| **SDK** | [`@1msg/sdk`](https://www.npmjs.com/package/@1msg/sdk) |\n| **Requires** | Node.js ≥ 18 |\n| **Language** | English (`--help`, tables, errors) |\n| **Docs** | [https://docs.1msg.io/](https://docs.1msg.io/) |\n\nAPI hosts:\n\n| Environment | `ONE_MSG_BASE_URL` |\n|-------------|--------------------|\n| Live channels | `https://api.1msg.io` |\n| Test channels | `https://sandbox.1msg.io` |\n\nBare hostnames (`api.1msg.io`, `sandbox.1msg.io`) are accepted and normalized to `https://`. Stage / local (`api-stage.1msg.io`, `http://127.0.0.1:3050`) work for `init` / `channel add`.\n\n> Implementation source of truth still lives in the `1msg-api` monorepo (`packages/cli`). This repository is the **distribution** package for `npx` / clone / npm. Flag text is frozen from the design RFC (`1msg-api/docs/CLI.md`).\n\n- [Install](#install)\n- [Quick start](#quick-start)\n- [Configuration](#configuration)\n- [Global flags](#global-flags)\n- [Commands](#commands)\n- [Output](#output)\n- [Errors and exit codes](#errors-and-exit-codes)\n- [Shell completion](#shell-completion)\n- [API coverage](#api-coverage)\n- [Architecture](#architecture)\n- [Development](#development)\n- [Related](#related)\n\n---\n\n## Install\n\n```bash\nnpx -y @1msg/cli --help\nnpx -y @1msg/cli version\n```\n\nOr install globally:\n\n```bash\nnpm i -g @1msg/cli\n1msg --help\n```\n\n### Clone and run\n\n```bash\ngit clone https://github.com/1msg/1msg-cli.git\ncd 1msg-cli\nnpm install\nnpm run build\nnode dist/index.js --help\n```\n\n---\n\n## Quick start\n\n```bash\nnpx -y @1msg/cli init\nnpx -y @1msg/cli status\nnpx -y @1msg/cli send --to 12020721369 --text \"Hello\"\nnpx -y @1msg/cli template list\n```\n\nNon-interactive init (CI / scripts):\n\n```bash\nprintf '%s' \"$ONE_MSG_TOKEN\" | 1msg init --name prod \\\n  --base-url https://api.1msg.io --instance-id ODI371267300 --token-stdin\n```\n\nA channel is one WhatsApp instance (instance id + token). Commands use the default channel from the config file unless `--channel` is set.\n\nSession messages (`1msg send`, most `1msg message *`) need an open 24-hour window. Outside that window use `1msg template send`.\n\n---\n\n## Configuration\n\nConfig file mode `0600`:\n\n| OS | Path |\n|----|------|\n| Linux / macOS | `~/.config/1msg/config.yaml` (`$XDG_CONFIG_HOME/1msg/config.yaml`) |\n| Windows | `%AppData%\\1msg\\config.yaml` |\n\n```yaml\n# ~/.config/1msg/config.yaml\nversion: 1\ndefault_channel: acme-prod\nchannels:\n  acme-prod:\n    base_url: https://api.1msg.io\n    instance_id: ODI371267300\n    # token omitted → filled from ONE_MSG_TOKEN\n  acme-test:\n    base_url: https://sandbox.1msg.io\n    instance_id: ODI371267301\n    token: \"…\"   # optional; file mode 0600\n```\n\nThere is **no API** to list a customer's channels. `channel list` / `use` / `add` / `remove` / `current` are always local.\n\nTokens are never printed in tables, logs, or `--json`.\n\n### Environment\n\n| Variable | Description |\n|----------|-------------|\n| `ONE_MSG_CHANNEL` | Same as `--channel` (config **name**, not instance id) |\n| `ONE_MSG_BASE_URL` | `https://api.1msg.io` or `https://sandbox.1msg.io` |\n| `ONE_MSG_INSTANCE_ID` | Channel instance id |\n| `ONE_MSG_TOKEN` | Channel API token |\n\nDeprecated aliases match MCP: `CHAT_API_BASE_URL`, `CHAT_API_TOKEN`, `CHAT_API_INSTANCE_ID`, `CHAT_API_KEY`, `TOKEN`, `INSTANCE_ID`. Prefer `ONE_MSG_*`.\n\n`NO_COLOR` disables ANSI color (same as `--no-color`).\n\n### Precedence\n\nResolve **which channel** first, then **fill empty fields**, then **flags**.\n\n1. Channel name: `--channel` / `ONE_MSG_CHANNEL` / `default_channel` / the only channel in the file.\n2. Take `base_url`, `instance_id`, `token` from that block.\n3. If a field is empty, fill from `ONE_MSG_BASE_URL` / `ONE_MSG_INSTANCE_ID` / `ONE_MSG_TOKEN`.\n4. `--base-url` / `--instance-id` / `--token` always win.\n5. If there is no config file, the three env vars are the implicit channel (CI).\n6. Else exit `5`: `no channel configured — run 1msg init`.\n\nA named channel that already has a token is **not** overwritten by a leftover `ONE_MSG_TOKEN` in the shell. `-c` on `channel list` is ignored: `list` is always the full local file. `-c` / `--channel` take a config **name**, not an instance id.\n\n### CI without a config file\n\n```bash\nexport ONE_MSG_BASE_URL=https://api.1msg.io\nexport ONE_MSG_INSTANCE_ID=ODI371267300\nexport ONE_MSG_TOKEN=***\n1msg send --to 12020721369 --text \"from ci\" --json\n```\n\n### Typical multi-channel flow\n\n```bash\n1msg channel add --name prod --base-url https://api.1msg.io \\\n  --instance-id ODI371267300 --token-stdin --default\n1msg channel add --name test --base-url https://sandbox.1msg.io \\\n  --instance-id ODI371267301 --token-stdin\n1msg channel use test\n1msg channel use ODI371267300          # unique instance id → config name\n1msg -c test send --to 12020721369 --text \"sandbox ping\"\n1msg -c prod template list --json\n```\n\n`channel use` lookup: exact config key, else unique `instance_id`. Zero matches → exit 1. Two names sharing that instance id → pass a config name.\n\n---\n\n## Global flags\n\nAvailable on every command:\n\n| Flag | Description |\n|------|-------------|\n| `-c, --channel <name>` | Named channel from the config file |\n| `--instance-id <id>` | Override instance id |\n| `--base-url <url>` | Override API root |\n| `--token <token>` | Override token (prefer `ONE_MSG_TOKEN`) |\n| `--json` | Print the API response body as JSON |\n| `--no-color` | Disable ANSI color |\n| `-h, --help` | Help for this command |\n| `-v, --version` | Version (root only) |\n\n`--json` is the **raw API body**. There is no `--raw`. The one CLI-built object is `channel info --json`: `{ \"status\": <GET /status>, \"me\": <GET /me> }`.\n\n### Shared destination flags\n\nUsed by send-like commands unless a command says otherwise. Exactly one of `--to` or `--chat-id`. Exception: `message payment` is `--to` only (public schema has no `chatId`).\n\n| Flag | Description |\n|------|-------------|\n| `--to <phone>` | Phone with country code, no `+` |\n| `--chat-id <id>` | `phone@c.us` · `group@g.us` · `BSUID@lid` |\n| `--quote <wamid>` | Reply to this message (`wamid.*`) |\n\nComplex bodies (`template add`, interactive messages, calling SDP) take flags for scalars and `--from-file` for JSON (`-` = stdin).\n\n---\n\n## Commands\n\nEvery command answers `1msg <command> --help`. This section is the map and the examples; flags live in `--help`.\n\n### `init`\n\nInteractive setup: config file, live vs sandbox, instance, token (hidden), set as default. Writes mode `0600` and runs `1msg status` unless `--no-verify`.\n\n```bash\n1msg init\nprintf '%s' \"$ONE_MSG_TOKEN\" | 1msg init --name prod \\\n  --base-url https://api.1msg.io --instance-id ODI371267300 --token-stdin\n```\n\n### `channel`\n\nLocal named channels, plus remote status/settings of the selected channel.\n\n| Subcommand | Where | What |\n|------------|-------|------|\n| `list` | local | Channels in the file (`*` = default). Columns: `default`, `name`, `instance_id`, `base_url`. Never `token`. |\n| `use <name\\|id>` | local | Set default channel |\n| `add` | local | Add a channel (first channel becomes default unless `--default`) |\n| `remove <name>` | local | Remove by **config name** only |\n| `current` | local | Default name and instance id |\n| `info` | API | `GET /status` then `GET /me` |\n| `status` | API | `GET /status` (alias: `1msg status`) |\n| `settings` / `settings set` | API | `GET/POST /settings` (only flags you pass are sent) |\n| `mm-lite` | API | `GET /mmLiteStatus` |\n| `automation` / `automation set` | API | Conversational automation |\n\n```bash\n1msg channel list\n1msg channel use acme-prod\n1msg channel info\n1msg channel info --json\n1msg -c acme-prod channel info --json\n1msg channel settings set --ack-notifications --no-guaranteed-hooks\n```\n\nIf either call in `channel info` fails, the CLI does not print a partial object: it emits that call's error and skips the second call.\n\n### `status` / `me`\n\n```bash\n1msg status\n1msg status --json\n1msg me\n1msg me update --about \"Available 9–18\" --email support@example.com\n```\n\nHuman `status` is key-value: `status`, `accountStatus`, `mm_lite_available`.\n\n### `send` / `message send`\n\nText or file inside the session window. Exactly one destination (`--to` or `--chat-id`) and exactly one body (`--text`, `--file`, or `--media-id`).\n\n```bash\n1msg send --to 12020721369 --text \"Hello\"\n1msg send --chat-id 12020721369@c.us --text \"Hello\" --quote wamid.HBgN…\n1msg send --to 12020721369 --file ./photo.jpg --caption \"Look\"\n1msg send --to 12020721369 --file https://example.com/a.pdf --filename invoice.pdf\n1msg send --to 12020721369 --media-id 123456 --media-type image\n```\n\nA local `--file` is read from disk, encoded as a data URI, and sent as `sendFile.body`. An `https` URL is passed through and **requires `--filename`**. This does not call `uploadMedia` unless you run `1msg media upload` yourself.\n\nRoot `1msg send` is only `sendMessage` + `sendFile`. The other public send operations are under `1msg message` and `1msg template send`.\n\nHuman send output:\n\n```\nsent  true\nid    gBGGeRhGZTEfAgkJCh2wAz4ZH-8\nto    12020721369@c.us\n```\n\n### `message`\n\n| Command | API | Notes |\n|---------|-----|-------|\n| `send` | `POST /sendMessage` or `/sendFile` | Same as `1msg send` |\n| `list` | `GET /messages` | Inbox history. Columns: `time`, `chat_id`, `from`, `type`, `id`, `body` (body truncated to 60). If the API returns `notice` and no rows, print the notice and exit 0. |\n| `read` | `POST /readMessage` | `--message-id` only; no chat id. `--typing` = typing indicator (max 25s) |\n| `react` | `POST /sendReaction` | `--emoji` → API `body`; `--message-id` → `quotedMsgId`. Empty emoji removes the reaction |\n| `location` | `POST /sendLocation` | `--lat` / `--lng` |\n| `location-request` | `POST /sendLocationRequest` | Optional `--text` |\n| `contact` | `POST /sendContact` | Flags or `--from-file` |\n| `buttons` | `POST /sendButton` | `--button id:title` repeatable, max 3. Interactive header only via `--from-file` |\n| `menu` | `POST /sendList` | WhatsApp list. `--from-file` required (`sections[]`) |\n| `carousel` | `POST /sendCarousel` | `--from-file` with `cards[]` and/or `params[]`. Carousel **outside** 24h is `template send --params`, not this command |\n| `product` | `POST /sendProduct` | `--catalog-id` + `--product-id`, or `--from-file` for lists |\n| `cta` | `POST /sendCtaUrl` | `--text` / `--button` / `--url` |\n| `address` | `POST /sendAddressMessage` | India and Singapore only (`--country IN\\|SG`) |\n| `order` | `POST /sendOrderDetails` | India payments; `--from-file` for order body |\n| `payment` | `POST /sendPaymentRequest` | `--to` + `--region IN\\|SG\\|BR` only (no `--chat-id`) |\n| `sticker` | `POST /sendSticker` | Exactly one of `--link`, `--media-id`, `--file` |\n| `flow` | `POST /sendFlow` | Session window. Outside 24h send a template with a FLOW button |\n\n```bash\n1msg message list --chat-id 12020721369@c.us --limit 20 --last\n1msg message read --message-id wamid.… --typing\n1msg message react --to 12020721369 --message-id wamid.… --emoji \"👍\"\n1msg message location --to 12020721369 --lat 55.7558 --lng 37.6173 \\\n  --name \"Red Square\" --address \"Moscow\"\n1msg message buttons --to 12020721369 --text \"Choose:\" \\\n  --button yes:Yes --button no:No\n1msg message menu --to 12020721369 --from-file menu.json\n1msg message cta --to 12020721369 --text \"See details\" \\\n  --button \"Open site\" --url https://example.com\n```\n\n### `template`\n\nWork outside the 24-hour session window.\n\n```bash\n1msg template list\n1msg template list --sort name --json\n1msg template send --to 12020721369 --name hello_world --lang en \\\n  --params '[{\"type\":\"body\",\"parameters\":[{\"type\":\"text\",\"text\":\"Ivan\"}]}]'\n1msg template add --from-file hello_world.json\n1msg template remove --name hello_world\n```\n\n`template list` columns: `name`, `status`, `language`, `category`, `id`. Footer: `total N`. `--params` is a Cloud API **components array**, not a string list. `--from-file` on `add` is required and must include `components[]`.\n\nA successful `template list` writes a completion cache of template names (see [Shell completion](#shell-completion)).\n\n### `media`\n\n```bash\n1msg media upload --file ./photo.jpg\n1msg media upload --url https://example.com/a.pdf\n1msg media get --id 123456\n1msg media delete --id 123456\n```\n\nPublic `uploadMedia` accepts a URL or a data URI, not multipart. `media get` returns metadata plus a temporary URL (~5 min). `POST /deleteMedia` (`deleteMediaLegacy`) is not exposed.\n\n### `group`\n\n`group-id` is the WABA group id **without** `@g.us`.\n\n```bash\n1msg group list\n1msg group create --name \"Support team\" --description \"Customer support\"\n1msg group get 120363046942338209\n1msg group update 120363046942338209 --subject \"Support\"\n1msg group invite-link 120363046942338209\n1msg group invite-link reset 120363046942338209\n1msg group delete 120363046942338209\n```\n\nList columns: `id`, `subject`.\n\n### `flow`\n\nWhatsApp Flows and the business encryption key. Some endpoints currently return HTTP 501 until the Meta Graph Flows rewrite is available — the CLI still exposes them and prints the API error.\n\n```bash\n1msg flow list\n1msg flow create --name lead_form --category LEAD_GENERATION\n1msg flow get FLOW123\n1msg flow publish FLOW123\n1msg flow assets FLOW123 --json-file flow.json\n1msg flow encryption\n1msg flow encryption set --pem-file business.pem\n```\n\nList columns: `id`, `name`, `status`, `categories` (comma-joined).\n\n### `webhook`\n\n```bash\n1msg webhook get\n1msg webhook set --url https://example.com/webhook\n1msg webhook set --url https://a.example/hook --url https://b.example/hook\n1msg webhook clear\n```\n\n`set` **replaces** the stored list (max 5). It does not append. `clear` calls `POST /settings` with an empty `webhookUrl` (`setWebhook` rejects empty).\n\n### `user`\n\n```bash\n1msg user blocked\n1msg user block --to 12020721369\n1msg user unblock --to 12020721369\n```\n\nBlocked-list column: `phone` (first present of `phone`, `wa_id`, `id`).\n\n### `catalog`\n\n```bash\n1msg catalog get\n1msg catalog set --cart --visible\n1msg catalog set --no-cart --no-visible\n```\n\n`set` sends both `is_cart_enabled` and `is_catalog_visible` (required by the API). Fails when the WABA has no catalog linked — that is an account limit, not a CLI bug. Columns: `id`, `cart`, `visible` (`true`/`false`).\n\n### `call`\n\nWhatsApp Calling API (beta). 1MSG proxies **signaling only**. Real media needs your own WebRTC or SIP stack. Trial / `subscriptionBlocked` → HTTP 403.\n\n```bash\n1msg call settings\n1msg call settings set --from-file calling.json\n1msg call connect --to 12185552828 --sdp-file offer.sdp\n1msg call pre-accept --call-id wacid.ABGG… --sdp-file answer.sdp\n1msg call accept --call-id wacid.ABGG… --sdp-file answer.sdp\n1msg call reject --call-id wacid.ABGG…\n1msg call hangup --call-id wacid.ABGG…\n```\n\nAll call-control commands `POST /initiateCall`. The CLI always sets `messaging_product=whatsapp`. Do not echo Meta's offer SDP as the answer.\n\n### `version`\n\n```bash\n1msg version\n1msg -v\n```\n\nPrints the CLI version and the `@1msg/sdk` version used for HTTP.\n\n---\n\n## Output\n\nDefault (no `--json`): tables or key-value with **stable column names**. Extra API fields are omitted from the table and appear only with `--json`.\n\nEmpty list: print `No rows.` to stderr and exit 0.\n\n`--json`: exact API response body (pretty-printed). Successful JSON output strips token-like keys. API error `--json` is the raw server body.\n\n`channel info --json` is the only CLI-built envelope:\n\n```json\n{\n  \"status\": {\n    \"isCloud\": true,\n    \"status\": \"connected\",\n    \"accountStatus\": \"authenticated\",\n    \"mm_lite_available\": false\n  },\n  \"me\": {\n    \"about\": \"Available 9–18\",\n    \"phone\": \"12020721369\"\n  }\n}\n```\n\nA single endpoint remains `1msg status --json` / `1msg me --json`.\n\n---\n\n## Errors and exit codes\n\nPublic API errors are `{ \"error\": \"<string>\" }` plus HTTP status. There is no `code` field — the CLI does not invent names like `TOKEN_EXPIRED`. Human output shows the HTTP status.\n\nHuman output: message + `(HTTP <status>)` + optional hint. `--json` on an API error prints the **raw server body** (no CLI envelope). Usage errors (no HTTP) print `{ \"error\": \"<string>\" }` and exit 1.\n\n```\n$ 1msg send --to 12020721369 --text \"Hello\"\nError: invalid or expired token (HTTP 401)\nHint: set ONE_MSG_TOKEN or run `1msg init`\n\n$ 1msg send --text \"Hello\"\nError: missing destination: pass --to or --chat-id\nSee:  1msg send --help\n\n$ 1msg send --to 12020721369 --text \"Hello\" --file ./a.jpg\nError: pass exactly one of --text, --file, or --media-id\n\n$ 1msg -c missing status\nError: channel \"missing\" not in config\nSee:  1msg channel list\n```\n\n| Exit | Meaning |\n|------|---------|\n| `0` | OK |\n| `1` | Usage |\n| `2` | API 4xx |\n| `3` | API 5xx |\n| `4` | Network |\n| `5` | Not configured (`1msg init`) |\n\n---\n\n## Shell completion\n\nPrint a script to stdout. The CLI never writes into `/etc` or `$fpath` by itself — redirect, then reload the shell.\n\n```bash\n1msg completion bash\n1msg completion zsh\n1msg completion powershell\n```\n\nWhat is completed:\n\n| Kind | Source |\n|------|--------|\n| Commands, subcommands, flags | Always, from the command tree |\n| Channel names (`-c` / `--channel` / `channel use` / `remove`) | Keys of `channels:` in the config file (local, no API) |\n| Template names (`template send --name`, `template remove --name`) | Cache written after a successful `1msg template list` |\n| Flow ids / group ids | Not cached; type them |\n\nTemplate cache:\n\n| OS | Path |\n|----|------|\n| Linux / macOS | `~/.cache/1msg/completion.json` |\n| Windows | `%LOCALAPPDATA%\\1msg\\completion.json` |\n\nShape: `{ \"updated_at\": \"<iso>\", \"channel\": \"<config name>\", \"templates\": [\"hello_world\", …] }`. Cache is per default channel name; after `channel use`, run `template list` again or names may be stale. Completing `--name` with no cache: no values (commands/flags still complete).\n\n**Bash** (user, no sudo):\n\n```bash\nmkdir -p ~/.local/share/bash-completion/completions\n1msg completion bash > ~/.local/share/bash-completion/completions/1msg\n# then: source ~/.bashrc\n```\n\nLinux system: `1msg completion bash | sudo tee /etc/bash_completion.d/1msg`.  \nmacOS Homebrew: `1msg completion bash > \"$(brew --prefix)/etc/bash_completion.d/1msg\"`.\n\n**Zsh:**\n\n```bash\nmkdir -p ~/.zsh/completions\n1msg completion zsh > ~/.zsh/completions/_1msg\n```\n\nOnce in `~/.zshrc`:\n\n```zsh\nfpath=($HOME/.zsh/completions $fpath)\nautoload -U compinit && compinit\n```\n\nThen `exec zsh`. Do not write to `${fpath[1]}` — that path is not stable.\n\n**PowerShell:**\n\n```powershell\n$dir = Split-Path $PROFILE\nNew-Item -ItemType Directory -Force $dir | Out-Null\n1msg completion powershell | Out-File -Encoding utf8 (Join-Path $dir 1msg.ps1)\n```\n\nOnce in `$PROFILE`: `. (Join-Path (Split-Path $PROFILE) '1msg.ps1')`.\n\n---\n\n## API coverage\n\n61 mapped public `operationId`s + explicit skip `deleteMediaLegacy` = all 62 operations in the public OpenAPI spec.\n\n| operationId | CLI |\n|---|---|\n| `sendMessage` | `message send --text` / `send --text` |\n| `sendFile` | `message send --file` / `--media-id` |\n| `createUploadMedia` | `media upload` |\n| `listMessages` | `message list` |\n| `createReadMessage` | `message read` |\n| `sendTemplate` | `template send` |\n| `listTemplates` | `template list` |\n| `addTemplate` | `template add` |\n| `removeTemplate` | `template remove` |\n| `getStatus` | `status` / `channel status` |\n| `getMe` | `me` |\n| `updateMe` | `me update` |\n| `retrieveMedia` | `media get` |\n| `deleteMedia` | `media delete` |\n| `sendReaction` | `message react` |\n| `sendLocation` | `message location` |\n| `sendLocationRequest` | `message location-request` |\n| `sendContact` | `message contact` |\n| `sendButton` | `message buttons` |\n| `sendList` | `message menu` |\n| `sendCarousel` | `message carousel` |\n| `sendProduct` | `message product` |\n| `sendCtaUrl` | `message cta` |\n| `sendAddressMessage` | `message address` |\n| `sendOrderDetails` | `message order` |\n| `sendPaymentRequest` | `message payment` |\n| `sendSticker` | `message sticker` |\n| `sendFlow` | `message flow` |\n| `getWebhook` | `webhook get` |\n| `setWebhook` | `webhook set` |\n| `listSettings` | `channel settings` |\n| `createSettings` | `channel settings set` / `webhook clear` |\n| `getMmLiteStatus` | `channel mm-lite` |\n| `getCommerce` | `catalog get` |\n| `createCommerce` | `catalog set` |\n| `getConversationalAutomation` | `channel automation` |\n| `setConversationalAutomation` | `channel automation set` |\n| `blockUser` | `user block` |\n| `unblockUser` | `user unblock` |\n| `listBlockedUsers` | `user blocked` |\n| `createGroups` | `group create` |\n| `listGroups` | `group list` |\n| `getGroupsGroupId` | `group get` |\n| `createGroupsGroupId` | `group update` |\n| `deleteGroupsGroupId` | `group delete` |\n| `getGroupsGroupIdInvitelink` | `group invite-link` |\n| `createGroupsGroupIdInvitelink` | `group invite-link reset` |\n| `createFlows` | `flow create` |\n| `listFlows` | `flow list` |\n| `getFlowsFlowId` | `flow get` |\n| `deleteFlowsFlowId` | `flow delete` |\n| `patchFlowsFlowIdMetadata` | `flow metadata` |\n| `patchFlowsFlowIdAssets` | `flow assets` |\n| `getFlowsFlowIdPreview` | `flow preview` |\n| `createFlowsFlowIdPublish` | `flow publish` |\n| `createFlowsFlowIdDeprecate` | `flow deprecate` |\n| `getCallingSettings` | `call settings` |\n| `updateCallingSettings` | `call settings set` |\n| `initiateCall` | `call connect` / `pre-accept` / `accept` / `reject` / `hangup` |\n| `getWhatsappBusinessEncryption` | `flow encryption` |\n| `setWhatsappBusinessEncryption` | `flow encryption set` |\n| `deleteMediaLegacy` | not exposed |\n\nLocal-only (no `operationId`): `init`, `channel list|use|add|remove|current`, `completion`, `version`.\n\nAll 17 public `send*` operations are mapped. Root `1msg send` is text/file only.\n\n---\n\n## Architecture\n\n```text\nOpenAPI YAML (1msg-api monorepo)\n  └─► codegen\n        ├─► NestJS controllers\n        ├─► @1msg/sdk            ← HTTP + types (published npm)\n        └─► @1msg/cli            ← commander + config + help; SDK client only\n```\n\nSee [ARCHITECTURE.md](./ARCHITECTURE.md).\n\nCoverage is asserted in the `1msg-api` monorepo: 61 mapped public `operationId`s + explicit `deleteMediaLegacy` skip = 62. `--help` text is snapshot-tested against the RFC.\n\n---\n\n## Development\n\n| Script | Purpose |\n|--------|---------|\n| `npm run build` | Compile TypeScript → `dist/` |\n| `npm test` | Jest unit tests (`--help` snapshots, precedence, SDK-only architecture) |\n| `npm start` | Run `dist/index.js` |\n| `npm pack --dry-run` | What npm would publish (`dist/`, this README, `ARCHITECTURE.md`, `LICENSE`) |\n\nCI (`.github/workflows/ci.yml`): install, build, test, smoke `--help` / `version`, `npm pack --dry-run`.\n\nPublish: tag `v*` on this repo, or the `1msg-api` workflow **Publish @1msg/cli** (checks out this repository). Required secret: `NPM_TOKEN`.\n\nDo not add a generator that emits one command per `operationId`. Do not call the API except through `@1msg/sdk`.\n\n---\n\n## Related\n\n- [1MSG API docs](https://docs.1msg.io/)\n- [`@1msg/sdk`](https://www.npmjs.com/package/@1msg/sdk) — TypeScript client\n- [`@1msg/mcp`](https://www.npmjs.com/package/@1msg/mcp) / [`1msg/1msg-mcp`](https://github.com/1msg/1msg-mcp) — MCP server on the same SDK\n- Design RFC (flag contract): `1msg-api/docs/CLI.md`\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md"}