Skip to main content

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 is an independent implementation of the WhatsApp Web protocol — not a fork of Baileys. The concepts overlap (companion pairing, Signal sessions, an event stream), but the API is different and it is not a drop-in replacement. This page maps the patterns you already know.
Auth state, message shapes, and method names differ. Plan to rewrite your socket setup and handlers — but the mental model (pair → listen → send) carries over directly.

Creating the socket

Baileys gives you a socket from a factory; zapo gives you a WaClient plus an explicit store.
// Baileys (typical)
const { state, saveCreds } = await useMultiFileAuthState('auth')
const sock = makeWASocket({ auth: state })
sock.ev.on('creds.update', saveCreds)

// zapo
import { createStore, WaClient } from 'zapo-js'
import { createSqliteStore } from '@zapo-js/store-sqlite'

const store = createStore({
  backends: { sqlite: createSqliteStore({ path: '.auth/state.sqlite', driver: 'auto' }) },
  providers: { auth: 'sqlite', signal: 'sqlite', senderKey: 'sqlite', appState: 'sqlite' }
})
const client = new WaClient({ store, sessionId: 'default' }, logger)
await client.connect()
There is no creds.update to save by hand — the store persists credentials automatically. Pick any backend (SQLite, Postgres, MySQL, Redis, Mongo) on Installation.

Events

Baileys multiplexes everything through sock.ev; zapo exposes a typed event per concern on client.
Baileyszapo
sock.ev.on('connection.update', ({ connection, qr, lastDisconnect }) => …)client.on('connection', …) + client.on('auth_qr', …) + client.on('auth_paired', …)
sock.ev.on('creds.update', saveCreds)(automatic — the store persists creds)
sock.ev.on('messages.upsert', ({ messages }) => …)client.on('message', (event) => …)
sock.ev.on('messages.update', …) (edits/reactions/polls)client.on('message_addon', …) / client.on('message_protocol', …)
sock.ev.on('message-receipt.update', …)client.on('receipt', …)
sock.ev.on('groups.update' / 'group-participants.update', …)client.on('group', …)
sock.ev.on('presence.update', …)client.on('presence', …) / client.on('chatstate', …)
The full map is in Events. Each event is strongly typed via WaClientEventMap.

Sending messages

// Baileys
await sock.sendMessage(jid, { text: 'hello' })
await sock.sendMessage(jid, { image: { url: './pic.jpg' }, caption: 'hi' })

// zapo
await client.message.send(jid, 'hello') // string shorthand for text
await client.message.send(jid, { type: 'image', media: './pic.jpg', mimetype: 'image/jpeg', caption: 'hi' })
zapo uses a discriminated content union ({ type: 'image' | 'video' | 'audio' | 'document' | 'poll' | 'reaction' | … }) instead of Baileys’ shape-by-key object. Quoting/mentions move from the content object into the options argument ({ quote, mentions }).

API mapping

Baileyszapo
makeWASocket(...)new WaClient(options, logger)
useMultiFileAuthState(...)createStore({ backends, providers })
sock.sendMessage(jid, content)client.message.send(jid, content, options?)
downloadMediaMessage(...)client.message.download(event) / downloadToFile(event, path)
sock.groupMetadata(jid)client.group.queryGroupMetadata(jid)
sock.groupCreate(...) / groupParticipantsUpdate(...)client.group.createGroup(...) / addParticipants / removeParticipants / promoteParticipants / …
sock.updateProfilePicture(...) / updateProfileStatus(...)client.profile.setProfilePicture(...) / setStatus(...)
sock.updateBlockStatus(...)client.privacy.blockUser(jid) / unblockUser(jid)
sock.sendPresenceUpdate(...)client.presence.send(...) / sendChatstate(...)
sock.logout()client.logout()
jidNormalizedUser(...) / jidDecode(...)toUserJid(...) / splitJid(...) / parseJidFull(...) (JID helpers)
proto.Messageproto (exported from the package root)

Key differences to keep in mind

  • LID-first. zapo prefers the privacy-preserving LID identity over the phone-number JID. Reply to event.chatJid, and prefer LIDs when you have them.
  • Coordinator API. Features are grouped on getters (client.message, client.group, client.privacy, …) instead of flat socket methods — see Architecture.
  • Pluggable, typed stores. Persistence is a first-class layer with official backends, not a JSON folder. See Stores.
  • No auto-reconnect. Like Baileys, you drive reconnection — but read Errors & disconnects for the reason codes.
  • No number registration. zapo connects with already-paired/registered credentials; it does not register new numbers.
Last modified on May 28, 2026