To integrate Webex by Cisco with Bolt.new, get a developer access token from developer.webex.com and create a Next.js API route that sends messages to Webex spaces, lists rooms, and manages people using Webex's REST API with Bearer token authentication. Outbound messaging works in Bolt's WebContainer preview. Incoming webhook events (new messages, user actions) require a deployed URL on Netlify or Bolt Cloud.
Integrating Webex Messaging and Meetings into Bolt.new Apps
Webex provides one of the most complete developer APIs in the enterprise collaboration space, covering messaging (spaces, direct messages), meetings (creating, scheduling, listing recordings), calling, and device management. For Bolt.new developers, the most common use cases are sending notifications to Webex spaces from app events, building bots that respond to messages, and creating meeting links that embed into Bolt-based scheduling tools.
The Webex API uses a simple Bearer token pattern — your developer access token goes in the Authorization header for every request. Getting started is unusually fast: go to developer.webex.com, sign in with any Webex or Cisco account, and your developer access token is displayed immediately on the 'Getting Started' page. This personal access token is valid for 12 hours and is perfect for development. For production, you create an integration (OAuth) or a bot account with a non-expiring bot token.
Webex bots are separate accounts with their own Webex identities. When users add your bot to a Webex space, the bot can send and receive messages in that space. Bot tokens don't expire, making them ideal for production notification bots and automated messaging. The distinction matters for Bolt.new integration: for sending notifications from your app to a Webex space, a bot token is the most practical approach. For user-specific operations (like creating meetings on behalf of users or reading their conversations), you need OAuth, which requires a deployed callback URL.
Integration method
Webex integrates with Bolt.new via its REST API using Bearer token authentication — your developer access token in the Authorization header. Create Next.js API routes that send messages to Webex spaces, list rooms, manage team members, and create meetings. Outbound Webex API calls work in Bolt's WebContainer preview. Webhooks for receiving new message events, room membership changes, and meeting notifications require your app to be deployed to Netlify or Bolt Cloud with a public HTTPS URL registered in the Webex developer portal.
Prerequisites
- A Webex account (free tier available at webex.com, supports full API access)
- A Webex bot token — create a bot at developer.webex.com/my-apps/new/bot and save the token (shown only once)
- The Webex space ID where your bot will send messages (get it by adding the bot to a space and calling GET /rooms)
- For OAuth-based user actions: a deployed URL for the OAuth callback (WebContainer cannot handle OAuth redirects)
- A Bolt.new project using Next.js for server-side API routes
Step-by-step guide
Create a Webex Bot and Get Your Access Token
Create a Webex Bot and Get Your Access Token
Webex provides two types of credentials for API access. The first is a personal access token, available immediately at developer.webex.com under 'Getting Started'. This is tied to your personal Webex account, is valid for 12 hours, and is perfect for development and testing. The second is a bot access token — bots are separate Webex accounts with their own names, email addresses, and persistent tokens that never expire. For production integrations that send automated messages, bot tokens are the practical choice. To create a bot, go to developer.webex.com, click your avatar, select 'My Webex Apps', then 'Create a New App' → 'Create a Bot'. Fill in the bot name (how it will appear in Webex), username (the @mention name), description, and optionally upload an icon. Click 'Add Bot'. The bot's access token is shown on the next page — copy it immediately. If you lose it, you can regenerate it from the bot's settings page, but existing webhooks using the old token will stop working. Add your bot to a Webex space: go to the Webex app, open a space (or create a new one for testing), click 'Add People', search for your bot's email address (botname@webex.bot), and add it. To find the space ID for that space, call GET https://webexapis.com/v1/rooms with your bot token and look for the space name in the response.
1# .env2WEBEX_BOT_TOKEN=your_bot_access_token_here3WEBEX_SPACE_ID=the_room_id_of_your_target_spacePro tip: Never commit your Webex bot token to Git. Unlike OAuth access tokens that expire, Webex bot tokens are permanent until regenerated. Store them only in server-side environment variables.
Expected result: You have a Webex bot created with its own Webex identity. The bot token is saved as WEBEX_BOT_TOKEN. The space ID of the target space is saved as WEBEX_SPACE_ID. The bot has been added to the target space.
Send Messages to Webex Spaces
Send Messages to Webex Spaces
The Webex Messages API is the primary outbound integration. Sending a message requires a POST to https://webexapis.com/v1/messages with a JSON body containing the space ID (roomId), and either text or markdown content. The markdown option supports bold, italic, headers, code blocks, and bullet lists — use it for rich notification messages rather than plain text. The Bearer token goes in the Authorization header. This outbound call works in Bolt's WebContainer preview — you can test message sending during development and see messages appear in your Webex space in real time. Webex messages can include file attachments by providing a files array of URLs, or Adaptive Cards for interactive content using the attachments field with the application/vnd.microsoft.card.adaptive content type. For most notification use cases, markdown text is sufficient. Keep messages concise since Webex spaces can be busy — include the most important information (what happened, severity, link for more details) without overwhelming the channel.
Create a Webex messaging API route at /api/webex/messages that handles POST requests. Accept roomId (optional, default to WEBEX_SPACE_ID), text, and markdown (boolean) in the request body. Use the WEBEX_BOT_TOKEN to POST to https://webexapis.com/v1/messages. If markdown is true, send the message as the 'markdown' field; otherwise use the 'text' field. Return the created message ID and roomId. Also create a helper function sendWebexNotification(message, isMarkdown?) that calls this endpoint for use throughout the app.
Paste this in Bolt.new chat
1// app/api/webex/messages/route.ts2import { NextResponse } from 'next/server';34const WEBEX_API = 'https://webexapis.com/v1';56function getWebexHeaders() {7 return {8 Authorization: `Bearer ${process.env.WEBEX_BOT_TOKEN}`,9 'Content-Type': 'application/json',10 };11}1213export async function POST(request: Request) {14 try {15 const { roomId, text, markdown } = await request.json();16 const targetRoom = roomId || process.env.WEBEX_SPACE_ID;1718 if (!targetRoom) {19 return NextResponse.json(20 { error: 'roomId is required or WEBEX_SPACE_ID must be set' },21 { status: 400 }22 );23 }2425 if (!text) {26 return NextResponse.json({ error: 'text is required' }, { status: 400 });27 }2829 const body: Record<string, string> = { roomId: targetRoom };30 if (markdown) {31 body.markdown = text;32 } else {33 body.text = text;34 }3536 const response = await fetch(`${WEBEX_API}/messages`, {37 method: 'POST',38 headers: getWebexHeaders(),39 body: JSON.stringify(body),40 });4142 if (!response.ok) {43 const error = await response.json();44 return NextResponse.json({ error }, { status: response.status });45 }4647 const message = await response.json();48 return NextResponse.json({ messageId: message.id, roomId: message.roomId });49 } catch (error: unknown) {50 const e = error as { message: string };51 return NextResponse.json({ error: e.message }, { status: 500 });52 }53}Pro tip: Use Webex markdown for notifications: **bold** for severity labels, `code` for identifiers, and bullet lists for multiple items. Webex renders markdown in all clients including mobile.
Expected result: POST to /api/webex/messages sends a message to the configured Webex space. The message appears in the space immediately. Markdown formatting renders correctly in Webex clients.
Create Webex Meetings Programmatically
Create Webex Meetings Programmatically
The Webex Meetings API lets you create scheduled meetings, generate join links, and manage meeting settings. Meeting creation requires a personal access token or OAuth token (not a bot token) because meetings are tied to user accounts, not bots. Use your developer personal access token for development testing. For production, implement OAuth 2.0 authorization so users authorize your app to create meetings on their behalf — the same pattern as GoToWebinar but with Webex's OAuth endpoints. The meeting creation endpoint is POST https://webexapis.com/v1/meetings. Required fields are title, start (ISO 8601), and end (ISO 8601). The response includes webLink (browser join URL), password, meetingNumber, and siteUrl. Store the webLink to display to meeting participants. Meeting host emails can be specified, and the API supports recurring meetings, alternative hosts, and custom join behavior. A useful pattern for Bolt scheduling apps: create a hidden API route that creates a Webex meeting when users confirm a booking, returns the join link, and stores it in your database alongside the booking record. Users see the join link in their booking confirmation without needing a Webex account themselves — they join as guests.
Create a Webex meeting creation route at /api/webex/meetings. Accept title, startTime (ISO string), endTime (ISO string), and optional password from POST request body. Use WEBEX_ACCESS_TOKEN (personal access token) to call POST https://webexapis.com/v1/meetings. Return the meeting's webLink, password, meetingNumber, and title. Add validation: ensure startTime is in the future and endTime is after startTime.
Paste this in Bolt.new chat
1// app/api/webex/meetings/route.ts2import { NextResponse } from 'next/server';34export async function POST(request: Request) {5 try {6 const { title, startTime, endTime, password } = await request.json();78 if (!title || !startTime || !endTime) {9 return NextResponse.json(10 { error: 'title, startTime, and endTime are required' },11 { status: 400 }12 );13 }1415 const start = new Date(startTime);16 const end = new Date(endTime);1718 if (start <= new Date()) {19 return NextResponse.json({ error: 'startTime must be in the future' }, { status: 400 });20 }21 if (end <= start) {22 return NextResponse.json({ error: 'endTime must be after startTime' }, { status: 400 });23 }2425 const meetingData: Record<string, unknown> = {26 title,27 start: start.toISOString(),28 end: end.toISOString(),29 enabledAutoRecordMeeting: false,30 allowAnyUserToBeCoHost: false,31 };32 if (password) meetingData.password = password;3334 const response = await fetch('https://webexapis.com/v1/meetings', {35 method: 'POST',36 headers: {37 Authorization: `Bearer ${process.env.WEBEX_ACCESS_TOKEN}`,38 'Content-Type': 'application/json',39 },40 body: JSON.stringify(meetingData),41 });4243 if (!response.ok) {44 const error = await response.json();45 return NextResponse.json({ error }, { status: response.status });46 }4748 const meeting = await response.json();49 return NextResponse.json({50 meetingId: meeting.id,51 title: meeting.title,52 webLink: meeting.webLink,53 password: meeting.password,54 meetingNumber: meeting.meetingNumber,55 startTime: meeting.start,56 endTime: meeting.end,57 });58 } catch (error: unknown) {59 const e = error as { message: string };60 return NextResponse.json({ error: e.message }, { status: 500 });61 }62}Pro tip: Personal access tokens expire after 12 hours. For production meeting creation, implement Webex OAuth 2.0 and store the access and refresh tokens per user. The OAuth callback URL must be a deployed HTTPS endpoint.
Expected result: POST to /api/webex/meetings with valid meeting details creates a Webex meeting and returns a webLink join URL. The meeting appears in the organizer's Webex calendar.
Deploy and Configure Message Webhooks
Deploy and Configure Message Webhooks
The messaging and meeting creation routes above use outbound API calls that work in Bolt's WebContainer preview. To build a responsive Webex bot that reacts to messages (someone mentions the bot, posts in a space, or sends a direct message), you need webhooks — Webex sends a POST to your endpoint when these events occur. Bolt's WebContainer has no public URL during development, so Webex cannot deliver webhook events. Deploy to Netlify or Bolt Cloud first. After deploying, create a Webex webhook via the API by calling POST https://webexapis.com/v1/webhooks with your bot token. Specify the webhook URL (your deployed handler endpoint), the event resource (messages), the event trigger (created), and optionally a filter (e.g., roomId to monitor only a specific space, or mentionedPeople=me to only receive messages that mention your bot). When the bot receives a message event, Webex sends only the message ID — you must make a second API call to GET /messages/{messageId} to fetch the actual message content. This two-step pattern prevents Webex from sending sensitive message data to unverified endpoints. Webex supports multiple webhook targets simultaneously, so you can have separate handlers for messages, memberships, and meetings.
Create a Webex webhook handler at /api/webex/webhook. When a POST arrives, extract the resource and event from the payload body. For message created events, fetch the actual message content by calling GET https://webexapis.com/v1/messages/{id} with WEBEX_BOT_TOKEN. If the message is from the bot itself, ignore it. Otherwise, parse the message text for commands starting with '/' and respond accordingly. Reply to the space using POST /messages with the same roomId. Also create a /api/webex/setup-webhook route that creates the Webex webhook registration pointing to the deployed handler URL.
Paste this in Bolt.new chat
1// app/api/webex/webhook/route.ts2import { NextResponse } from 'next/server';34interface WebexWebhookPayload {5 resource: string;6 event: string;7 data: { id: string; roomId: string; personId: string };8}910interface WebexMessage {11 id: string;12 roomId: string;13 personId: string;14 text?: string;15}1617const WEBEX_API = 'https://webexapis.com/v1';18const botHeaders = {19 Authorization: `Bearer ${process.env.WEBEX_BOT_TOKEN}`,20 'Content-Type': 'application/json',21};2223export async function POST(request: Request) {24 try {25 const payload: WebexWebhookPayload = await request.json();2627 if (payload.resource === 'messages' && payload.event === 'created') {28 // Fetch actual message content29 const msgResponse = await fetch(30 `${WEBEX_API}/messages/${payload.data.id}`,31 { headers: botHeaders }32 );33 const message: WebexMessage = await msgResponse.json();3435 // Ignore messages from the bot itself36 const meResponse = await fetch(`${WEBEX_API}/people/me`, { headers: botHeaders });37 const me = await meResponse.json();38 if (message.personId === me.id) {39 return NextResponse.json({ skipped: 'own message' });40 }4142 // Handle commands43 const text = (message.text || '').trim();44 let reply = 'I received your message.';45 if (text.startsWith('/help')) {46 reply = 'Available commands: /help, /status';47 } else if (text.startsWith('/status')) {48 reply = '**Status**: All systems operational ✅';49 }5051 await fetch(`${WEBEX_API}/messages`, {52 method: 'POST',53 headers: botHeaders,54 body: JSON.stringify({ roomId: message.roomId, markdown: reply }),55 });56 }5758 return NextResponse.json({ received: true });59 } catch (error: unknown) {60 const e = error as { message: string };61 return NextResponse.json({ error: e.message }, { status: 500 });62 }63}Pro tip: Always check if the incoming message is from the bot itself before processing — without this check, your bot will respond to its own messages, creating an infinite loop.
Expected result: After deployment and webhook registration, messages to the Webex space trigger the webhook handler. The bot fetches message content, processes commands, and replies in the space. The bot ignores its own messages.
Common use cases
App Event Notifications to Webex Space
Send automated notifications to a Webex team space when important events occur in your Bolt app — new user signups, order completions, error alerts, or deployment notifications. The bot posts formatted messages to a designated space, keeping the whole team informed without anyone needing to check the app.
Create a notification system that sends messages to our team's Webex space when important events happen. Create a /api/webex/notify API route that accepts a message string and optional markdown boolean, then posts to a Webex space using the bot token from WEBEX_BOT_TOKEN and the space ID from WEBEX_SPACE_ID. The message should include the event type, timestamp, and relevant details. Call this from my app's key event handlers: new user signup, order completion, and critical error detection.
Copy this prompt to try it in Bolt.new
Webex Meeting Scheduler
Build a meeting scheduler in your Bolt app that creates Webex meetings for selected time slots and returns join links. Users pick a time, the app creates a Webex meeting, and all participants receive the join URL. The meeting link integrates with your existing scheduling or booking system.
Create a meeting scheduler that creates Webex meetings. Build /api/webex/meetings (POST) that accepts title, startTime, endTime, and invitees array (emails). Use the Webex Meetings API with WEBEX_ACCESS_TOKEN to create the meeting, then return the webLink (browser join URL) and password. Display the meeting details in a confirmation card with a 'Copy Join Link' button and 'Add to Calendar' functionality for Google Calendar and Outlook.
Copy this prompt to try it in Bolt.new
Webex Bot for Team Slash Commands
Build a Webex bot that responds to slash commands in your team's Webex space. Team members type '/status', '/deploy prod', or '/report daily' and the bot executes the corresponding action and replies in the space. Requires deployment for the webhook endpoint that receives messages.
Build a Webex slash command bot. Create /api/webex/webhook as the message webhook handler. When the bot receives a message activity, check if the text starts with '/'. For '/status', fetch system health metrics and reply with a formatted status message. For '/help', list available commands. For unrecognized commands, reply 'Unknown command. Type /help for the list of available commands.' Ignore messages from other bots using the actor type check.
Copy this prompt to try it in Bolt.new
Troubleshooting
Webex API returns 401 Unauthorized for all requests
Cause: The access token is expired (personal access tokens expire after 12 hours), the bot token has been regenerated, or the Authorization header format is wrong.
Solution: For development, refresh your personal access token at developer.webex.com — scroll to the 'Getting Started' section and copy the fresh token. For production bots, verify WEBEX_BOT_TOKEN is still valid by calling GET https://webexapis.com/v1/people/me with the token. If the bot token is invalid, regenerate it in your app settings at developer.webex.com/my-apps. The Authorization header must be 'Bearer YOUR_TOKEN' with a space after 'Bearer'.
1// Test if your bot token is valid:2const test = await fetch('https://webexapis.com/v1/people/me', {3 headers: { Authorization: `Bearer ${process.env.WEBEX_BOT_TOKEN}` }4});5const me = await test.json();6console.log('Bot identity:', me.displayName, me.emails);Webex webhook events never arrive during development
Cause: Bolt's WebContainer has no publicly accessible URL. Webex cannot deliver webhook POST requests to a browser-based runtime.
Solution: Deploy to Netlify or Bolt Cloud first. After deployment, create your Webex webhook registration pointing to your deployed URL (e.g., https://your-app.netlify.app/api/webex/webhook). You can create the webhook registration using the API: POST to https://webexapis.com/v1/webhooks with your bot token and the deployed URL.
1// Register webhook after deploying:2const webhook = await fetch('https://webexapis.com/v1/webhooks', {3 method: 'POST',4 headers: { Authorization: `Bearer ${process.env.WEBEX_BOT_TOKEN}`, 'Content-Type': 'application/json' },5 body: JSON.stringify({6 name: 'My Bolt Bot Webhook',7 targetUrl: 'https://your-app.netlify.app/api/webex/webhook',8 resource: 'messages',9 event: 'created',10 }),11});Bot responds to its own messages causing an infinite reply loop
Cause: The webhook handler doesn't check if the message author is the bot itself, so the bot's replies trigger more webhook events, which trigger more replies.
Solution: Before processing any message, fetch your bot's identity via GET /people/me and compare the message's personId to your bot's id. If they match, return immediately without processing.
1// Add at the top of your message handler:2const meRes = await fetch('https://webexapis.com/v1/people/me', { headers: botHeaders });3const me = await meRes.json();4if (message.personId === me.id) return NextResponse.json({ skipped: 'own message' });Best practices
- Use a Webex bot token for notification bots rather than your personal access token — bot tokens don't expire and won't break when your personal token rotates every 12 hours
- Store WEBEX_BOT_TOKEN as a server-side environment variable (no NEXT_PUBLIC_ prefix) — it allows sending messages to any space the bot is a member of
- Always check message.personId against your bot's own ID before processing messages to prevent infinite reply loops
- Use Webex markdown formatting for notification messages — bold for severity, code blocks for identifiers, and bullet lists for multiple items improve readability in all Webex clients
- Deploy before testing webhooks — Webex webhook events cannot reach Bolt's WebContainer, and attempting to debug webhook issues in development wastes time
- Respond to Webex webhooks within 60 seconds — Webex retries failed deliveries, and slow responses cause duplicate message processing
- Create separate Webex webhooks for different event types (messages created, memberships created) rather than a single all-events webhook to simplify your handler logic
- Use filter parameters when creating webhooks (e.g., mentionedPeople=me) to reduce webhook volume — only receive events that require a bot response rather than all space activity
Alternatives
Microsoft Teams has better Microsoft 365 integration and a larger user base in enterprise environments — choose Teams when your organization uses Microsoft 365 or Azure.
Slack has a more developer-friendly API, larger app ecosystem, and higher adoption among tech teams — choose Slack when your target users are more likely to be on Slack than Webex.
Zoom combines video meetings with team messaging and has better hardware-agnostic performance — choose Zoom when video quality and ease of use are the top priorities over enterprise IT integration.
Frequently asked questions
What's the difference between a Webex personal access token and a bot token?
A personal access token represents your Webex user account, expires after 12 hours, and is meant for development and testing. A bot token represents a bot account (a separate Webex identity with its own name and email), never expires, and is meant for production integrations. Use your personal access token while building and testing in Bolt, then switch to a bot token before deploying to production.
Can I send messages to Webex from Bolt's WebContainer preview?
Yes. Sending messages to Webex is an outbound HTTPS call that works in Bolt's WebContainer. You can test your /api/webex/messages route and see messages appear in your Webex space during development. What doesn't work in the preview is receiving incoming Webex events via webhooks — those require a deployed URL that Webex can call.
How do I find a Webex room (space) ID?
Call GET https://webexapis.com/v1/rooms with your bot token to list all spaces the bot is a member of. Find the space by name in the response and copy its id field. Alternatively, use the Webex developer portal at developer.webex.com/docs/api/v1/rooms/list-rooms to call the API interactively and browse results. Once you have the room ID, store it as WEBEX_SPACE_ID in your .env file.
Does Webex support Adaptive Cards like Microsoft Teams?
Yes. Webex supports Adaptive Cards through its 'attachments' API — the same card format used by Teams and Azure Bot Framework. Include the card JSON in the 'attachments' field of your message body with contentType 'application/vnd.microsoft.card.adaptive'. Webex renders Adaptive Cards in desktop and mobile clients, allowing interactive buttons, form inputs, and rich layouts in bot responses.
Is Webex free for developers?
Yes. Webex offers a free plan that includes team messaging, 1:1 and group video calls, and full API access. The free plan is more than sufficient for building and testing Bolt integrations. Paid plans ($14.50-$25/user/month) add unlimited meeting duration, larger meeting sizes (up to 1,000), cloud recording, and admin controls. Bot creation and API access are available on all plans including free.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation