# Administración de grupos y canales (/es/docs/wa/commands-admin)

Miembros, invitaciones, ajustes, moderación y estadísticas de grupos. Los cambios requieren permisos.

## Opciones globales [#opciones-globales]

| Opción | Qué hace |
| --- | --- |
| `-V, --version` | output the version number. |
| `-v, --verbose` | more detail in what is shown: -v ids, -vv everything we know. Default: `0`. |
| `--json` | machine-readable output: one JSON value on stdout; --json=id,text keeps only those fields. |
| `--jsonl` | machine-readable output: one JSON object per line, for streaming and jq. |
| `--quiet` | diagnostics off; a failure is still said. |
| `--trace` | the connection's own log lines on stderr — never message content. |
| `--debug` | on a failure, its whole record — cause and stack — in place of the short line. |
| `--timeout <duration>` | give up on the whole command after this — 30s, 2m, 500ms. |
| `--offline` | answer from what was recorded and never connect; fails if nothing was. |
| `--no-input` | never prompt or open interactive login; piped input remains available. |
| `--max-input-bytes <bytes>` | maximum buffered input bytes (default: 16777216). |
| `--max-output-bytes <bytes>` | maximum machine output bytes (default: 4194304; 0 disables). |
| `--brief` | found messages as reference, title, time, sender and excerpt only. |
| `--full` | found messages with their whole text and every provider field. |
| `--dry-run` | preview parsed arguments and permissions before running the action. |
| `--yes` | go ahead without the question an ask level puts before a write. |
| `--record` | keep this run — ids and timings, never message content. |
| `--no-record` | do not keep it, whatever the configuration says. |

## Comandos [#comandos]

### `wa chats members` [#wa-chats-members]

who is in a group

#### `wa chats members list` [#wa-chats-members-list]

everyone in a group, a page at a time, with their role and when they were last seen

```sh
wa chats members list <chat> [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `query` | optional | field:value terms; this list filters by none yet. |

| Opción | Qué hace |
| --- | --- |
| `--limit <n>` | how many to show. |
| `--page <n>` | which page, starting at 1. |
| `--all` | every row, no paging. |

#### `wa chats members check` [#wa-chats-members-check]

members that look like bots, each with its reasons — read from the member list and the local store; never one request per person, and it removes nobody

```sh
wa chats members check <chat> [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `query` | optional | field:value terms that narrow the list — the fields are below. |

| Opción | Qué hace |
| --- | --- |
| `--max-pages <pages>` | at most this many pages of 200 members, a pause between them (default: 10). |
| `--deep <n>` | also check the top n in full — profile, photos and everything they wrote — one person a second; the public ban lists cover Telegram only, so nothing is sent. |

#### `wa chats members history` [#wa-chats-members-history]

who joined, who left and whose profile changed, oldest first — what chats members fetch recorded in the local store; never asks the messenger

```sh
wa chats members history <chat> [query]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `query` | optional | field:value terms that narrow the list — the fields are below. |

#### `wa chats members fetch` [#wa-chats-members-fetch]

read a group's whole member list into the local store's member history: who joined, who left, daily counts and profile changes; someone is recorded as gone only when every member was read

**Changes something on this computer only.**

```sh
wa chats members fetch <chat> [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

| Opción | Qué hace |
| --- | --- |
| `--track` | also fetch it daily while serve runs; chats tracking lists and edits those chats. |
| `--max-pages <pages>` | at most this many pages of 200 members, a pause between them (default: 10). |

#### `wa chats members add` [#wa-chats-members-add]

add people; they are told

**Changes something in WhatsApp.**

```sh
wa chats members add <chat> <person>
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `person` | required | an id, or part of a name. |

#### `wa chats members remove` [#wa-chats-members-remove]

remove people; their messages stay

**Changes something in WhatsApp.**

```sh
wa chats members remove <chat> <person>
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `person` | required | an id, or part of a name. |

### `wa chats create` [#wa-chats-create]

create a group or a channel; the people added are told

**Changes something in WhatsApp.**

```sh
wa chats create <title> [person] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `title` | required | the group's name. |
| `person` | optional | people to add: an id, or part of a name. |

| Opción | Qué hace |
| --- | --- |
| `--channel` | a private channel instead of a group; people join it by its link. |

### `wa chats update` [#wa-chats-update]

rename a group or channel, change its description, or turn one of its settings on or off

**Changes something in WhatsApp.**

```sh
wa chats update <chat> [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

| Opción | Qué hace |
| --- | --- |
| `--title <title>` | the new name. |
| `--description <text>` | the new description. |
| `--photo <file>` | a new photo for it — a .jpg or .jpeg file. |
| `--remove-photo` | take its photo away; not with --photo. |
| `--only-admins-add <on\|off>` | only admins may add members. |
| `--join-approval <on\|off>` | people ask to join, and an admin lets them in. |
| `--only-admins-send <on\|off>` | only admins may send messages. |
| `--only-admins-edit-info <on\|off>` | only admins may change the name, photo and description. |
| `--disappear-after <duration\|off>` | new messages disappear this long after sending: 24h, 7d, 90d; off keeps them. |

### `wa chats links` [#wa-chats-links]

a group's invite link

#### `wa chats links show` [#wa-chats-links-show]

the invite link, if you may see it

```sh
wa chats links show <chat>
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

#### `wa chats links reset` [#wa-chats-links-reset]

replace the invite link; the old one stops working

**Changes something in WhatsApp.**

```sh
wa chats links reset <chat>
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

### `wa chats requests` [#wa-chats-requests]

requests to join a group that needs an admin's approval

#### `wa chats requests list` [#wa-chats-requests-list]

who asked to join, newest first; only admins see them, and reading tells nobody

```sh
wa chats requests list <chat> [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `query` | optional | field:value terms that narrow the list — the fields are below. |

| Opción | Qué hace |
| --- | --- |
| `--limit <n>` | how many to show. |
| `--page <n>` | which page, starting at 1. |

#### `wa chats requests confirm` [#wa-chats-requests-confirm]

let them in; the group sees them join

**Changes something in WhatsApp.**

```sh
wa chats requests confirm <chat> <person>
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `person` | required | who asked: an id from `chats requests list`. |

#### `wa chats requests reject` [#wa-chats-requests-reject]

turn the request away

**Changes something in WhatsApp.**

```sh
wa chats requests reject <chat> <person>
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `person` | required | who asked: an id from `chats requests list`. |

### `wa chats admins` [#wa-chats-admins]

give or take back a member's admin rights

#### `wa chats admins add` [#wa-chats-admins-add]

make a member an admin, with every right: members, admins, info, pin, link, post, delete

**Changes something in WhatsApp.**

```sh
wa chats admins add <chat> <person>
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `person` | required | an id, or part of a name. |

#### `wa chats admins remove` [#wa-chats-admins-remove]

take an admin's rights back; they stay a member

**Changes something in WhatsApp.**

```sh
wa chats admins remove <chat> <person>
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `person` | required | an id, or part of a name. |

### `wa chats moderate` [#wa-chats-moderate]

judge a group's new messages and members by its rules, and act as they allow

**Changes something in WhatsApp.**

```sh
wa chats moderate <chat> [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

| Opción | Qué hace |
| --- | --- |
| `--since-time <time>` | judge what came after this ISO 8601 time, or 2h / 1d ago; the saved point stays. |
| `--dry-run` | judge and plan; do nothing. |
| `--allow-dangerous` | yes to every action whose level in the group's rules is ask. |
| `--max-actions <n>` | at most this many actions in one run; 10 if not given. |

### `wa chats pin` [#wa-chats-pin]

keep a chat at the top of your chat list; nobody in it is told

**Changes something in WhatsApp.**

```sh
wa chats pin <chat>
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

### `wa chats unpin` [#wa-chats-unpin]

let a pinned chat move down the chat list again

**Changes something in WhatsApp.**

```sh
wa chats unpin <chat>
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

### `wa chats delete` [#wa-chats-delete]

delete a chat from this account; the others in it keep it and its messages

**Changes something in WhatsApp.**

```sh
wa chats delete <chat> [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

| Opción | Qué hace |
| --- | --- |
| `--allow-dangerous` | go ahead without the question an ask level puts before a deletion. |

## `wa stats` [#wa-stats]

statistics about messages, chats and their authors

### `wa stats messages` [#wa-stats-messages]

message statistics from the local store

#### `wa stats messages show` [#wa-stats-messages-show]

how many stored messages match, by chat, sender, day or hour — the local store only

```sh
wa stats messages show [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `query` | optional | a strict Lucene query, as for search messages; none counts every stored message; with --saved, more words AND-ed to it. |

| Opción | Qué hace |
| --- | --- |
| `--by <group>` | count by chat, sender, day or hour (default: chat). |
| `--chat <chat>` | only this chat — the same as chat: in the query; a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `--source <accounts>` | every account of this messenger held in the store; personal, bots or all — the same as in: in the query. |
| `--limit <n>` | how many rows. |
| `--timezone <zone>` | the IANA timezone for calendar days and hours. |
| `--exact` | bare words and quotes match their exact form only, as exact:word does; text: still matches every form. |
| `--saved <name\|id>` | count what a saved search or an earlier run matches; options typed here replace its own. |

#### `wa stats messages counters` [#wa-stats-messages-counters]

per-counter observations and bounded remote refresh

#### `wa stats messages counters show` [#wa-stats-messages-counters-show]

show saved counter values and their observation freshness

```sh
wa stats messages counters show [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `query` | optional | strict Lucene query over stored messages. |

| Opción | Qué hace |
| --- | --- |
| `--chat <chat>` | only this chat; a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `--source <accounts>` | held accounts of this messenger; refresh uses the active account. |
| `--exact` | bare words match exact forms. |
| `--timezone <zone>` | IANA timezone for query dates. |
| `--selection <json>` | pinned counter-targets selection from counters show; conflicts with query and scope. |
| `--counters <names>` | distinct views,reactions,comments fields; all three by default. |
| `--limit <n>` | messages, 1–100; 20 by default. |
| `--max-age <duration>` | maximum fresh observation age; 24h by default. |

#### `wa stats messages counters sync` [#wa-stats-messages-counters-sync]

read authoritative counters for bounded messages and update their local observations

**Changes something on this computer only.**

```sh
wa stats messages counters sync [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `query` | optional | strict Lucene query over stored messages. |

| Opción | Qué hace |
| --- | --- |
| `--chat <chat>` | only this chat; a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `--source <accounts>` | held accounts of this messenger; refresh uses the active account. |
| `--exact` | bare words match exact forms. |
| `--timezone <zone>` | IANA timezone for query dates. |
| `--selection <json>` | pinned counter-targets selection from counters show; conflicts with query and scope. |
| `--counters <names>` | distinct views,reactions,comments fields; all three by default. |
| `--limit <n>` | messages, 1–100; 20 by default. |
| `--max-messages <n>` | maximum messages to refresh, 1–100. |
| `--sync-time <duration>` | remote refresh budget; 30s by default, maximum 5m. |
| `--dry-run` | preview exact stored targets and counter capabilities without connecting. |

#### `wa stats messages unanswered` [#wa-stats-messages-unanswered]

oldest detected questions without an observed qualifying explicit reply

```sh
wa stats messages unanswered [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `query` | optional | a strict Lucene query; none selects every stored message. |

| Opción | Qué hace |
| --- | --- |
| `--source <accounts>` | every held account of this messenger; personal, bots or all. |
| `--saved <name\|id>` | run a saved report of this kind; typed report options replace stored options. |
| `--timezone <zone>` | the IANA timezone for calendar date boundaries. |
| `--limit <n>` | report rows, 1–100; 20 if not given. |
| `--answerer <person>` | stored name, alias, @username, ID or person:provider/account/id; ambiguous names require a choice; repeat for more. |

#### `wa stats messages discussion` [#wa-stats-messages-discussion]

viewed posts with little recorded discussion

```sh
wa stats messages discussion [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `query` | optional | a strict Lucene query; none selects every stored message. |

| Opción | Qué hace |
| --- | --- |
| `--source <accounts>` | every held account of this messenger; personal, bots or all. |
| `--saved <name\|id>` | run a saved report of this kind; typed report options replace stored options. |
| `--timezone <zone>` | the IANA timezone for calendar date boundaries. |
| `--limit <n>` | report rows, 1–100; 20 if not given. |

#### `wa stats messages top` [#wa-stats-messages-top]

rank stored messages by a measure or explainable score; counters are snapshots with per-field observation freshness

```sh
wa stats messages top [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `query` | optional | a strict Lucene query; none selects every stored message. |

| Opción | Qué hace |
| --- | --- |
| `--measure <name>` | the ranking metric; not with score or weights. One of: `views`, `reactions`, `forwards`, `comments`, `replies`, `thread-size`. |
| `--score <preset>` | helpful/active for authors; engaging for either target. One of: `helpful`, `active`, `engaging`. |
| `--weights <json>` | the complete component weights; replaces preset weights. |
| `--source <accounts>` | every held account of this messenger; personal, bots or all. |
| `--timezone <zone>` | the IANA timezone for dates and active days. |
| `--limit <n>` | ranked rows, 1–100. |
| `--saved <name\|id>` | run a saved query or ranking run; typed options replace stored options. |

#### `wa stats messages evidence` [#wa-stats-messages-evidence]

bounded messages, answer pairs or retention members from an exact drilldown selection

```sh
wa stats messages evidence <message> [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `message` | required | the canonical message locator, or retention cohort reference, from drilldown. |

| Opción | Qué hace |
| --- | --- |
| `--selection <json>` | the resolved ranking selection returned in drilldown. |
| `--component <name>` | the exposed ranking component. |
| `--limit <n>` | evidence rows, 1–100; 20 if not given. |
| `--cursor <cursor>` | continue the same component and stored-evidence fingerprint. |

### `wa stats contacts` [#wa-stats-contacts]

statistics about human authors

#### `wa stats contacts responses` [#wa-stats-contacts-responses]

counts and median/p90 latency for selected human answering identities

```sh
wa stats contacts responses [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `query` | optional | a strict Lucene query; none selects every stored message. |

| Opción | Qué hace |
| --- | --- |
| `--source <accounts>` | every held account of this messenger; personal, bots or all. |
| `--saved <name\|id>` | run a saved report of this kind; typed report options replace stored options. |
| `--timezone <zone>` | the IANA timezone for calendar date boundaries. |
| `--limit <n>` | report rows, 1–100; 20 if not given. |
| `--answerer <person>` | stored name, alias, @username, ID or person:provider/account/id; ambiguous names require a choice; repeat for more. |

#### `wa stats contacts top` [#wa-stats-contacts-top]

rank the human authors of stored messages by a measure or explainable score; counters are snapshots with per-field observation freshness

```sh
wa stats contacts top [query] [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `query` | optional | a strict Lucene query; none selects every stored message. |

| Opción | Qué hace |
| --- | --- |
| `--measure <name>` | the ranking metric; not with score or weights. One of: `messages`, `words`, `reactions`, `replies`, `answers`, `answer-time`, `threads`, `active-days`. |
| `--score <preset>` | helpful/active for authors; engaging for either target. One of: `helpful`, `active`, `engaging`. |
| `--weights <json>` | the complete component weights; replaces preset weights. |
| `--source <accounts>` | every held account of this messenger; personal, bots or all. |
| `--timezone <zone>` | the IANA timezone for dates and active days. |
| `--limit <n>` | ranked rows, 1–100. |
| `--saved <name\|id>` | run a saved query or ranking run; typed options replace stored options. |

#### `wa stats contacts evidence` [#wa-stats-contacts-evidence]

bounded messages, answer pairs or retention members from an exact drilldown selection

```sh
wa stats contacts evidence <person> [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `person` | required | the exact native person id from the ranking row. |

| Opción | Qué hace |
| --- | --- |
| `--selection <json>` | the resolved ranking selection returned in drilldown. |
| `--component <name>` | the exposed ranking component. |
| `--limit <n>` | evidence rows, 1–100; 20 if not given. |
| `--cursor <cursor>` | continue the same component and stored-evidence fingerprint. |

### `wa stats chats` [#wa-stats-chats]

statistics about one chat

#### `wa stats chats show` [#wa-stats-chats-show]

a group's or channel's numbers for a period: messages, active members, replies, reactions, questions answered, joins and leaves — counted from the local store; joins and leaves too

```sh
wa stats chats show <chat> [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

| Opción | Qué hace |
| --- | --- |
| `--since-time <time>` | ISO 8601, or 2h / 1d ago; 7 days ago if not given. |
| `--by <group>` | also one row per calendar day or week (weeks start on Monday). |
| `--timezone <zone>` | the IANA timezone for calendar days. |

#### `wa stats chats newcomers` [#wa-stats-chats-newcomers]

known-join members and their help within a join window

```sh
wa stats chats newcomers <chat> [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

| Opción | Qué hace |
| --- | --- |
| `--since-time <time>` | from this ISO 8601 time, or 2h / 1d ago; 30d ago if not given. |
| `--until-time <time>` | through this ISO 8601 time, or 2h / 1d ago. |
| `--within <duration>` | the help window after a known newcomer join. |
| `--saved <name\|id>` | run a saved report of this kind; typed report options replace stored options. |
| `--timezone <zone>` | the IANA timezone for calendar date boundaries. |
| `--limit <n>` | report rows, 1–100; 20 if not given. |
| `--answerer <person>` | stored name, alias, @username, ID or person:provider/account/id; ambiguous names require a choice; repeat for more. |

#### `wa stats chats retention` [#wa-stats-chats-retention]

joining cohorts and observed checkpoint membership from saved roster observations

```sh
wa stats chats retention <chat> [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

| Opción | Qué hace |
| --- | --- |
| `--since-time <time>` | joining period starts at ISO 8601 or a relative time; last 90 days by default. |
| `--until-time <time>` | joining period ends at this time; now by default. |
| `--checkpoints <durations>` | up to 10 increasing joining ages, comma separated; 1d,7d,30d by default. |
| `--within <duration>` | activity and early departure window after joining; 7d by default. |
| `--by <group>` | group joining dates by calendar day or Monday week. One of: `day`, `week`. |
| `--timezone <zone>` | IANA timezone for joining cohorts. |
| `--limit <n>` | cohorts and member evidence, 1–100. |

### `wa stats tasks` [#wa-stats-tasks]

task statistics

#### `wa stats tasks show` [#wa-stats-tasks-show]

per chat: how many tasks are open, the oldest open one, the median time to close

```sh
wa stats tasks show [options]
```

| Opción | Qué hace |
| --- | --- |
| `--chat <chat>` | only this chat; a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |
| `--type <type>` | only this type: question, request, mention or promise. |

### `wa stats charts` [#wa-stats-charts]

a chart's data from a chat's statistics, and optionally a dark SVG or PNG image

**Changes something on this computer only.**

```sh
wa stats charts <chat> [options]
```

| Argumento | Obligatoriedad | Qué es |
| --- | --- | --- |
| `chat` | required | a chat: its name, or its WhatsApp id (…@lid, …@g.us, …@newsletter). |

| Opción | Qué hace |
| --- | --- |
| `--chart-kind <messages\|active\|membership>` | what to draw: messages, active authors, or joins and leaves. Default: `messages`. |
| `--by <group>` | one point per calendar day or week (weeks start on Monday). Default: `day`. |
| `--since-time <time>` | ISO 8601, or 2h / 1d ago; 7 days ago if not given. |
| `--timezone <zone>` | the IANA timezone for calendar days. |
| `--output <file>` | write a dark image to a new .svg or .png file. |

## Códigos de salida [#códigos-de-salida]

Branch on the code, not on the text: the text can change, the code does not.

| Code | When |
| --- | --- |
| `0` | it worked |
| `2` | `validation_error` |
| `3` | `configuration_error` |
| `4` | `authentication_error` |
| `5` | `permission_error` |
| `6` | `not_found` |
| `7` | `confirmation_required` |
| `8` | `rate_limited` |
| `9` | `timeout` |
| `10` | `network_error` |
| `11` | `provider_error` |
| `12` | `provider_unavailable` |
| `13` | `invalid_response` |
| `14` | `outcome_unknown` |
| `130` | `cancelled` |
| `1` | anything else |

`0` and only `0` means the operation was done. `14` (`outcome_unknown`) means a message **may**
have gone: repeat it only with the same `--operation-id`, which WhatsApp uses to drop a second copy.
