Event Reference
API reference for all events emitted by the Open-WA Client.

Event Reference
Open-WA uses a centralized event system based on HyperEmitter. You can listen to these events to react to WhatsApp messages, connection state changes, and internal runtime lifecycle steps.
Listener examples
Import the shared emitter when you need process-level lifecycle events:
import { ev } from '@open-wa/wa-automate';Listen for common runtime and WhatsApp activity events by name:
ev.on('client.ready', ({ sessionId }) => {
console.log(`Session ${sessionId} is ready`);
});
ev.on('message.received', async ({ message, ctx }) => {
console.log('Message received', ctx.correlationId, message);
});
ev.on('session.connection.disconnected', ({ details }) => {
console.warn('Session disconnected', details?.reason);
});
ev.on('error', ({ scope, error, fatal }) => {
console.error(`Open-WA error in ${scope}`, { fatal, error });
});Use client-level helpers, such as client.onMessage, for normal bot behavior after the client is ready. Use ev when you need startup, auth, disconnect, webhook, persistence, or internal runtime events.
Wildcard example
The shared emitter supports wildcard listeners. This is useful for debugging or for carefully redacted audit sinks. Some compatibility and session-level emitters also pass session data through wildcard segments:
ev.on('**.**', (payload, sessionId, namespace) => {
auditEvent({
namespace,
sessionId,
receivedAt: Date.now(),
});
});Keep wildcard listeners narrow in production. QR codes, link codes, session artifacts, and persistence events can contain sensitive data.
OpenWAEventMap
This interface defines all available events and their corresponding payload shapes.
Prop
Type
Full event names
The table below lists every event name in OpenWAEventMap with its namespace. Event names without a dot are process-level compatibility or utility events.
| Namespace | Events |
|---|---|
launch.create | launch.create.start, launch.create.retry, launch.create.ready |
launch.config.setup | launch.config.setup.before, launch.config.setup.after |
launch.logging.setup | launch.logging.setup.before, launch.logging.setup.after |
launch.update.check | launch.update.check.before, launch.update.check.after |
launch.browser.init | launch.browser.init.before, launch.browser.init.after |
launch.page.init | launch.page.init.before, launch.page.init.after |
launch.page.interception | launch.page.interception.before, launch.page.interception.after |
launch.navigation.gotoWaWeb | launch.navigation.gotoWaWeb.before, launch.navigation.gotoWaWeb.after |
launch.modules.wait | launch.modules.wait.before, launch.modules.wait.after |
launch.injection.earlyCheck | launch.injection.earlyCheck.before, launch.injection.earlyCheck.after |
launch.auth | launch.auth.check.before, launch.auth.check.after, launch.auth.nuke.detected, launch.auth.timeout, launch.auth.phoneOutOfReach, launch.auth.qr.requested, launch.auth.qr.generated, launch.auth.qr.scanned, launch.auth.qr.expired, launch.auth.linkCode.requested, launch.auth.linkCode.generated, launch.auth.pairing, launch.auth.syncing |
launch.license.preload | launch.license.preload.before, launch.license.preload.after |
launch.wapi.inject | launch.wapi.inject.before, launch.wapi.inject.after |
launch.helper.pre_api | launch.helper.pre_api.before, launch.helper.pre_api.after |
launch.session | launch.session.validityCheck.before, launch.session.validityCheck.after, launch.session.invalid.retry |
launch.license.check | launch.license.check.before, launch.license.check.after |
launch.patch.init | launch.patch.init.before, launch.patch.init.after |
launch.patch.integrity | launch.patch.integrity.before, launch.patch.integrity.after |
launch.client.finalize | launch.client.finalize.before, launch.client.finalize.after |
session.state | session.state.changed |
session.connection | session.connection.disconnected, session.connection.reconnecting, session.connection.reconnected |
session.frame | session.frame.navigated |
session.reinject | session.reinject.detected, session.reinject.before, session.reinject.after, session.reinject.qr.waiting |
session.stale | session.stale.detected |
session | session.logout |
message | message.received, message.any, message.deleted |
ack | ack.changed |
group | group.addedToGroup, group.removedFromGroup, group.participants.changed.global, group.approval.request, group.changed |
chat | chat.deleted, chat.opened, chat.state |
device | device.battery, device.plugged |
call | call.incoming, call.state |
auth | auth.logout |
ui | ui.button, ui.poll.vote |
broadcast | broadcast.received |
label | label.changed |
story | story.received |
commerce | commerce.order, commerce.product.new |
reaction | reaction.added |
media.preprocess | media.preprocess.before, media.preprocess.after |
webhook | webhook.registered, webhook.unregistered, webhook.trigger.before, webhook.trigger.after, webhook.queue.enqueued, webhook.queue.dequeued, webhook.deliver.before, webhook.deliver.after |
persistence.session.save | persistence.session.save.before, persistence.session.save.after |
persistence.compress.zstd | persistence.compress.zstd.before, persistence.compress.zstd.after |
persistence.archive.zip | persistence.archive.zip.before, persistence.archive.zip.after |
persistence.upload.s3 | persistence.upload.s3.before, persistence.upload.s3.after |
patch.apply | patch.apply.before, patch.apply.after |
patch.init | patch.init.before, patch.init.after |
license.check | license.check.before, license.check.after |
license.inject | license.inject.before, license.inject.after |
cli | cli.launched |
server.start | server.start.before, server.start.after |
server.port | server.port.live |
core | core.starting, core.started, core.stopping, core.stopped |
client | client.ready |
| Process-level | internal_launch_progress, critical_internal_message, error |
Payload samples
The generated table above is the source of truth for payload shapes. These samples show the structure you will usually see in logs or listeners.
client.ready
{
"sessionId": "sales"
}message.received
{
"ctx": {
"correlationId": "evt_01HX9Q8K7V3P",
"ts": 1715683200000
},
"message": {
"id": "true_447700900123@c.us_3EB0F",
"from": "447700900123@c.us",
"body": "Hi"
}
}launch.auth.qr.generated
{
"correlationId": "launch_01HX9Q8K7V3P",
"attempt": 1,
"ts": 1715683200000,
"step": "launch.auth.qr.generated",
"details": {
"qr": "2@abc...",
"ascii": "████ QR ████",
"attemptInThisCycle": 1
}
}session.connection.disconnected
{
"correlationId": "session_01HX9Q8K7V3P",
"ts": 1715683300000,
"step": "session.connection.disconnected",
"details": {
"reason": "browser_closed",
"wasLoggedIn": true
}
}webhook.trigger.after
{
"ctx": {
"correlationId": "webhook_01HX9Q8K7V3P",
"ts": 1715683400000
},
"webhookId": "primary-crm",
"event": "message.received",
"enqueued": true
}Lifecycle ordering
A normal first login usually follows this order:
core.startinglaunch.create.startlaunch.config.setup.beforelaunch.config.setup.afterlaunch.browser.init.beforelaunch.browser.init.afterlaunch.page.init.beforelaunch.page.init.afterlaunch.navigation.gotoWaWeb.beforelaunch.navigation.gotoWaWeb.afterlaunch.auth.check.beforelaunch.auth.qr.generated, when a new login needs a QRlaunch.auth.qr.scanned, after the QR is scannedlaunch.auth.check.after, when auth state is knownlaunch.wapi.inject.beforelaunch.wapi.inject.afterlaunch.session.validityCheck.beforelaunch.session.validityCheck.afterlaunch.client.finalize.beforelaunch.client.finalize.aftersession.state.changed, usually toREADYclient.readycore.started
Warm starts can skip QR events. Failed starts may emit retry, timeout, invalid session, or error events before the lifecycle reaches client.ready.
Mapping to session-events guide
This reference lists the typed event names and payloads from the core event map. For a task-oriented guide to QR capture, session data handling, lifecycle timing, and wildcard patterns, read Session events.
Common Payloads
StepEvent
Most internal launch and lifecycle events use the StepEvent wrapper.
Prop
Type
EventContext
Standard metadata included with almost every event.
Prop
Type

Was this helpful?
Wally and his cute companion coffee mug are coding day and night to keep this up-to-date!
