Groups API
Create, configure, and manage WhatsApp groups for community engagement and customer communication.
Official Documentation: WhatsApp Groups API
Overview
The Groups API enables comprehensive group management:
- Create Groups: Set up new WhatsApp groups
- List Groups: Retrieve all groups for your phone number
- Manage Participants: Add and remove group members
- Join Requests: Handle group join approval workflows
- Invite Links: Generate and manage shareable invite links
- Group Settings: Update group name, description, and picture
Endpoints
POST /{PHONE_NUMBER_ID}/groupsGET /{PHONE_NUMBER_ID}/groups?limit&after&beforeGET /{GROUP_ID}?fieldsPOST /{GROUP_ID}DELETE /{GROUP_ID}GET /{GROUP_ID}/invite_linkPOST /{GROUP_ID}/invite_linkGET /{GROUP_ID}/join_requestsPOST /{GROUP_ID}/join_requestsDELETE /{GROUP_ID}/join_requestsDELETE /{GROUP_ID}/participantsImportant Notes
Quick Start
import WhatsApp from 'meta-cloud-api';
const client = new WhatsApp({ accessToken: process.env.CLOUD_API_ACCESS_TOKEN!, phoneNumberId: Number(process.env.WA_PHONE_NUMBER_ID), businessAcctId: process.env.WA_BUSINESS_ACCOUNT_ID,});
// Create a groupconst group = await client.groups.createGroup({ subject: 'Product Updates', description: 'Get notified about new product releases', join_approval_mode: 'auto_approve',});
// Get group infoconst info = await client.groups.getGroupInfo(group.id, [ 'subject', 'description', 'participants',]);
// Generate invite linkconst invite = await client.groups.getGroupInviteLink(group.id);
// Remove participantsawait client.groups.removeParticipants(group.id, ['15551234567']);
// Delete groupawait client.groups.deleteGroup(group.id);Create Group
Set up a new WhatsApp group.
Basic Group Creation
const group = await client.groups.createGroup({ subject: 'Customer Support', description: 'Get help from our support team', join_approval_mode: 'auto_approve',});
console.log('Group ID:', group.id);console.log('Invite link:', group.invite_link);Group with Approval Required
const group = await client.groups.createGroup({ subject: 'VIP Customers', description: 'Exclusive updates for VIP members', join_approval_mode: 'approval_required',});Group with Profile Picture
import fs from 'fs';
const imageBuffer = fs.readFileSync('/path/to/group-icon.jpg');const imageFile = new File([imageBuffer], 'icon.jpg', { type: 'image/jpeg'});
const group = await client.groups.createGroup({ subject: 'Team Chat', description: 'Internal team communication', join_approval_mode: 'auto_approve', profile_picture: imageFile,});List Groups
Retrieve all groups managed by your phone number.
Get All Groups
const groups = await client.groups.listGroups();
groups.data.forEach(group => { console.log(`${group.subject} (${group.id})`);});Paginated List
// Get first pageconst page1 = await client.groups.listGroups({ limit: 20 });
// Get next pageif (page1.paging?.cursors?.after) { const page2 = await client.groups.listGroups({ limit: 20, after: page1.paging.cursors.after, });}Get All Groups (All Pages)
async function getAllGroups() { const allGroups = []; let after: string | undefined;
do { const response = await client.groups.listGroups({ limit: 100, after, });
allGroups.push(...response.data); after = response.paging?.cursors?.after; } while (after);
return allGroups;}Get Group Information
Retrieve detailed information about a specific group.
Get All Fields
const group = await client.groups.getGroupInfo(groupId, [ 'id', 'subject', 'description', 'participants', 'created_at', 'updated_at',]);
console.log(group);Get Specific Fields
// Just basic infoconst basicInfo = await client.groups.getGroupInfo(groupId, [ 'subject', 'description',]);
// Just participantsconst members = await client.groups.getGroupInfo(groupId, [ 'participants',]);Update Group Settings
Modify group name, description, or profile picture.
Update Basic Information
await client.groups.updateGroupSettings(groupId, { subject: 'Updated Group Name', description: 'Updated group description',});Update Profile Picture
import fs from 'fs';
const imageBuffer = fs.readFileSync('/path/to/new-icon.jpg');const imageFile = new File([imageBuffer], 'icon.jpg', { type: 'image/jpeg'});
await client.groups.updateGroupSettings(groupId, { profile_picture: imageFile,});Complete Update
await client.groups.updateGroupSettings(groupId, { subject: 'Product Announcements', description: 'Official product updates and news', profile_picture: imageFile,});Manage Invite Links
Generate and revoke group invite links.
Get Current Invite Link
const invite = await client.groups.getGroupInviteLink(groupId);
console.log('Invite link:', invite.invite_link);console.log('Invite code:', invite.invite_code);Revoke and Generate New Link
const newInvite = await client.groups.revokeGroupInviteLink(groupId);
console.log('New invite link:', newInvite.invite_link);Share Invite Link
const invite = await client.groups.getGroupInviteLink(groupId);
// Send invite link via messageawait client.messages.text({ to: '15551234567', body: `Join our group: ${invite.invite_link}`,});Handle Join Requests
Manage group join approval workflow.
List Pending Join Requests
const requests = await client.groups.getJoinRequests(groupId);
requests.data.forEach(request => { console.log(`User ${request.wa_id} wants to join`);});Approve Join Request
await client.groups.approveJoinRequest(groupId, '15551234567');
console.log('Join request approved');Reject Join Request
await client.groups.rejectJoinRequest(groupId, '15551234567');
console.log('Join request rejected');Bulk Approve Requests
async function approveAllPendingRequests(groupId: string) { const requests = await client.groups.getJoinRequests(groupId);
for (const request of requests.data) { await client.groups.approveJoinRequest(groupId, request.wa_id); }
console.log(`Approved ${requests.data.length} join requests`);}Manage Participants
Add and remove group members.
Remove Single Participant
await client.groups.removeParticipants(groupId, ['15551234567']);
console.log('Participant removed');Remove Multiple Participants
const usersToRemove = [ '15551234567', '15559876543', '15555555555',];
await client.groups.removeParticipants(groupId, usersToRemove);
console.log(`Removed ${usersToRemove.length} participants`);Remove Participants in Batches
async function removeManyParticipants( groupId: string, phoneNumbers: string[]) { // Process in batches of 8 (API limit) const batchSize = 8;
for (let i = 0; i < phoneNumbers.length; i += batchSize) { const batch = phoneNumbers.slice(i, i + batchSize); await client.groups.removeParticipants(groupId, batch); console.log(`Removed batch ${i / batchSize + 1}`); }}Delete Group
Permanently delete a group.
await client.groups.deleteGroup(groupId);
console.log('Group deleted');Advanced Use Cases
Community Group Manager
class CommunityGroupManager { private client: WhatsApp;
constructor(client: WhatsApp) { this.client = client; }
async createCommunityGroup( name: string, description: string, requireApproval: boolean = true ) { const group = await this.client.groups.createGroup({ subject: name, description, join_approval_mode: requireApproval ? 'approval_required' : 'auto_approve', });
// Store group info await database.groups.insert({ id: group.id, name, description, createdAt: new Date(), });
return group; }
async broadcastToGroup(groupId: string, message: string) { const group = await this.client.groups.getGroupInfo(groupId, [ 'participants', ]);
// Send message to all participants for (const participant of group.participants) { await this.client.messages.text({ to: participant.wa_id, body: message, }); } }
async autoModerateJoinRequests(groupId: string) { const requests = await this.client.groups.getJoinRequests(groupId);
for (const request of requests.data) { // Check if user meets criteria const isApproved = await this.checkUserEligibility(request.wa_id);
if (isApproved) { await this.client.groups.approveJoinRequest( groupId, request.wa_id ); } else { await this.client.groups.rejectJoinRequest( groupId, request.wa_id ); } } }
private async checkUserEligibility(waId: string): Promise<boolean> { // Your eligibility logic return true; }}VIP Customer Group
async function setupVIPGroup() { // Create VIP group const group = await client.groups.createGroup({ subject: 'VIP Customers', description: 'Exclusive offers and early access', join_approval_mode: 'approval_required', });
// Get invite link const invite = await client.groups.getGroupInviteLink(group.id);
// Send invite to VIP customers const vipCustomers = await database.customers.find({ tier: 'VIP' });
for (const customer of vipCustomers) { await client.messages.text({ to: customer.phoneNumber, body: `Welcome to our VIP group! Join here: ${invite.invite_link}`, }); }
return group;}Product Launch Group
async function createProductLaunchGroup(productName: string) { const group = await client.groups.createGroup({ subject: `${productName} Launch`, description: `Get updates about ${productName}`, join_approval_mode: 'auto_approve', });
// Send announcement const subscribers = await database.subscribers.find({ interested_in: productName, });
const invite = await client.groups.getGroupInviteLink(group.id);
for (const subscriber of subscribers) { await client.messages.template({ to: subscriber.phoneNumber, template: { name: 'product_launch_invite', language: { code: 'en_US' }, components: [ { type: 'BODY', parameters: [ { type: 'TEXT', text: productName }, { type: 'TEXT', text: invite.invite_link }, ], }, ], }, }); }
return group;}Response Formats
Create Group Response
{ id: 'GROUP_ID', subject: 'Product Updates', invite_link: 'https://chat.whatsapp.com/...'}Group Info Response
{ id: 'GROUP_ID', subject: 'Customer Support', description: 'Get help from our support team', participants: [ { wa_id: '15551234567', is_admin: true }, { wa_id: '15559876543', is_admin: false } ], created_at: '2024-01-15T10:30:00Z', updated_at: '2024-01-20T15:45:00Z'}Join Requests Response
{ data: [ { wa_id: '15551234567', requested_at: '2024-01-15T10:30:00Z' } ]}Error Handling
try { await client.groups.createGroup({ subject: 'New Group', description: 'Description', join_approval_mode: 'auto_approve', });} catch (error) { if (error.response) { const { code, message } = error.response.data.error;
switch (code) { case 131031: console.error('Invalid group settings'); break; case 131000: console.error('Group creation failed'); break; default: console.error(`Error ${code}: ${message}`); } }}Best Practices
-
Use Descriptive Names: Make group purpose clear
// ✅ Goodsubject: 'Product Launch 2024 - Beta Testers'// ❌ Badsubject: 'Group 1' -
Set Appropriate Approval Mode: Choose based on use case
// Public community - auto approvejoin_approval_mode: 'auto_approve'// Private/VIP - require approvaljoin_approval_mode: 'approval_required' -
Batch Participant Removals: Respect API limits
// Process in batches of 8const batchSize = 8;for (let i = 0; i < users.length; i += batchSize) {await client.groups.removeParticipants(groupId,users.slice(i, i + batchSize));} -
Track Group Metrics: Monitor group health
interface GroupMetrics {groupId: string;memberCount: number;joinRequestsToday: number;messagesThisWeek: number;}async function getGroupMetrics(groupId: string): Promise<GroupMetrics> {const info = await client.groups.getGroupInfo(groupId, ['participants',]);return {groupId,memberCount: info.participants.length,joinRequestsToday: await countTodayJoinRequests(groupId),messagesThisWeek: await countWeeklyMessages(groupId),};} -
Automate Join Request Handling: Reduce manual work
setInterval(async () => {const groups = await client.groups.listGroups();for (const group of groups.data) {await autoModerateJoinRequests(group.id);}}, 60 * 60 * 1000); // Every hour
Related Documentation
- Messages API - Send group messages
- Webhooks - Receive group events
- Templates API - Create group invite templates
- Community Management - Best practices
Source Code
View the source code on GitHub: GroupsApi.ts