Broadcast & Mass Notification Bot
Overview
Use the Chat API to send targeted one-to-one messages to large employee populations, functioning as a personalised broadcast mechanism.
Traditional broadcast communications, such as all-company emails, feed posts, and push notifications are inherently impersonal. They land in the same format for everyone, get lost in crowded inboxes, and offer no way to personalise the message or collect a response. For time-sensitive or action-required communications (benefits enrollment deadlines, mandatory training reminders, emergency alerts, shift changes), organisations need a channel that feels direct and personal while operating at scale.
The Workvivo Bot API enables exactly this. By creating a bot and opening individual channels with each target employee, you can send personalised one-to-one messages that appear as direct chat conversations; not mass announcements. Each message can include the employee's name, relevant details (their specific deadline, their manager's name, their office location), and interactive elements (quick replies to confirm receipt, card buttons to take action). The result is a broadcast mechanism that feels like a personal message, drives higher engagement than feed posts, and can collect responses programmatically.
Value & Benefits
Achieve higher engagement than feed posts or email. One-to-one chat messages have significantly higher open and read rates than feed posts or emails because they appear as direct conversations in the employee's chat list.
Personalise at scale. Each message can be tailored with employee-specific data (name, department, deadline, manager) while being sent programmatically to hundreds or thousands of recipients.
Collect responses and confirmations. Quick reply buttons let employees acknowledge receipt, confirm attendance, or select options, giving you structured response data without requiring them to navigate to another system.
Target precisely. Use the Users API to filter recipients by team, space, or role before sending, ensuring messages reach only the relevant population.
Control notification behaviour. Choose whether messages trigger mobile push notifications or arrive silently, depending on urgency.
Applications
Benefits enrollment reminders. Send personalised messages to employees who haven't yet completed enrollment, including their specific deadline and a button linking directly to the enrollment portal.
Mandatory training notifications. Notify employees who have outstanding training requirements, with their specific course name and due date, and a quick reply to confirm they'll complete it.
Emergency and safety alerts. Broadcast urgent messages (office closures, safety incidents, weather alerts) to all employees or specific location teams, with quick replies to confirm they've seen the alert.
Shift change notifications. Notify frontline workers of schedule changes with their specific new shift time, and collect confirmation via quick reply buttons.
IT maintenance and outage alerts. Inform affected users about upcoming system maintenance or active outages, with estimated resolution times and a link to the status page.
Survey and feedback distribution. Send personalised survey invitations via bot message with quick reply buttons for simple responses, or card buttons linking to a full survey form.
Technical Details
Before using these examples, complete Quick Start to create an app and API key and find your Base URL and Workvivo-Id.
Broadcast Architecture
Before sending messages, make sure Chat is enabled and configured for the organisation, and that you have already created a bot with POST /v1/chat/bots. The bot must be available to the target recipient: either set global_audience to true, or include the recipient through the bot's team or space audience. Chat is a paid add-on in Workvivo, so this pattern requires an organisation with Chat configured.
The broadcast pattern uses three API operations in sequence:
- Identify recipients: Use
GET /v1/userswith filters (in_teams,in_spaces,in_roles) to build the target list. - Create bot channels: Use
POST /v1/chat/bots/channelsto open a 1:1 channel between the bot and each recipient. - Send messages: Use
POST /v1/chat/bots/messageto deliver the personalised message to each channel.
Step 1: Identify Recipients
Filter users by team, space, or role to build your target audience.
curl -X GET "https://api.workvivo.com/v1/users?in_teams=101|102&take=50&skip=0" \
-H "Authorization: Bearer $WORKVIVO_TOKEN" \
-H "Workvivo-Id: $WORKVIVO_ORG_ID" \
-H "Accept: application/json"
{
"data": [
{
"id": 1,
"external_id": "emp-1001",
"email": "roma.baumbach@example.com",
"name": "Roma Baumbach",
"first_name": "Roma",
"last_name": "Baumbach",
"display_name": null,
"avatar_url": "https://yourcompany.workvivo.com/avatar/1.jpg",
"job_title": "Occupational Health Safety Technician",
"timezone": "Europe/Dublin",
"locale": "en-US",
"hire_date": null,
"manager_id": 42,
"date_of_birth": null,
"mobile_phone": null,
"direct_dial": null,
"has_logged_in": true,
"created_at": "2026-03-31T15:08:43Z",
"permalink": "https://yourcompany.workvivo.com/people/1"
}
],
"status": "success",
"meta": {
"pagination": {
"skip": 0,
"take": 50,
"total_records": 125,
"next_page": "https://api.workvivo.com/v1/users?in_teams=101|102&skip=50&take=50"
}
}
}
Step 2: Create a Bot Channel
Open a 1:1 channel between the bot and a recipient.
curl -X POST https://api.workvivo.com/v1/chat/bots/channels \
-H "Authorization: Bearer $WORKVIVO_TOKEN" \
-H "Workvivo-Id: $WORKVIVO_ORG_ID" \
-F "user_id=1" \
-F "bot_userid=broadcast_bot_userid"
{
"data": {
"channel_url": "example_channel_url",
"cover_url": "https://images.com/example-image",
"member_count": 2,
"created_at": "2026-06-17T00:00:00Z",
"users": [
{ "user_id": 1, "name": "Roma Baumbach" },
{
"bot_userid": "broadcast_bot_userid",
"bot_nickname": "Company Alerts"
}
]
},
"status": "success",
"meta": {}
}
Step 3: Send a Personalised Message
The examples below show request bodies for POST /v1/chat/bots/message. The first tab shows the full cURL wrapper for a text message; the remaining tabs show alternate JSON bodies you can send to the same endpoint.
curl -X POST https://api.workvivo.com/v1/chat/bots/message \
-H "Authorization: Bearer $WORKVIVO_TOKEN" \
-H "Workvivo-Id: $WORKVIVO_ORG_ID" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data @- <<'JSON'
{
"bot_userid": "broadcast_bot_userid",
"channel_url": "example_channel_url",
"type": "message",
"message": "Hi Roma, your benefits enrollment deadline is June 30. Please complete your selections before then to avoid defaulting to last year's plan."
}
JSON
{
"bot_userid": "broadcast_bot_userid",
"channel_url": "example_channel_url",
"type": "quick_reply",
"replies": [
{ "label": "Already done ✓", "message": "Enrollment Complete" },
{ "label": "Remind me later", "message": "Remind Later" },
{ "label": "I need help", "message": "Need Help" }
]
}
{
"bot_userid": "broadcast_bot_userid",
"channel_url": "example_channel_url",
"type": "card",
"cards": [
{
"cardTitle": "Benefits Enrollment - Action Required",
"cardDescription": "Hi Roma, your enrollment deadline is June 30. Click below to complete your selections.",
"buttons": [
{
"label": "Open Enrollment Portal",
"link": "https://benefits.yourcompany.com"
},
{ "label": "Done ✓", "message": "Enrollment Complete" }
]
}
]
}
Suppressing push notifications: For non-urgent broadcasts (e.g., weekly digests), include "send_push": false to deliver the message without triggering a mobile notification.
JavaScript Integration Example
Load the users in one or more teams, create a bot channel for each user, and send a personalised message.
import {
createBotChannel,
getUsersInTeams,
sendBotMessage,
} from './helpers.js';
export async function sendBenefitsReminder(teamIds) {
const users = await getUsersInTeams(teamIds);
for (const user of users) {
const channelUrl = await createBotChannel(user.id);
const firstName = user.first_name ?? user.name;
await sendBotMessage(
channelUrl,
`Hi ${firstName}, your benefits enrollment deadline is June 30.`,
);
}
}
sendBenefitsReminder([101, 102]);
const apiUrl = 'https://api.workvivo.com/v1';
const headers = {
Authorization: `Bearer ${process.env.WORKVIVO_TOKEN}`,
'Workvivo-Id': process.env.WORKVIVO_ORG_ID,
Accept: 'application/json',
};
async function request(path, options = {}) {
const response = await fetch(`${apiUrl}${path}`, {
...options,
headers: { ...headers, ...options.headers },
});
if (!response.ok) {
throw new Error(`Workvivo API request failed: ${response.status}`);
}
return response.json();
}
export async function getUsersInTeams(teamIds) {
const users = [];
const take = 50;
let skip = 0;
while (true) {
const query = new URLSearchParams({
in_teams: teamIds.join('|'),
skip,
take,
});
const result = await request(`/users?${query}`);
const page = result.data ?? [];
users.push(...page);
if (!result.meta?.pagination?.next_page) {
return users;
}
skip += take;
}
}
export async function createBotChannel(userId) {
const body = new URLSearchParams({
user_id: userId,
bot_userid: process.env.WORKVIVO_BOT_USERID,
});
const result = await request('/chat/bots/channels', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body,
});
return result.data.channel_url;
}
export function sendBotMessage(channelUrl, message) {
return request('/chat/bots/message', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
bot_userid: process.env.WORKVIVO_BOT_USERID,
channel_url: channelUrl,
type: 'message',
message,
send_push: true,
}),
});
}