Overview
WhatsApp uses a special ID format called JID (Jabber ID) to identify users, groups, broadcast lists, and other entities. Understanding JID structure is essential for working with Baileys.
A JID consists of three parts: user@server[:device]
- user - The unique identifier (phone number for users, timestamp for groups)
- server - The server domain
- device - Optional device ID for multi-device protocol
Server Types
From src/WABinary/jid-utils.ts:8:
type JidServer =
| 'c.us' // User (legacy)
| 'g.us' // Group
| 'broadcast' // Broadcast list
| 's.whatsapp.net' // User (new)
| 'call' // Call
| 'lid' // LID (Logged In Device)
| 'newsletter' // Newsletter/Channel
| 'bot' // Bot
| 'hosted' // Hosted PN
| 'hosted.lid' // Hosted LID
User JIDs
[country_code][phone_number]@s.whatsapp.net
Examples:
User JIDs do not include +, (), or -. Only digits followed by @s.whatsapp.net.
[country_code][phone_number]@c.us
This format is deprecated but still encountered in some contexts.
Group JIDs
[timestamp]-[creator_suffix]@g.us
Example: [email protected]
- The first number is typically a Unix timestamp of group creation
- The second number identifies the group creator
Broadcast List JIDs
Example: 1234567890@broadcast
Stories/Status
From src/WABinary/jid-utils.ts:5:
const STORIES_JID = 'status@broadcast'
Stories use the special JID status@broadcast.
Newsletter JIDs
Newsletters (WhatsApp Channels) use the @newsletter server.
JID Utilities
Baileys provides utility functions for working with JIDs.
jidDecode
Parse a JID into its components:
From src/WABinary/jid-utils.ts:55:
function jidDecode(jid: string | undefined): FullJid | undefined
type FullJid = {
server: JidServer
user: string
domainType?: number
device?: number
}
Example:
import { jidDecode } from '@whiskeysockets/baileys'
const decoded = jidDecode('[email protected]')
// {
// server: 's.whatsapp.net',
// user: '19999999999',
// domainType: 0,
// device: undefined
// }
const groupDecoded = jidDecode('[email protected]')
// {
// server: 'g.us',
// user: '123456789-1234567890',
// domainType: 0
// }
jidEncode
Construct a JID from components:
From src/WABinary/jid-utils.ts:51:
function jidEncode(
user: string | number | null,
server: JidServer,
device?: number,
agent?: number
): string
Example:
import { jidEncode } from '@whiskeysockets/baileys'
const userJid = jidEncode('19999999999', 's.whatsapp.net')
// '[email protected]'
const groupJid = jidEncode('123456789-1234567890', 'g.us')
// '[email protected]'
// With device ID
const deviceJid = jidEncode('19999999999', 's.whatsapp.net', 0)
// '19999999999:[email protected]'
jidNormalizedUser
Normalize a user JID (convert c.us to s.whatsapp.net):
From src/WABinary/jid-utils.ts:113:
function jidNormalizedUser(jid: string | undefined): string
Example:
JID Type Checking
Baileys provides functions to check JID types:
From src/WABinary/jid-utils.ts:87-108:
// Check if same user
function areJidsSameUser(
jid1: string | undefined,
jid2: string | undefined
): boolean
// Check JID types
function isJidGroup(jid: string | undefined): boolean
function isJidBroadcast(jid: string | undefined): boolean
function isJidStatusBroadcast(jid: string): boolean
function isJidNewsletter(jid: string | undefined): boolean
function isPnUser(jid: string | undefined): boolean
function isLidUser(jid: string | undefined): boolean
function isJidBot(jid: string | undefined): boolean
function isJidMetaAI(jid: string | undefined): boolean
Examples:
import {
isJidGroup,
isJidBroadcast,
areJidsSameUser,
isJidStatusBroadcast
} from '@whiskeysockets/baileys'
// Check if group
if (isJidGroup('[email protected]')) {
console.log('This is a group')
}
// Check if broadcast
if (isJidBroadcast('1234567890@broadcast')) {
console.log('This is a broadcast list')
}
// Check if status/story
if (isJidStatusBroadcast('status@broadcast')) {
console.log('This is a status update')
}
// Compare users (ignoring device ID)
if (areJidsSameUser(
'19999999999:[email protected]',
'[email protected]'
)) {
console.log('Same user, different device')
}
Special JIDs
From src/WABinary/jid-utils.ts:1-6:
import { isJidBot, META_AI_JID } from '@whiskeysockets/baileys'
if (isJidBot(META_AI_JID)) {
console.log('This is Meta AI')
}
Multi-Device Protocol
Device IDs
In multi-device protocol, JIDs can include a device ID:
:0 is the primary device (phone)
:1, :2, etc. are companion devices
Transferring Device ID
From src/WABinary/jid-utils.ts:123:
function transferDevice(fromJid: string, toJid: string): string
Example:
LID (Logged In Device)
LID is a privacy-focused identifier used in some contexts:
LID Utilities
import { isLidUser } from '@whiskeysockets/baileys'
if (isLidUser('abc123@lid')) {
console.log('This is a LID user')
}
Practical Examples
Sending to a User
const phoneNumber = '19999999999'
const jid = `${phoneNumber}@s.whatsapp.net`
await sock.sendMessage(jid, { text: 'Hello!' })
import { jidDecode } from '@whiskeysockets/baileys'
function getPhoneNumber(jid: string): string | undefined {
const decoded = jidDecode(jid)
return decoded?.server === 's.whatsapp.net'
? decoded.user
: undefined
}
const phone = getPhoneNumber('[email protected]')
// '19999999999'
Validating Group JID
import { isJidGroup } from '@whiskeysockets/baileys'
function isValidGroupJid(jid: string): boolean {
return isJidGroup(jid) && jid.includes('-')
}
Filtering Message Types
import { isJidNewsletter, isJidGroup } from '@whiskeysockets/baileys'
sock.ev.on('messages.upsert', ({ messages }) => {
for (const msg of messages) {
const jid = msg.key.remoteJid!
if (isJidGroup(jid)) {
console.log('Group message')
} else if (isJidNewsletter(jid)) {
console.log('Newsletter message')
} else {
console.log('Private message')
}
}
})
JID Domain Types
From src/WABinary/jid-utils.ts:20:
enum WAJIDDomains {
WHATSAPP = 0,
LID = 1,
HOSTED = 128,
HOSTED_LID = 129
}
Domain types are used internally to route messages to the correct server infrastructure.
Best Practices
JID Handling Tips:
- Always validate - Use type checking functions before operations
- Normalize user JIDs - Use
jidNormalizedUser for consistency
- Handle device IDs - Use
areJidsSameUser to compare users across devices
- Never hardcode formats - Use
jidEncode to construct JIDs
- Check types - Use
isJidGroup, isJidBroadcast, etc. before group operations
- Store normalized JIDs - Always normalize before storing in database
Common Mistakes
Avoid These Mistakes:❌ Including + in JIDs: [email protected]✅ Use digits only: [email protected]❌ Mixing server types: Using c.us for new messages✅ Use s.whatsapp.net for users: jidNormalizedUser(jid)❌ String concatenation: phoneNumber + '@s.whatsapp.net'✅ Use jidEncode: jidEncode(phoneNumber, 's.whatsapp.net')
See Also