Linking, devices and profiles
Link a WhatsApp device by QR code, manage profiles and understand the single-connection rule.
Read this page when you connect wa to your WhatsApp account for the first time, when you add a second account, or
when wa says a profile is not linked. At the end you know how to link, how to check who a profile is, how to
unlink, and where wa keeps what it needs to stay linked.
⚠️
wais an unofficial client of your real WhatsApp account. WhatsApp may ban an account that uses one, and bans accounts that send in bulk or write to strangers.wawrites only when a command asks, limits sends and holds every write when WhatsApp says to slow down. Do not send in bulk or to strangers (limits).
First, the words this page uses:
- Linked device:
waon this computer, as WhatsApp sees it. You link it from the phone, the way you link WhatsApp Web, and the phone lists it under Settings → Linked devices. Its keys live in one file on this computer. Whoever has that file can read and send as you, so treat it like your password. - History push: the copy of your recent chats the phone sends once, seconds after linking.
wakeeps what arrives; older messages of one chat can be asked of the phone later (older history). - Profile: a name for one linked device on this computer, with its own keys and settings. Every command that
uses an account names it, so you pick one name at setup (
wa personal setup) and use it from then on (profiles).
First run
wa personal setup guides a first run in five steps: this computer's folders, the link, the account, five chats
from the local store, and the agent skill (--agent codex, cursor, claude, gemini, all or none). Allow
about five minutes, most of it the history push. Run it in a terminal. A profile linked before is checked without
linking again, and nothing is asked. Before the QR code or the pairing code, setup and session start print the
warning above on stderr, once per link. wa personal session start is the command for the link alone.
Linking
wa personal session start # a QR code in the terminal
wa personal session start phone # your number, typed in the terminal, then a code to type on the phoneQR: scan the code in WhatsApp on the phone: Settings → Linked devices → Link a device. The code is renewed while you wait.
Phone: type your number in international format when wa asks. wa shows an eight-character pairing code;
on the phone, open Settings → Linked devices → Link a device → Link with phone number instead, and type it. The
number goes to the engine on its input, never as an argument, so other programs on this computer cannot see it in
the list of processes.
Right after either, the phone pushes your history. session start keeps the same connection open, saves what
arrives into the local store, and stops when the phone has been quiet for 45 seconds, or at Ctrl+C. Ctrl+C there,
or --timeout, ends only this wait: the device stays linked, what arrived is kept and counted, and the command ends
with exit code 0. wa personal setup waits the same way, then goes on to its remaining steps under the
command's usual time limit, started afresh. Then keep receiving with wa personal server install
(the local store).
When an agent runs the link
Your AI agent can start the link for you. Without a terminal, wa prints the QR code as plain text, and the agent
pastes it into the chat for you to scan:
wa personal setup --agent claude --json
wa personal session start qrThe agent runs the command in the background, since it waits for your scan. WhatsApp sends a new code after 60
seconds and then every 20 seconds; the agent pastes each new one and says the old one expired. With --json, each
code is also one line on stderr: {"event":"qr","qr":{"text":…,"expires_at":null,"scan":…}}. The text is about 73
columns wide. Linking is not offered over MCP: an app that only has MCP asks you to run the command. A pairing
code is for you to run in your own terminal: an agent never asks you for your phone number or a code in the chat.
Check and unlink
wa personal account show # who this profile is linked as; the phone number shows only its last four digits
wa account list # every profile on this computer, and the account each is linked as
wa personal session end # unlink the device on WhatsApp's side, and delete its keys hereChange your name, about and photo
wa personal account update --first-name Ana --last-name Silva # WhatsApp keeps one name: "Ana Silva"
wa personal account update --description "Back on Monday" # the "about" line
wa personal account update --photo ~/me.jpg # the profile photo, a square JPEGThe name goes to the phone and your other devices at once. Other people probably see it only once the phone next
comes online: a device tells WhatsApp its name when it says it is online, and wa never does. A
device linked a few minutes ago may not have WhatsApp's settings keys yet; keep serve running a while and try again.
For a profile photo, wa requires a square JPEG from 190 to 720 pixels per side, using the same validation as for a group photo. wa does not convert or crop images and rejects PNG or WebP content before changing anything. When name, about and photo are supplied together, they are changed in that order; a later error names the changes already made. Remove the photo from the phone.
wa personal session end removes the device on WhatsApp's side too: it disappears from the phone's list of linked
devices. It leaves the local store as it is. While serve runs for the profile, it refuses (exit code 12): stop
serve first with wa personal server stop, or Ctrl+C where it runs.
One connection per device
WhatsApp allows one connection for each linked device; a second one makes WhatsApp drop the first. So one wa
command at a time may connect a profile. serve, watch and every command that connects take the device's lock
first; another command for the same profile is refused and names the holder:
this WhatsApp login is in use by serve (pid 4242)serve is the exception. While it runs, a command for the same profile that would connect does not take the lock:
it runs inside serve, on serve's connection. It reaches serve through a socket next to serve's lock
(<state>/serve/<profile>.sock, mode 0600, so only your own user can open it). This covers sends, edits,
deletions, reactions, marking read, downloads, group and people commands, watch, doctor --online and the MCP
server wa <profile> mcp. The send guard and the profile's permissions still apply. A command run this way never
asks: a write at permission level ask needs --yes (--allow-dangerous for a deletion), or it is refused and
says so.
- Not through
serve: linking and unlinking (session start,session end,setup) andmcp --http.chats listandchats showread the local store, so they never connect.--offlineand--dry-runruns do not connect at all. serveis starting or does not answer: the command fails. It never opens a second connection.wawas upgraded andservenot restarted: the command runs inside the olderserve, with its code. When the two speak different relay versions, the command is refused and says to restartserve.wa upgraderestarts running servers itself; otherwise usewa <profile> server restart.- Windows: commands do not go through
serve. Whileserveruns, a command that connects is refused as above, with exit code 12.
With no serve running, each command connects on its own. While one of them holds the device, or wa personal mcp,
which keeps its connection for two minutes after a call, serve cannot start. Reads never connect, so they work
beside any of them.
How long a link lives
Until it is ended: by wa personal session end, from the phone's list of linked devices, or by WhatsApp itself. The
phone must come online now and then, or WhatsApp logs its linked devices out. When the device was removed, every
command that connects says so with exit code 4; link again with wa personal session start
(WhatsApp logged this device out).
Profiles
A profile is a separate linked device: its own keys, settings, recipients and runs. It is named by the first word, not by an option:
wa personal chats list # profile "personal"
wa work chats list # profile "work"
export WA_PROFILE=work # the same for the whole shell sessionThe first word is the profile when it is not a command. A profile therefore cannot be called chats,
messages or any other command word. Names are letters, digits, dot, dash and underscore, starting with a letter or
a digit.
The order, first match wins: the first word, then WA_PROFILE. With neither, a command that uses an account stops
with exit code 2 and lists the profiles on this computer. wa never picks one, not even the only one. Commands
that use no account run without a profile: --help, --version, commands, skill show, account list and
config show.
WA_PROFILE_LOCK pins a process to one profile. Set it where an agent runs, and a first word or WA_PROFILE
naming any other profile is refused (exit code 5). Without it, an agent could pick a profile with fewer limits.
What each profile is for: profiles.
Where the parts are kept
| What | Where |
|---|---|
| the device keys | ~/.local/share/whatsapp-cli/profiles/<profile>/private.db, readable by your user only |
| who holds the one connection | private.db.lock beside it |
| chats and messages | the WireCat store every WireCat CLI shares, ~/.local/share/WireCat/wirecat.db |
| settings | ~/.config/whatsapp-cli/config.json; never a secret |
WA_CONFIG_DIR, WA_STATE_DIR and WA_CACHE_DIR move the three folders (configuration
reference).