Besides the standard companion mode (linking via QR / pairing code, like WhatsApp Web),Documentation Index
Fetch the complete documentation index at: https://zapo.to/llms.txt
Use this file to discover all available pages before exploring further.
zapo can connect as a primary mobile client — speaking the Android app’s protocol over a raw TCP socket.
Mobile support is stable and functional. The one thing
zapo does not provide is a registration API — requesting an SMS/voice code, submitting an OTP, or approving a takeover. Registering a number is complex and requires a physical phone, so it’s intentionally out of scope. You connect with an already-registered credential set, and that path is solid.How it differs from companion mode
| Companion (default) | Mobile | |
|---|---|---|
| Transport | WebSocket (wss://…) | TCP socket (tcp://g.whatsapp.net:443) |
| Auth | QR / pairing code | Pre-registered credentials + device fingerprint |
| Identity | Linked device | Primary account |
| Platform | Browser (chrome, …) | android |
| Device info | Not required | Required (hardware fingerprint) |
Enabling mobile mode
Mobile mode is triggered by themobileTransport option (a WaMobileTransportOptions). Its presence — or persisted deviceInfo in the loaded credentials — switches the client from the WebSocket transport to the TCP transport.
WaMobileTransportOptions
| Field | Type | Notes |
|---|---|---|
deviceInfo | WaMobileTransportDeviceInfo | Required hardware fingerprint (see below). |
tcpUrl | string | Defaults to tcp://g.whatsapp.net:443. |
passive | boolean | false sends keep-alives; true is idle. |
pushName | string | Display name. |
yearClass / memClass | number | Device performance/memory class. |
WaMobileTransportDeviceInfo
manufacturer, device, osVersion, osBuildNumber, appVersion are required; mcc, mnc, localeLanguageIso6391, localeCountryIso31661Alpha2, phoneId, deviceBoard, deviceModelType are optional. A stable fingerprint across runs matters — persist it and reuse the same values.
Credentials
Mobile mode needs an already-registered credential set: aWaAuthCredentials with meJid populated, platform: 'android', and deviceInfo attached. You seed these into the auth store before connecting (e.g. imported from a device bundle).
Once credentials with
deviceInfo are persisted, later reconnects automatically use the mobile TCP transport — you don’t need to pass mobileTransport again.Registration events
While your mobile session is connected, you’re notified when someone tries to register your number on another device — a security-relevant signal, surfaced as these events:| Event | Payload | Meaning |
|---|---|---|
mobile_registration_code | { code, expiryTimestampMs, fromDeviceId } | Someone requested a registration code to register your number on another phone; the issued code is surfaced here. |
mobile_account_takeover_notice | { serverToken, attemptTimestampMs, newDeviceName?, newDevicePlatform?, newDeviceAppVersion? } | Another device is claiming (taking over) your number. |
These events are informational —
zapo surfaces them but intentionally does not expose methods to submit a code or respond to a takeover. Provisioning a number is done on a real phone; bring the resulting credentials to zapo and connect.Standard features still apply
Once connected in mobile mode, the rest of the API is unchanged —client.message, client.group, events, stores, etc. all work the same way. The only difference is the transport and the auth/identity model.