npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@codexverified/baileys

v2.18.18

Published

CODEX TECHNOLOGY a premium Baileys developed and built by Dev Codex, with Meta compositing, bot planning replay, welcome flow, rich messages, interactive messages, albums, and more.

Readme

BAILEYS

The intelligent interactive and productivity layer for WhatsApp protocols.

Version Developer CODEX Node.js Powered by codexverified/baileys License

Main WhatsApp Channel Backup WhatsApp Channel Support Group Telegram Channel Telegram Group Website

A readable, carefully maintained Baileys distribution for building reliable WhatsApp integrations. built by codex

@codexverified/baileys is a Node.js and TypeScript library for creating WhatsApp automations over the Baileys protocol. It provides a socket-oriented API for authentication, messaging, media, interactive content, rich responses, newsletters, groups, communities, business features, account utilities, and carefully documented extensions.

The package is maintained by Codex under the CodexVerified organization. It is intended for developers who want a practical Baileys foundation with familiar interfaces, public TypeScript declarations, readable source code, explicit behavior, and room for carefully tested improvements.

Table of contents

At a glance

| Property | Value | | --- | --- | | Package | @codexverified/baileys | | Version | 2.18.18 | | Runtime | Node.js 20 or newer | | Module format | ESM, with CommonJS compatibility where supported | | Type declarations | Included at lib/index.d.ts | | License | MIT, as declared by the package metadata | | Maintainer | Codex | | Entry point | lib/index.js | | Repository | https://github.com/codexverified/baileys |

Installation

| Method | Command | Notes | | --- | --- | --- | | From npm | npm install @codexverified/baileys | Standard install when published under your organization | | From local archive | npm install ./codex-baileys-2.18.18.tgz | Place the .tgz beside your application | | Source audit (no scripts) | npm install --ignore-scripts | Skips install hooks for local review |

Both npm and archive installs use the same import name:

import { makeWASocket } from '@codexverified/baileys'

Quick start

The following example creates a socket, stores multi-file authentication credentials, reconnects after an unexpected disconnect, and replies to incoming messages. Keep the session directory private and never commit it to a public repository.

import {
  DisconnectReason,
  makeWASocket,
  useMultiFileAuthState
} from '@codexverified/baileys'
import P from 'pino'

async function start() {
  const { state, saveCreds } = await useMultiFileAuthState('./session')

  const sock = makeWASocket({
    auth: state,
    logger: P({ level: 'silent' })
  })

  sock.ev.on('creds.update', saveCreds)

  sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
    if (connection === 'open') {
      console.log('Connected with @codexverified/baileys')
    }

    if (connection === 'close') {
      const statusCode = lastDisconnect?.error?.output?.statusCode
      if (statusCode !== DisconnectReason.loggedOut) {
        start().catch(console.error)
      }
    }
  })

  sock.ev.on('messages.upsert', async ({ messages }) => {
    for (const message of messages) {
      if (!message.message || message.key.fromMe) continue

      await sock.sendMessage(message.key.remoteJid, {
        text: 'Hello from @codexverified/baileys'
      })
    }
  })
}

start().catch(console.error)

CommonJS usage

const {
  makeWASocket,
  useMultiFileAuthState
} = require('@codexverified/baileys')

If your runtime or bundler does not support this interop path, use the ESM import form instead.

Core capabilities

| Area | What it covers | | --- | --- | | Connections & authentication | WebSocket connection events, reconnect handling, browser identity configuration, pairing-code flows, connection state transitions | | Auth persistence | Multi-file credentials, single-file state, SQLite-backed persistence (optional driver), cache-manager integrations | | Messages & conversations | Text, mentions, replies, reactions, edits, deletions, forwards, polls, contacts, locations, events, group invitations, quoted messages, disappearing messages, view-once envelopes | | Media & albums | Images, video, audio, documents, stickers, thumbnails, albums; sourced from URLs, local files, or buffers; optional sharp / @napi-rs/image / jimp image processing; GIF-style video playback | | Interactive content | Buttons, lists, native flows, hydrated templates, carousel layouts, button grids | | Rich content & previews | Code blocks, tables, inline entities, LaTeX-oriented content, link previews, structured response arrays | | Rich menus (experimental) | Header image, row/carousel cards, stable button IDs, toast metadata, disclaimers, footer action | | Groups & communities | Group creation, participant management, settings, metadata, invites, labels, community/subgroup relationships | | Newsletters & channels | Channel metadata, follow/unfollow, posts, reactions, media, polls | | Account, business & privacy | Profile/business helpers, product & catalog operations, privacy controls, username utilities, status publishing, favorites management | | Storage & protocol utilities | In-memory and ordered-dictionary stores, cache-manager support, LID/phone-number resolution, event utilities, message normalization, media retry handling, TypeScript declarations |

Everyday message usage

| Message type | Key options | Example | | --- | --- | --- | | Text | text | sock.sendMessage(jid, { text: '...' }) | | Media with caption | image / video / audio / document, caption | sock.sendMessage(jid, { image: { url } , caption: '...' }) | | GIF-style video | video, gifPlayback: true | sock.sendMessage(jid, { video: { url }, gifPlayback: true }) | | View-once media | viewOnce: true (also viewOnceV2, viewOnceV2Extension, spoiler) | sock.sendMessage(jid, { image: { url }, viewOnce: true }) | | Spoiler / view-once (new) | mediaSpoilerMode: 'viewOnce' \| 'native' | see below |

await sock.sendMessage(jid, {
  text: 'A message from Codex'
})

await sock.sendMessage(jid, {
  image: { url: './media/photo.jpg' },
  caption: 'A photo message'
})

await sock.sendMessage(jid, {
  video: { url: './media/animation.mp4' },
  gifPlayback: true,
  caption: 'Animated media'
})

await sock.sendMessage(jid, {
  image: { url: './media/private-image.jpg' },
  caption: 'Open once',
  viewOnce: true
})

await sock.sendMessage(jid, {
  video: { url: './media/clip.mp4' },
  caption: 'View-once video',
  mediaSpoilerMode: 'viewOnce'
})

await sock.sendMessage(jid, {
  image: { url: './media/hidden-preview.jpg' },
  mediaSpoilerMode: 'native'
})

mediaSpoilerMode is an additional, opt-in path for supported image, video, document, or sticker media:

| Value | Effect | | --- | --- | | viewOnce | Wraps supported media in a view-once envelope | | native | Applies the native spoiler context flag |

The existing viewOnce, viewOnceV2, viewOnceV2Extension, and spoiler options remain supported and take precedence over mediaSpoilerMode when explicitly set.

Rich menu example

await sock.richMenu(jid, {
  header: {
    title: 'Codex Menu',
    image: {
      url: 'https://example.com/menu.jpg',
      mime_type: 'image/jpeg'
    }
  },
  body: {
    row: true,
    carousel: false,
    cards: [
      {
        title: 'Account',
        buttons: [
          { id: 'profile', text: 'Profile' },
          { id: 'settings', text: 'Settings' }
        ]
      },
      {
        title: 'Support',
        buttons: ['help', 'contact']
      }
    ]
  },
  footer: {
    text: 'Codex Technology',
    url: 'https://example.com'
  }
})

| Rich menu field | Purpose | | --- | --- | | header | Optional title and image shown above the menu | | body.row / body.carousel | Layout mode for the cards | | body.cards | Rows of stable button IDs and labels | | footer | Text plus an optional action URL |

Status, grids, tables, and flows

| Helper | Purpose | | --- | --- | | sendStatus | Post a status update, optionally with mentions via statusJidList | | sendRichButtonGrid | Send a card grid of stable-ID buttons | | sendInteractiveTable | Send tabular content with headers, rows, and action buttons | | sendWhatsAppFlow | Launch a published WhatsApp Flow |

await sock.sendStatus({ text: 'New Codex status' }, {
  statusJidList: ['[email protected]']
})

await sock.sendRichButtonGrid(jid, {
  text: 'Choose an option',
  cards: [{
    title: 'Actions',
    buttons: [
      { id: 'first_action', text: 'First action' },
      { id: 'second_action', text: 'Second action' }
    ]
  }]
})

await sock.sendInteractiveTable(jid, {
  title: 'Plans',
  headers: ['Name', 'Price'],
  rows: [['Basic', '$5'], ['Pro', '$10']],
  buttons: [{ id: 'choose_pro', text: 'Choose Pro' }],
  footer: 'Select a plan'
})

await sock.sendWhatsAppFlow(jid, {
  text: 'Open the form',
  flowId: 'your-flow-id',
  flowToken: 'your-flow-token',
  flowName: 'your-flow-name',
  flowAction: 'navigate',
  flowActionPayload: { screen: 'WELCOME' }
})

These helpers are protocol- and client-dependent. Use graceful fallbacks when an application serves a wide range of WhatsApp client versions.

Authentication and deployment guidance

| Practice | Detail | | --- | --- | | Session privacy | Keep the session directory private and excluded from version control | | Access control | Use a dedicated service account or restricted filesystem permissions where possible | | Secrets handling | Do not place access tokens, private keys, phone numbers, or personal account data in the README, package archive, or a public repository | | Dependency pinning | Pin dependencies with a lockfile for production deployments | | Runtime | Use a supported Node.js runtime | | Connection handling | Monitor connection events; handle logout separately from recoverable disconnects; avoid uncontrolled parallel sockets on reconnect |

Development workflow

npm test

Before submitting changes, validate ESM syntax, CommonJS compatibility where applicable, generated protocol files, and the declarations in lib/index.d.ts. Keep package metadata, exports, runtime requirements, and documentation synchronized. When a protocol behavior is experimental, document the fallback behavior and the client versions used during testing.

Recent compatibility updates

| Update | Detail | | --- | --- | | Album association fix | Album child messages use association type 1, the compatible child-association wire value, rather than treating the MEDIA_ALBUM message category as the association value | | View-once preserved | Explicit view-once implementations remain unchanged | | mediaSpoilerMode | New opt-in path for a view-once envelope or native spoiler flag, without altering existing defaults |

About Codex

This package is built and maintained by Codex, also known as Dev Codex. Codex is a developer from Nigeria who focuses on practical, accessible, and reliable software projects across the JavaScript and TypeScript ecosystem.

| | | | --- | --- | | Tech stack | JavaScript, HTML, TypeScript, Node.js, GitHub, Baileys, APIs, key-value stores | | Project types | Application development, websites, WhatsApp bots, Telegram bots, API endpoints, games | | Telegram | @codexverified | | Email | [email protected] |

The developer's work is driven by a commitment to learning, experimentation, clear documentation, and useful software that developers can understand and extend. This package reflects that commitment through its readable source, public declarations, practical examples, and emphasis on responsible automation.

Package layout

| Path | Contents | | --- | --- | | lib/ | JavaScript implementation, supporting utilities, public TypeScript declarations | | WAProto/ | Generated WhatsApp protocol definitions | | engine-requirements.js | Installation-time runtime checks | | package.json | Package metadata, scripts, dependencies, exports | | README.md | User-facing installation and usage guide |

Security and responsible use

This library interacts with WhatsApp accounts and user communications.

| Guideline | Detail | | --- | --- | | Authorization | Use only with accounts and data you are authorized to control | | Compliance | Respect WhatsApp's terms, applicable law, and message participants' privacy expectations | | Messaging conduct | Avoid unsolicited messaging | | Credential safety | Protect authentication state and never commit session files, tokens, private keys, or personal data to a public repository | | Media access | Limit access to stored media | | Transparency | Provide clear notice when an application performs automated actions | | Dependency review | Review installation scripts and optional dependencies before deploying to production; use pinned versions for repeatable builds |

Disclaimer

@codexverified/baileys is an independent, source-available Node.js library that communicates with WhatsApp using the Baileys protocol. It is not affiliated with, endorsed by, or officially connected to WhatsApp LLC or Meta Platforms, Inc. "WhatsApp" is a trademark of its respective owner, referenced here only for interoperability description.

No malware, no phishing, no hidden network calls. As a matter of project policy and design:

| Statement | Detail | | --- | --- | | No malicious payloads | The package does not contain, download, execute, or otherwise support malware, spyware, ransomware, keyloggers, or similar malicious code. | | No phishing or credential harvesting | The library does not construct, send, or facilitate phishing messages, fake login prompts, or credential-harvesting flows. It provides generic messaging primitives; how an application built on top of them is used is the responsibility of that application's developer. | | No covert data exfiltration | The package does not silently transmit your messages, contacts, media, or authentication state to Codex, CodexVerified, or any third party. The only network calls it makes are the ones necessary to connect to WhatsApp's own servers, plus explicitly caller-invoked helpers (such as checkStatusWA) that are never triggered automatically. | | No obfuscated code | The source is distributed as readable JavaScript/TypeScript with public type declarations, so it can be inspected line by line. Installs can be run with --ignore-scripts for an audit-first review, as noted in the Installation table. | | Not a guarantee, an invitation to verify | This statement describes the project's design intent and current source code. It is not a substitute for your own review, a third-party security audit, or a legal warranty. You are encouraged to read the source, pin dependency versions, and review any application built on top of this package before deploying it. |

Developer responsibility and acceptable use

This package gives developers general-purpose building blocks for WhatsApp automation (messaging, groups, newsletters/channels, rich responses, and similar features). Like any general-purpose toolkit, those same building blocks can be pointed at abusive uses by a developer who chooses to. The table below names the patterns this project explicitly does not endorse, alongside why they're harmful:

| Prohibited / discouraged use | Why it's a problem | | --- | --- | | Auto-following WhatsApp channels/newsletters on behalf of users without their explicit, informed consent | Misrepresents the user's intent, inflates follower counts artificially, and can violate WhatsApp's platform policies | | Sending unsolicited "channel pill" style promotional messages, forwarded rich-response spam, or bulk broadcast content to people who did not opt in | Standard spam/harassment; damages recipients' experience and violates most anti-spam and consumer-protection laws | | Using the bundled diagnostic helpers (e.g. checkStatusWA) for bulk number enumeration or unsolicited scanning of phone numbers | Enables targeting and abuse of people who never opted into any check; the helper's own documentation already flags this | | Impersonating WhatsApp, Meta, or another party; phishing; credential harvesting | Deceives end users and is illegal in most jurisdictions | | Evading WhatsApp's account-integrity enforcement, terms of service, or rate limits | Undermines platform trust and the safety of the messaging ecosystem for everyone |

Where responsibility sits. CodexVerified builds and documents the library itself, not the applications developers build with it. If a developer chooses to use this package to do any of the above, that developer — not CodexVerified or the @codexverified/baileys project — is solely responsible for that conduct, including any legal, financial, or platform consequences that follow from it. The maintainers do not operate, monitor, or have visibility into third-party deployments of this code, and inclusion of a feature in this library is not an endorsement of every way it could be used.

This project's own position is the opposite of the misuse above: CodexVerified is built around respecting user privacy and giving developers transparent, inspectable tools — not around helping anyone spam, deceive, or manipulate WhatsApp users. Developers who build on this package are expected to hold themselves to that same standard.

No warranty. This software is provided "as is," without warranty of any kind, express or implied, including but not limited to warranties of merchantability, fitness for a particular purpose, and non-infringement, to the fullest extent permitted by the license declared in package.json. Use of this package to interact with WhatsApp may be subject to WhatsApp's own terms of service, which are outside the maintainers' control.

Privacy policy

This section describes what the package itself does and does not do with data. It does not describe how any particular application built on top of this package handles data — that is determined by the developer of that application.

Data the package handles locally, on your own infrastructure:

| Data type | How it's handled | | --- | --- | | Authentication/session state | Generated and stored wherever your application configures it (e.g. useMultiFileAuthState('./session')). The package does not upload this elsewhere. Keep it private, as noted in Security and responsible use. | | Messages and media | Sent to and received from WhatsApp's own servers as part of normal protocol operation. The package does not copy, log, or relay this content to Codex, CodexVerified, or any other third party. | | Phone numbers passed to optional helpers | checkStatusWA sends a phone number to whatever endpoint you configure for that call. This only happens if your code explicitly calls it; the destination and its own privacy practices are your responsibility to review before use. |

What the package does not do:

  • It does not phone home, run analytics/telemetry, or transmit usage data to Codex, CodexVerified, or any other party.
  • It does not embed hidden credentials, tracking identifiers, or remote "kill switches."
  • It does not access data outside of what your application explicitly wires it up to.

Your responsibilities as a developer. If you build an application on top of this package that collects personal data (e.g. contacts, message content, phone numbers), you are the data controller for that application and are responsible for complying with applicable privacy laws (such as GDPR, CCPA, or Nigeria's NDPA) and with WhatsApp's own terms and business policies. This package is a communication toolkit, not a compliance framework.

Contact. Questions about this policy or the project can be sent to [email protected] or via @codexverified on Telegram.

License and maintenance

This distribution is provided under the license declared in package.json and the accompanying license file. Review those terms before redistributing or combining this package with third-party code.

@codexverified/baileys is built and maintained by Codex under the CodexVerified organization. Contributions, bug reports, and carefully documented improvements are welcome through the project repository.

Compatibility additions

The current source includes several independently implemented compatibility helpers identified during comparison with the published upstream package. These additions preserve the Codex package identity and do not copy package-specific attribution enforcement or remote licensing checks.

Copy-to-clipboard rich response

sendCopyButton creates a forwarded GenAI-style rich response with a copy-to-clipboard addon action.

| Option | Purpose | | --- | --- | | text | The content that gets copied | | label | Optional visible button text | | alignment | END, START, or CENTER |

await sock.sendCopyButton(jid, {
  text: 'npm install @codexverified/baileys',
  label: 'Copy install command',
  alignment: 'END'
})

As with other private or experimental WhatsApp rich-response layouts, clients may fall back to plain rendering or ignore the addon action.

Slot-machine HTML generator

generateSlotMachineHtml produces a self-contained five-reel Fruit Bonanza game with adjustable starting credits. It is a standalone HTML payload and performs no network requests.

| Option | Purpose | | --- | --- | | title | Display title for the generated page | | startingCredits | Initial credit balance |

import { generateSlotMachineHtml } from '@codexverified/baileys'

const html = generateSlotMachineHtml({
  title: 'Codex Fruit Bonanza',
  startingCredits: 500
})

The generator does not by itself send HTML through WhatsApp. Applications should only use an HTML-capable message primitive when that primitive is available and authorized for their deployment.

Optional ban-status checker

checkStatusWA is an explicit, caller-invoked diagnostic helper. It is never called during installation, socket creation, reconnection, or message sending. The endpoint is configurable, credentials are not embedded, and callers should review the endpoint's terms and privacy implications before sending a phone number.

import { checkStatusWA } from '@codexverified/baileys'

const result = await checkStatusWA('+447700900123', {
  diagnostic: true
})
console.log(result.status) // active, banned, blocked, not_registered, rate_limited, or unknown

| Status value | Meaning | | --- | --- | | active | Number appears active on WhatsApp | | banned | Number appears banned | | blocked | Number appears blocked | | not_registered | Number is not registered on WhatsApp | | rate_limited | Check was rate limited | | unknown | Status could not be determined |

This helper is not an anti-ban guarantee, does not bypass enforcement, and should not be used for bulk enumeration or unsolicited checking.

Comparison references

The feature comparison was based on the published package metadata and documentation available from npm and the independent package analysis page at Socket. The Codex implementation adds compatible behavior through readable, package-owned code rather than copying upstream-specific integrity, attribution, or remote-verification mechanisms.

Additional functional compatibility helpers

The source also exposes portable helpers for native-flow responses, view-once inspection, rich content preparation, HTML payload construction, and website previews. These are functional compatibility APIs only; package-specific identity checks, attribution enforcement, remote license gates, trusted-channel auto-follow behavior, and other ownership structures are not included.

| Helper | Purpose | | --- | --- | | parseNativeFlowResponse | Normalize quick-reply, single-select, and Flow response envelopes | | parseWhatsAppFlowResponse | Return only responses identified as WhatsApp Flow responses | | buildWhatsAppFlowButton / makeWhatsAppFlowButton | Build published Flow button parameters for a caller-owned Flow ID and token | | prepareRichTextMessage | Build a forwarded rich text response | | prepareRichImageMessage | Build a forwarded rich image response | | prepareRichLinkMessage | Build a forwarded response with inline link entities | | prepareRichGenerationMessage | Build a rich response from caller-provided rich content | | prepareHtmlMessage | Build an HTML primitive payload for clients that support the experimental structure | | prepareSlotMachineMessage | Wrap the local slot-machine generator as an HTML message payload | | generateLinkPreviewHtml / generateWebsitePreviewHtml | Create escaped link cards or an explicitly requested metadata preview | | parseViewOnceInfo and related helpers | Inspect, download, reconstruct, and apply explicit view-once policies |

All networked helpers are opt-in. Website previews fetch only when explicitly called, and Flow helpers require credentials and identifiers owned by the application. Experimental WhatsApp layouts remain client-dependent and should always have a plain-text fallback.

AI generation primitive

buildImaginePrimitive creates the Meta-style AI image or animation generation-state payload used by rich responses. It is a pure payload builder — it does not call a generation service itself, generate media, or send anything on its own; callers wire it up to whatever AI generation backend they use, then pass the resulting primitive into a rich-response message.

| Field | Purpose | | --- | --- | | state | Generation status: GENERATING, COMPLETE, or ERROR | | mediaUrl | URL of the generated media

CODEX-compatible rich messaging additions

The Codex socket now includes the compatible rich-message helpers documented by CODEX, while retaining Codex-specific APIs and package identity. These helpers are opt-in convenience methods over the existing WhatsApp message relay layer.

| Helper | Purpose | | --- | --- | | sendRichMedia | Sends a complete GenAI-style rich response envelope. | | sendRichGeneration | Sends an AI image/video generation card with a generation state. | | updateRichGeneration | Replaces an existing generation card using the message-edit protocol. | | sendRichText | Sends text inside a forwarded rich-response envelope. | | sendRichImage | Sends an image inside a forwarded rich-response envelope. | | sendRichLink | Sends inline links inside a forwarded rich-response envelope. | | sendReels | Sends rich response content containing reel metadata. | | sendRichSources | Sends rich response content with source metadata. | | sendLink / sendLinkV2 | Convenience aliases for rich inline-link responses. | | sendRichWebview | Sends a native-flow URL CTA for a hosted WebView or Mini App. |

Rich text, images, and links

await sock.sendRichText(jid, {
  text: 'A rich response from Codex'
})

await sock.sendRichImage(jid, {
  url: 'https://example.com/image.png',
  mimeType: 'image/png'
})

await sock.sendRichLink(jid, {
  text: 'Read the documentation',
  links: [{ text: 'Documentation', url: 'https://example.com/docs' }]
})

AI generation cards

const pending = await sock.sendRichGeneration(jid, {
  text: 'Generating an image…',
  mediaType: 'image',
  status: 'GENERATING',
  estimatedMs: 5000,
  itemId: 'image-001'
})

await sock.updateRichGeneration(jid, pending.messageId, {
  text: 'Generation complete',
  mediaType: 'image',
  status: 'READY',
  url: 'https://example.com/generated.png',
  itemId: 'image-001'
})

updateRichGeneration requires the original message identifier returned by sendRichGeneration. Generation and rich-response payloads are protocol-sensitive and should be tested against the WhatsApp clients your application supports.

WebView or Mini App CTA

await sock.sendRichWebview(jid, {
  title: 'Open the dashboard',
  text: 'Tap below to continue',
  buttonText: 'Open dashboard',
  url: 'https://example.com/dashboard',
  useWebview: true,
  toast: 'Opening dashboard'
})

The URL is validated before serialization. Treat button replies and URL destinations as untrusted input, and perform authorization on the server rather than relying on a button identifier.

Reels and source metadata

await sock.sendReels(jid, [{
  url: 'https://example.com/reel.mp4',
  title: 'Featured reel'
}], quotedMessage, { text: 'Featured today' })

await sock.sendRichSources(
  jid,
  'Useful references',
  [{ title: 'Project site', url: 'https://example.com' }],
  quotedMessage
)

These helpers preserve the existing quoted and send-option arguments where supported. The package does not enable background automation or contact discovery as a side effect of using them.

References

Prepared-message relay targeting

relayMessage now accepts optional delivery-scoping controls compatible with CODEX’s relay API. These controls are intended for prepared messages and retry handling; use them only when the application understands the device-level delivery consequences.

await sock.relayMessage(jid, preparedMessage, {
  messageId: 'message-id',
  participant: { jid: '[email protected]' },
  protected: true
})

await sock.relayMessage(jid, preparedMessage, {
  messageId: 'message-id',
  retryParticipants: {
    jid: '15551234567:[email protected]',
    count: 1
  }
})

The participant option targets recipient-only delivery in a one-to-one chat. retryParticipants or participants identifies a device for retry resend, while isSecret, protected, and me restrict delivery to the corresponding device classes. These options do not bypass WhatsApp permissions or authorization checks.

| Added helper | Purpose | | --- | --- | | sendAlbumMessage | Sends two or more image/video items as an album. | | sendRichTextCopy, sendMarkdownQuote, sendQuoteCopy | Rich Markdown responses with optional copy-to-clipboard actions. | | sendBotDiagnostics, sendBotCommand, sendBotToolResult | Experimental bot metadata envelopes for diagnostics, commands, and resolved tool calls. |

Usage

await sock.sendAlbumMessage(jid, [
  { type: 'image', data: { url: './one.jpg' } },
  { type: 'image', data: { url: './two.jpg' } }
], { caption: 'Album caption' })
await sock.sendRichTextCopy(jid, {
  text: '**Install command**\n\nnpm install @codexverified/baileys',
  copyText: 'npm install @codexverified/baileys',
  copyLabel: 'Copy command'
})

await sock.sendMarkdownQuote(jid, {
  text: 'Instruction:\n\n> Use this exact configuration.'
})

Bot metadata helpers are experimental and should not be used as authorization or security controls.

await sock.sendBotCommand(jid, {
  text: 'Run deployment',
  commandName: 'deploy',
  commandDescription: 'Deploy the current build',
  commandPrompt: 'Deploy the current build'
})

Full-width stacked albums

sendAlbumMessage sends a rich vertical album rather than the legacy parent/child album collection. Each image or video is rendered as one large media item on its own row. Provide at least two publicly fetchable media URLs. Both { image: { url } } and the typed { type: 'image', data: { url } } forms are accepted.

await sock.sendAlbumMessage(jid, [
  { image: { url: 'https://example.com/one.jpg' } },
  { image: { url: 'https://example.com/two.jpg' } },
  { image: { url: 'https://example.com/three.jpg' } }
], { caption: 'Codex album' })

The rich album path is URL-based and does not upload local buffers. Remove accidental whitespace from URLs before sending; the implementation trims URL values, but clean URLs are recommended.

A2UI command menu

sendA2UICommandMenu sends the large command/function menu UI: an optional image header, title, command rows, URL buttons, and a native-flow fallback. The rows entries use [command, description] tuples, matching the menu layout shown in the WhatsApp client.

await sock.sendA2UICommandMenu(jid, {
  image: { url: 'https://example.com/menu.jpg' },
  title: 'Speed menu',
  rows: [
    ['.menu', 'Main menu'],
    ['.ping', 'Speed check']
  ],
  buttons: [
    { text: 'Website', url: 'https://example.com' },
    { text: 'Support', url: 'https://example.com/support' }
  ]
})

AIRich command menu and video grid

The compatibility update also exposes the two AIRich layouts that were not already present in Codex. sendAIRichCommandMenu sends the manually serialized command card with an image, Markdown command table, optional widget CTAs, and footer URL actions. The image must be a publicly fetchable URL.

await sock.sendAIRichCommandMenu(jid, {
  image: 'https://example.com/menu.png',
  title: 'CODEX AI',
  subtitle: 'Choose a command',
  rows: [
    ['.menu', 'Show the main menu'],
    ['.ping', 'Check service latency']
  ],
  buttons: [
    { id: 'docs', text: 'Documentation', url: 'https://example.com/docs' }
  ],
  footer: 'Developed by - CODEX TECHNOLOGY'
})

sendVideoGridMessage sends at least two video URL items as a GenAIGridLayoutViewModel containing GenAIVideoPrimitive entries. It is separate from sendAlbumMessage, which uses the vertical album layout.

await sock.sendVideoGridMessage(jid, [
  {
    url: 'https://cdn.example.com/first.mp4',
    title: 'First clip',
    thumbnailUrl: 'https://cdn.example.com/first.jpg',
    progressiveUrls: ['https://cdn.example.com/first-720p.mp4']
  },
  {
    url: 'https://cdn.example.com/second.mp4',
    title: 'Second clip',
    thumbnailUrl: 'https://cdn.example.com/second.jpg'
  }
])

Both layouts are experimental WhatsApp protocol structures. Client rendering can change, and callers should provide a plain-message fallback where reliability matters.

Bot planning responses

sendBotPlanning sends a bot-planning rich response with a summary, ordered step text, and optional planning/query-plan capabilities.

await sock.sendBotPlanning(jid, {
  text: 'Preparing the deployment',
  steps: [
    { title: 'Build', body: 'Compile the application' },
    { title: 'Verify', body: 'Run the checks' },
    'Publish the release'
  ],
  queryPlan: true
})

Newsletter invite metadata

newsletterGetInviteInfo accepts either a channel invite code or a WhatsApp channel invite URL and returns the resolved newsletter metadata, or null when WhatsApp does not return a matching record.

const info = await sock.newsletterGetInviteInfo('https://whatsapp.com/channel/INVITE_CODE')
console.log(info?.id, info?.name, info?.invite)

The lookup is an explicit network request and does not follow, join, or subscribe to the channel.

Carousel, compatibility aliases, and source search

sendCarousel normalizes card media, captions, footers, and buttons before sending a carousel message.

await sock.sendCarousel(jid, [
  {
    title: 'Documentation',
    body: { text: 'Read the API guide' },
    media: { image: { url: 'https://example.com/docs.jpg' } },
    buttons: [{ text: 'Open', id: 'docs' }]
  }
])

HoldOn is retained as a compatibility alias for sendRichButtonGrid. New applications should prefer the descriptive Codex-named method.

grepCode(pattern, options) searches installed package source files and returns matching file, line, column, and source-line information. It is an explicit diagnostic helper and performs no network access.

const matches = sock.grepCode('prepareVideoGridMessage', { includeReadme: true })

Interactive rich HTML

The compatibility update also exposes sendRichHtmlMessage, which uses the interactive GenAI HTML primitive and supports embedded tabs. Only pass trusted, sanitized HTML; this is not a general-purpose HTML sanitizer.

await sock.sendRichHtmlMessage(jid, {
  title: 'CODEX TECHNOLOGY',
  html: '<h1>Hello</hi>',
  url: 'https://codex-ai.site',
  trustedSources: ['codex-ai.site']
})

Multiple tabs can be supplied with tabs; each tab may provide its own html, url, and trustedSources. The structure is experimental and depends on WhatsApp client support.

Codex unified responses and the built-in mini-app

sendCodexMessage accepts one object containing any supported combination of text, links, media, products, reels, tables, code, LaTeX, or suggestions. Unsupported optional sections are ignored by the rich-response serializer, so callers can use one stable entry point for heterogeneous response data.

await sock.sendCodexMessage(jid, {
  text: 'Here is your result',
  links: [{ text: 'Open the docs', url: 'https://example.com/docs' }],
  table: {
    title: 'Summary',
    headers: ['Name', 'Status'],
    rows: [['Codex', 'Ready']]
  }
})

sendMiniApp sends the bundled interactive mini-app as a trusted rich HTML screen. The helper does not fetch or execute caller-provided remote code; pass only presentation options such as title and keep authentication or business actions on your own server.

await sock.sendMiniApp(jid, {
  title: 'Codex mini-app'
}, {
  quoted: message
})

The package also exports BotCapabilityType, normalizeBotCapabilities, buildBotCapabilityMetadata, and buildBotRichResponse for applications that need to construct compatible bot metadata.

New AIRich metadata helpers

The package includes experimental helpers for protocol-backed rich clients. Rendering depends on the recipient's WhatsApp client version; these helpers do not call Meta AI or any private backend.

await sock.sendA2UIMessage(jid, {
  type: 'im_a2ui',
  data: {
    version: 'v0.9',
    createSurface: {
      surfaceId: 'custom-card',
      catalogId: 'https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json',
      components: [{ id: 'root', component: 'Column', children: ['title'] }]
    }
  }
})

await sock.sendRichMap(jid, {
  centerLatitude: 6.5244,
  centerLongitude: 3.3792,
  annotations: [{ latitude: 6.53, longitude: 3.38, title: 'Lagos', body: 'Nigeria' }],
  showInfoList: true
})

await sock.sendBotPromptSuggestions(jid, {
  text: 'Choose a follow-up',
  suggestions: ['Summarize this', 'Translate this', 'Explain further'],
  selectedPromptId: 'translate'
})

await sock.sendBotSources(jid, {
  text: 'Relevant sources:',
  sources: [{
    provider: 2,
    url: 'https://example.com/docs',
    query: 'baileys proto',
    title: 'Documentation',
    citationNumber: 1
  }]
})

await sock.sendRichDynamicMedia(jid, {
  type: 'IMAGE',
  url: 'https://example.com/image.jpg',
  version: 1
})

await sock.sendBotPttTranscript(jid, {
  text: 'Voice transcript',
  transcript: 'Hello, this text came from a voice message.'
})

await sock.sendSocialEntity(jid, {
  platform: 'YOUTUBE',
  username: 'example',
  title: 'Example creator',
  imageUrl: 'https://example.com/avatar.png',
  entityUrl: 'https://www.youtube.com/@example',
  isVerified: true,
  resultText: 'See results'
})

await sock.sendInstagramProfile(jid, {
  username: 'example',
  title: 'Example profile',
  imageUrl: 'https://example.com/avatar.png',
  entityUrl: 'https://www.instagram.com/example',
  isVerified: true,
  resultText: 'See results'
})

The map, prompt, source, dynamic-media, transcript, A2UI, and social/entity payloads are serialized from the generated WAProto structures. Validate URLs, button identifiers, and any user-supplied metadata in your own application before sending.

Thanks for reading my README.