Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with Microsoft Teams

Integrate Bolt.new with Microsoft Teams using two approaches: incoming webhooks for quick channel notifications (works immediately in Bolt's WebContainer, just POST JSON to a webhook URL), or the Microsoft Graph API for full message, channel, and meeting management (requires Azure AD app registration and deployment for OAuth). Start with incoming webhooks for fast results, then upgrade to Graph API for richer features.

What you'll learn

  • How to set up Teams incoming webhooks for channel notifications without Azure AD setup
  • How to send formatted Adaptive Cards to Teams channels from a Bolt app server route
  • How to register an Azure AD app and use the Microsoft Graph API to send messages
  • How to create Teams meeting links via the Microsoft Graph Calendar API
  • Why incoming webhooks work in Bolt's preview while OAuth flows and bots require deployment
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate17 min read20 minutes (incoming webhooks) or 45 minutes (Graph API)CommunicationApril 2026RapidDev Engineering Team
TL;DR

Integrate Bolt.new with Microsoft Teams using two approaches: incoming webhooks for quick channel notifications (works immediately in Bolt's WebContainer, just POST JSON to a webhook URL), or the Microsoft Graph API for full message, channel, and meeting management (requires Azure AD app registration and deployment for OAuth). Start with incoming webhooks for fast results, then upgrade to Graph API for richer features.

Connecting Bolt.new Apps to Microsoft Teams for Business Messaging

Microsoft Teams sits at the center of the Microsoft 365 ecosystem, meaning an integration with Teams often implies access to SharePoint documents, OneDrive files, Outlook calendar, and Azure Active Directory user management as well. The Microsoft Graph API is the unified gateway to all of these services — one API, one access token, multiple Microsoft services. This is both the power and the complexity of Teams integration compared to Slack: the setup requires an Azure AD app registration, which sounds intimidating but follows a clear step-by-step process.

For most Bolt apps, the fastest path to useful Teams integration is incoming webhooks. Microsoft Teams supports incoming webhook connectors that give you a URL you can POST JSON messages to from any server — no Azure setup, no OAuth, no token management. You create the webhook in the Teams channel settings in two minutes and get a URL. POST a JSON payload to that URL from your Next.js API route and the message appears in the channel. This works perfectly from Bolt's WebContainer because it's a standard outbound HTTPS call. Incoming webhooks are ideal for build notifications, form submission alerts, order notifications, and any scenario where your app needs to push information to a Teams channel.

For richer interactions — sending messages to specific one-on-one chats, reading channel history, scheduling Teams meetings, managing team membership — the Microsoft Graph API is necessary. This path requires registering an app in Azure Active Directory, configuring OAuth 2.0 permissions, and handling token acquisition. The OAuth redirect flow requires a deployed redirect URI, which means you need to deploy to Netlify or Vercel to test Graph API features that involve user login. Server-to-server (client credentials) Graph API flows work without a redirect URI and can be tested in the Bolt preview.

Integration method

Bolt Chat + API Route

Teams integration has two distinct paths depending on complexity. For channel notifications — sending alerts, summaries, or updates to a Teams channel — use incoming webhooks: create a webhook connector in Teams, copy the URL, and POST a JSON card to it from any server-side route. This requires no Azure setup and works immediately in Bolt's WebContainer. For full Graph API access (sending messages to specific chats, scheduling meetings, reading team membership) you need an Azure AD app registration, OAuth 2.0 authentication, and a deployed URL for the OAuth redirect flow. Webhooks requiring Teams to call your app (bots, event subscriptions) cannot be reached during Bolt development and need deployment.

Prerequisites

  • A Microsoft Teams workspace where you have permission to add connectors to channels (Team owner or admin role)
  • For incoming webhooks only: access to a Teams channel's settings to add an Incoming Webhook connector
  • For Microsoft Graph API: an Azure account (free tier works) to register an Azure AD application
  • A Next.js project in Bolt.new — prompt 'Create a Next.js app' if starting fresh
  • For OAuth-based Graph API calls: a deployed app on Netlify or Vercel with a public HTTPS URL for the OAuth redirect URI

Step-by-step guide

1

Set up a Teams incoming webhook for channel notifications

Teams incoming webhooks are the fastest way to send messages to a Teams channel from Bolt. No Azure registration, no OAuth, no tokens — just a URL that accepts JSON POST requests. The setup takes two minutes. Open Microsoft Teams and navigate to the channel where you want to receive notifications. Click the three-dot menu next to the channel name → Connectors (or in newer Teams UI: More options → Manage channel → Connectors). Search for 'Incoming Webhook' in the connector list, click Add, then click Add again on the confirmation screen. Give the webhook a name (e.g., 'Bolt App Notifications') and optionally upload an icon image. Click Create. Teams will show you a long HTTPS URL — this is your webhook endpoint. Copy it immediately. The URL contains an embedded authentication token and is unique to this channel. Store it as TEAMS_WEBHOOK_URL in your Bolt project's .env.local file. Keep this URL private — anyone with this URL can post to your channel. To send a message, POST a JSON payload to this URL. Teams accepts two message formats: simple MessageCard (JSON with @type: 'MessageCard') or the newer Adaptive Card format. Adaptive Cards are preferred for rich, structured messages — they support buttons, images, tables, and interactive elements. For simple text notifications, MessageCard is faster to implement. The POST request goes directly from your server-side Next.js route to Teams' servers, which makes it work perfectly from Bolt's WebContainer — it's a standard outbound HTTPS call with no CORS concerns.

Bolt.new Prompt

Set up Microsoft Teams incoming webhook integration in my Next.js app. Add TEAMS_WEBHOOK_URL to .env.local as a placeholder. Create app/api/teams/notify/route.ts that accepts a POST with title, message, severity (info/warning/critical), and optional actionUrl plus actionLabel. Send an Adaptive Card to the Teams webhook with color-coded based on severity. Return success or error.

Paste this in Bolt.new chat

app/api/teams/notify/route.ts
1// .env.local
2TEAMS_WEBHOOK_URL=https://your-tenant.webhook.office.com/webhookb2/...
3
4// app/api/teams/notify/route.ts
5import { NextRequest, NextResponse } from 'next/server';
6
7const SEVERITY_COLORS: Record<string, string> = {
8 info: '0078D4', // Teams blue
9 warning: 'FFB900', // amber
10 critical: 'D13438', // red
11};
12
13export async function POST(request: NextRequest) {
14 const { title, message, severity = 'info', actionUrl, actionLabel } = await request.json();
15
16 const webhookUrl = process.env.TEAMS_WEBHOOK_URL!;
17 const color = SEVERITY_COLORS[severity] ?? SEVERITY_COLORS.info;
18
19 // Adaptive Card format (current Teams standard)
20 const card = {
21 type: 'message',
22 attachments: [
23 {
24 contentType: 'application/vnd.microsoft.card.adaptive',
25 content: {
26 $schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
27 type: 'AdaptiveCard',
28 version: '1.4',
29 body: [
30 {
31 type: 'TextBlock',
32 text: title,
33 weight: 'Bolder',
34 size: 'Medium',
35 color: severity === 'critical' ? 'Attention' : severity === 'warning' ? 'Warning' : 'Default',
36 },
37 {
38 type: 'TextBlock',
39 text: message,
40 wrap: true,
41 color: 'Default',
42 },
43 ],
44 ...(actionUrl && actionLabel
45 ? {
46 actions: [
47 {
48 type: 'Action.OpenUrl',
49 title: actionLabel,
50 url: actionUrl,
51 },
52 ],
53 }
54 : {}),
55 },
56 },
57 ],
58 };
59
60 const response = await fetch(webhookUrl, {
61 method: 'POST',
62 headers: { 'Content-Type': 'application/json' },
63 body: JSON.stringify(card),
64 });
65
66 if (!response.ok) {
67 const errorText = await response.text();
68 return NextResponse.json({ error: errorText }, { status: response.status });
69 }
70
71 return NextResponse.json({ success: true });
72}

Pro tip: Teams incoming webhooks have a rate limit of approximately 4 messages per second per webhook URL. For notification-heavy applications, batch related alerts into a single Adaptive Card with multiple body sections rather than sending separate requests.

Expected result: POST /api/teams/notify with a title and message sends a formatted Adaptive Card to your Teams channel. The card appears within 1–2 seconds with the correct color coding based on severity.

2

Register an Azure AD app for Microsoft Graph API access

For Graph API access beyond incoming webhooks — sending messages to specific chats, creating meetings, reading team membership — you need to register an Azure AD application. Go to portal.azure.com and sign in with your Microsoft account. In the search bar, type 'App registrations' and click the result. Click New registration. Give the app a name like 'Bolt Teams Integration'. Under Supported account types, choose 'Accounts in this organizational directory only' if you're only integrating with your own tenant, or 'Accounts in any organizational directory' for multi-tenant apps. For the Redirect URI, choose 'Web' and enter https://localhost:3000/api/auth/callback for development (you'll add your deployed URL later). Click Register. You will see the Overview page with your Application (client) ID and Directory (tenant) ID — copy both. Next, create a client secret: click Certificates & secrets → New client secret. Give it a description, choose an expiry (24 months is typical), and click Add. Copy the Value immediately — it's shown only once. Now configure API permissions. Click API permissions → Add a permission → Microsoft Graph. For sending messages to channels and creating meetings, you need: ChannelMessage.Send (Delegated, for user-context messages) and OnlineMeetings.ReadWrite (Delegated, for meeting creation). For server-to-server operations without user login, add Application permissions instead: ChannelMessage.Send (Application) requires admin consent. Click Add permissions, then Grant admin consent if you have admin rights. Store all three values (client ID, client secret, tenant ID) in .env.local. These credentials are sensitive — keep them server-side only.

Bolt.new Prompt

Add Microsoft Graph API configuration to my Next.js app for Teams integration. Add AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID to .env.local as placeholders. Create lib/graph.ts with a getGraphToken function that fetches a client credentials OAuth token from Microsoft's token endpoint (for app-level access without user login). Return the access_token for use in Graph API calls.

Paste this in Bolt.new chat

lib/graph.ts
1// .env.local (add to existing file)
2AZURE_CLIENT_ID=your_application_client_id
3AZURE_CLIENT_SECRET=your_client_secret_value
4AZURE_TENANT_ID=your_directory_tenant_id
5
6// lib/graph.ts
7let cachedToken: { token: string; expiresAt: number } | null = null;
8
9export async function getGraphToken(): Promise<string> {
10 if (cachedToken && Date.now() < cachedToken.expiresAt - 60_000) {
11 return cachedToken.token;
12 }
13
14 const tenantId = process.env.AZURE_TENANT_ID!;
15 const clientId = process.env.AZURE_CLIENT_ID!;
16 const clientSecret = process.env.AZURE_CLIENT_SECRET!;
17
18 const params = new URLSearchParams({
19 grant_type: 'client_credentials',
20 client_id: clientId,
21 client_secret: clientSecret,
22 scope: 'https://graph.microsoft.com/.default',
23 });
24
25 const response = await fetch(
26 `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
27 { method: 'POST', body: params }
28 );
29
30 if (!response.ok) {
31 throw new Error(`Graph token request failed: ${response.status}`);
32 }
33
34 const data = await response.json();
35 cachedToken = {
36 token: data.access_token,
37 expiresAt: Date.now() + data.expires_in * 1000,
38 };
39 return cachedToken.token;
40}
41
42export async function graphFetch(
43 endpoint: string,
44 method = 'GET',
45 body?: unknown
46): Promise<Response> {
47 const token = await getGraphToken();
48 return fetch(`https://graph.microsoft.com/v1.0${endpoint}`, {
49 method,
50 headers: {
51 Authorization: `Bearer ${token}`,
52 'Content-Type': 'application/json',
53 },
54 ...(body ? { body: JSON.stringify(body) } : {}),
55 });
56}

Pro tip: The client_credentials grant type used here authenticates as the application itself (not a specific user). This works for sending channel messages and creating meetings without requiring any user to log in. It requires admin consent for most Graph permissions — your Azure AD admin must approve the permissions before the token will work.

Expected result: The getGraphToken function successfully fetches a Microsoft Graph access token using client credentials. You can verify by calling GET /me on the Graph API — note that /me requires delegated auth; use /organization for app-level verification.

3

Create Teams meetings via the Microsoft Graph API

With the Graph API token utility in place, you can create online meeting links programmatically. The Microsoft Graph endpoint for creating Teams meetings is POST /users/{userId}/onlineMeetings. This creates a meeting and returns a joinWebUrl that any participant can click to join the Teams meeting — no calendar event required. The request body requires at least a startDateTime and endDateTime in ISO 8601 format. You can also set the subject (meeting title), participants (attendee email addresses), and settings like allowAttendeeToEnableCamera or recordAutomatically. The response includes joinWebUrl (the link for attendees), joinMeetingIdSettings, and organizer details. Note: for Application-level token (client credentials, no user login), the POST must use /users/{userId}/onlineMeetings where userId is the Object ID of a real user in your Azure AD tenant — not /me, which requires delegated auth. Find the user's Object ID in Azure Portal → Users → click the user → Object ID. Store this as AZURE_MEETING_HOST_USER_ID in your env variables. The client_credentials token approach works from Bolt's WebContainer — it's an outbound HTTPS call to Microsoft's Graph API. If you need meetings to appear in specific users' calendars or require delegated user permissions, that requires an OAuth user flow with a redirect URI, which needs a deployed URL. For simple 'generate a Teams join link' functionality, client credentials work fine in development.

Bolt.new Prompt

Add Teams meeting creation to my app. Create app/api/teams/meetings/create/route.ts that accepts a POST with subject, startTime (ISO 8601), durationMinutes, and optional attendeeEmails array. Call the Microsoft Graph API to create a Teams online meeting using the user ID from AZURE_MEETING_HOST_USER_ID env var. Return the joinWebUrl, meetingId, and startDateTime.

Paste this in Bolt.new chat

app/api/teams/meetings/create/route.ts
1// app/api/teams/meetings/create/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { graphFetch } from '@/lib/graph';
4
5export async function POST(request: NextRequest) {
6 const { subject, startTime, durationMinutes = 60, attendeeEmails = [] } = await request.json();
7
8 if (!subject || !startTime) {
9 return NextResponse.json(
10 { error: 'subject and startTime are required' },
11 { status: 400 }
12 );
13 }
14
15 const userId = process.env.AZURE_MEETING_HOST_USER_ID!;
16 const start = new Date(startTime);
17 const end = new Date(start.getTime() + durationMinutes * 60_000);
18
19 const body = {
20 subject,
21 startDateTime: start.toISOString(),
22 endDateTime: end.toISOString(),
23 ...(attendeeEmails.length > 0
24 ? {
25 participants: {
26 attendees: attendeeEmails.map((email: string) => ({
27 upn: email,
28 role: 'attendee',
29 })),
30 },
31 }
32 : {}),
33 };
34
35 const response = await graphFetch(`/users/${userId}/onlineMeetings`, 'POST', body);
36
37 if (!response.ok) {
38 const error = await response.json();
39 return NextResponse.json({ error }, { status: response.status });
40 }
41
42 const meeting = await response.json();
43 return NextResponse.json({
44 joinWebUrl: meeting.joinWebUrl,
45 meetingId: meeting.id,
46 startDateTime: meeting.startDateTime,
47 subject: meeting.subject,
48 });
49}

Pro tip: The joinWebUrl returned by the Graph API works for anyone — they can join in a browser without installing Teams. Share this URL directly with attendees instead of requiring them to have Teams installed.

Expected result: POST /api/teams/meetings/create returns a Teams meeting joinWebUrl that you can test by opening in a browser. The meeting link is active immediately and does not expire until the meeting end time.

4

Deploy and test the full integration

Incoming webhook notifications work in Bolt's WebContainer preview and can be tested immediately — send a test notification from the Bolt UI and verify it appears in your Teams channel. The Graph API calls (meeting creation, channel messaging) also work in the preview as long as you're using client credentials (application-level auth), not user-delegated OAuth. For features that require user login — accessing the authenticated user's calendar, sending messages as a specific user, or reading personal chat history — you need a delegated OAuth flow. This requires a publicly accessible redirect URI, which means you must deploy first. Add your deployed URL as a redirect URI in your Azure AD app registration (portal.azure.com → App registrations → your app → Authentication → Add URI). Use a URL like https://your-app.netlify.app/api/auth/callback. When deploying to Netlify or Vercel, add all Azure AD environment variables to the hosting platform's environment settings. In Netlify: Site settings → Environment variables. In Vercel: Project settings → Environment variables. Add TEAMS_WEBHOOK_URL, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID, and AZURE_MEETING_HOST_USER_ID. After deployment, verify both integration paths work: send a test notification through the webhook endpoint and confirm it appears in Teams, then create a test meeting and confirm the joinWebUrl opens a valid Teams meeting. For webhook subscriptions (receiving events from Microsoft Graph when Teams activity occurs), register your subscription endpoint in the Graph API after deployment — the subscription endpoint must be publicly accessible.

Bolt.new Prompt

Add a Teams integration test page to my app. Create a /teams-test page with three sections: (1) Send Notification form with fields for title, message, and severity that calls /api/teams/notify, (2) Create Meeting form with subject, date/time, and duration that calls /api/teams/meetings/create and displays the returned joinWebUrl, (3) Status panel showing whether the Teams webhook URL and Azure credentials are configured (check env vars are non-empty, don't expose values).

Paste this in Bolt.new chat

Pro tip: Add your deployed production URL to Azure AD's Redirect URIs before testing OAuth flows. You can have multiple redirect URIs — add both http://localhost:3000/api/auth/callback (for local development) and your production URL (for deployed testing).

Expected result: The Teams test page shows all three integration components. Sending a notification posts a card to your Teams channel. Creating a meeting returns a valid joinWebUrl. Both operations confirm the integration is working correctly.

Common use cases

Channel notification system for app events

Send real-time notifications to a Teams channel when important events happen in your Bolt app: new user signups, form submissions, payment completions, or error alerts. Use formatted Adaptive Cards for rich notifications that include buttons, images, and structured data — not just plain text messages.

Bolt.new Prompt

Create a /api/teams/notify route that sends a formatted Adaptive Card to a Teams channel via an incoming webhook. The card should have a title, a description field, a severity badge (Info/Warning/Critical), and a 'View Details' button that links to a URL. Test it by sending a sample notification from the UI.

Copy this prompt to try it in Bolt.new

Teams meeting scheduler from a Bolt booking form

Build a meeting booking form in your Bolt app that creates a Teams meeting link using the Microsoft Graph Calendar API. When a user fills out the form with date, time, and attendee emails, your app creates a calendar event with a Teams meeting link and emails the join URL to all attendees.

Bolt.new Prompt

Create a meeting scheduler form with fields for meeting topic, date/time, duration, and attendee email addresses. When submitted, call /api/teams/meetings/create to create a Teams meeting via the Microsoft Graph API. Display the returned Teams meeting link as a button the user can copy.

Copy this prompt to try it in Bolt.new

Deployment or CI/CD status notifications

Integrate your Bolt app's deployment pipeline with a Teams channel so that build completions, failed tests, or production deployments automatically post a status card to the engineering team's channel. The incoming webhook approach is ideal — no Azure setup required, and the POST call works from any CI/CD system.

Bolt.new Prompt

Create a /api/teams/deploy-status route that accepts a POST with project name, status (success/failed/in-progress), deployment URL, and commit message. Send an Adaptive Card to the Teams webhook URL with color-coded status (green for success, red for failed) and a 'View Deployment' link.

Copy this prompt to try it in Bolt.new

Troubleshooting

Incoming webhook POST returns '400 Bad Request' with '"Summary" or "Text" property is required'

Cause: The Adaptive Card payload is missing required fields, or you're using the legacy MessageCard format incorrectly. Teams incoming webhooks require either a summary field at the top level, or for Adaptive Cards, the outer message wrapper must have a type: 'message' field.

Solution: Add a summary field to your top-level JSON payload: { type: 'message', summary: 'Notification from Bolt', attachments: [...] }. The summary is used in Teams push notifications when the channel is not open. Without it, Teams rejects the payload.

typescript
1// Add summary to the top-level payload
2const card = {
3 type: 'message',
4 summary: title, // Required for Teams push notifications
5 attachments: [{ contentType: '...', content: { ... } }],
6};

Graph API returns 401 with 'InvalidAuthenticationToken' even with a freshly generated token

Cause: The client credentials token is being used for a delegated-only API endpoint (one that requires a user context, like /me or /users/{id}/messages), or the Azure AD app's required permissions have not been granted admin consent.

Solution: In Azure Portal → App registrations → your app → API permissions, check that all permissions show 'Granted for {tenant}' in the Status column. If they show 'Not granted', click Grant admin consent at the top of the permissions page. You must be an Azure AD admin to grant consent. For delegated-only endpoints, use user-delegated OAuth instead of client credentials.

Teams meeting creation returns 403 Forbidden with 'Insufficient privileges'

Cause: The Azure AD app does not have the OnlineMeetings.ReadWrite application permission, or admin consent has not been granted for that permission.

Solution: Go to Azure Portal → App registrations → your app → API permissions. Verify OnlineMeetings.ReadWrite is listed as an Application permission (not Delegated). If it's missing, add it: Add a permission → Microsoft Graph → Application permissions → search OnlineMeetings → check OnlineMeetings.ReadWrite → Add. Then click Grant admin consent. Token changes take effect immediately — no need to rotate credentials.

OAuth redirect flow fails with 'redirect_uri_mismatch' during user login

Cause: The redirect URI in the OAuth authorization request does not exactly match any registered redirect URI in the Azure AD app registration. This is a common issue when using localhost during development but the Azure app only has the production URL registered.

Solution: Add all redirect URIs you use to your Azure AD app: portal.azure.com → App registrations → your app → Authentication → Add URI. Add both http://localhost:3000/api/auth/callback (for Bolt development) and https://your-deployed-app.netlify.app/api/auth/callback (for production). The URI must match character-for-character, including the trailing slash if present.

Best practices

  • Start with incoming webhooks for channel notifications — they require no Azure setup and work immediately in Bolt's WebContainer preview. Upgrade to Graph API only when you need features webhooks cannot provide (user-specific messages, meeting creation, reading team data).
  • Store TEAMS_WEBHOOK_URL, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID as server-side environment variables only — never use NEXT_PUBLIC_ prefix on any Teams or Azure credentials as they would be exposed in the client bundle.
  • Cache the Microsoft Graph access token with its expiry time — tokens are valid for 3600 seconds and requesting a new token on every API call wastes latency and can hit token endpoint rate limits.
  • Use client credentials (application-level auth) for server-to-server operations like meeting creation and channel notifications — this avoids the complexity of OAuth user flows and does not require users to authorize the integration.
  • Test incoming webhook notifications fully in Bolt's WebContainer preview before deploying — webhook POST calls are outbound HTTP requests that work without a public URL. Only deploy when you need user OAuth flows or Graph webhook subscriptions (event listening).
  • Rotate Azure AD client secrets before they expire (Azure shows expiry dates in Certificates & secrets) — an expired secret causes all Graph API calls to fail with 401. Set a calendar reminder 30 days before expiry.
  • Use Adaptive Cards instead of the legacy MessageCard format for Teams notifications — Microsoft has deprecated MessageCard and Adaptive Cards provide much richer formatting with tables, buttons, images, and interactive elements supported across all Teams clients.

Alternatives

Frequently asked questions

Can I send Teams notifications in Bolt's development preview without deploying?

Yes for two scenarios: incoming webhook notifications (POST JSON to the webhook URL) and Microsoft Graph API calls using client credentials (application-level auth). Both are outbound HTTPS requests that work from Bolt's WebContainer. The scenarios that require deployment are: user OAuth flows (users logging into your app via Microsoft), Graph webhook subscriptions (receiving events from Microsoft Graph), and Teams bots that require Microsoft to call your server.

What is the difference between Teams incoming webhooks and the Microsoft Graph API?

Incoming webhooks are one-way: your app can post messages to a Teams channel by sending a JSON POST to a webhook URL — no authentication setup, no Azure app, instant to configure. The Graph API is bidirectional and more powerful: you can send messages, read channel history, create meetings, manage team membership, and access Microsoft 365 data. Graph API requires Azure AD app registration and OAuth authentication. Use incoming webhooks for simple notifications, Graph API for interactive features.

Does Bolt.new have a native Microsoft Teams integration?

No. Microsoft Teams is not one of Bolt's native connectors. You build the integration manually using the patterns in this guide — either incoming webhooks for channel notifications or Microsoft Graph API routes for full Teams management. Bolt's AI can generate most of the boilerplate when you describe what messaging features you need.

Can I build a Teams bot with Bolt.new?

Yes, but with a key constraint: Teams bots require Microsoft to send messages to your server (bot framework callbacks), which means your bot endpoint must be publicly accessible. During Bolt development, the WebContainer has no public URL, so you cannot receive bot framework callbacks in preview. You need to deploy your app first, then register the bot endpoint URL in Azure. Once deployed, building a Teams bot that responds to mentions and slash commands is straightforward using the Bot Framework SDK.

Why does my Azure AD client credentials token not work for Teams Graph API calls?

Most Teams-related Graph API permissions require explicit admin consent. After adding permissions in Azure Portal, you must click the 'Grant admin consent for {tenant}' button — a tenant admin must approve the permissions before the token can access those resources. Also verify you added Application permissions (not Delegated) for server-to-server use — Delegated permissions require a user to be signed in. Check the Status column in API permissions to confirm consent is granted.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.