Widget tab
Embed the ElevenLabs agent widget in a Microsoft Teams tab for click-to-talk.
Overview
Section titled “Overview”Host a small HTML page that loads the agent widget and surface it as a Teams tab. Users open the tab and talk to the agent in the Teams client — no phone number or telephony. This is the lightest-weight approach; use it for internal self-service assistants and demos.
The agent widget running in a Teams tab
How it works
Section titled “How it works”The widget is a web component. Teams renders a tab’s contentUrl inside a webview (iframe), so the widget runs exactly as it would on a website — including microphone capture, provided the page is allowed to embed in Teams and is granted media permission.
Widget embedded in a Teams tab
Requirements
Section titled “Requirements”- A public ElevenLabs agent with authentication disabled (Advanced tab of the agent settings). Widgets require this.
- An HTTPS host for a single static HTML file (Vercel, Netlify, Cloudflare Pages, Azure Static Web Apps, etc.).
- Permission in your tenant to upload a custom Teams app (Teams admin center → Manage apps → custom app upload), if you use the custom-tab option.
Step 1 — Create the widget page
Section titled “Step 1 — Create the widget page”Create agent-widget.html with the widget embed and your agent ID:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Voice Agent</title>
</head>
<body style="margin:0">
<elevenlabs-convai
agent-id="<replace-with-agent_7101k5zvyjhmfg983brhmhkd98n6>"
></elevenlabs-convai>
<script
src="https://unpkg.com/@elevenlabs/convai-widget-embed"
async
type="text/javascript"
></script>
</body>
</html>Deploy it to your HTTPS host and confirm it loads and the mic works in a normal browser first.
Step 2 — Add it to Teams
Section titled “Step 2 — Add it to Teams”You have two options, in increasing order of reliability for voice.
Option A — Website tab (quickest, may be link-only)
Section titled “Option A — Website tab (quickest, may be link-only)”In a chat or channel, + Add a tab → Website, paste your HTTPS URL, and save.
Option B — Custom tab app (recommended for voice)
Section titled “Option B — Custom tab app (recommended for voice)”A tiny custom Teams app declares the page as a static tab and requests media permission, which is what makes the microphone work reliably inside Teams.
Create the manifest
Create
manifest.json. Replaceyour-domain.comwith your host and set a unique GUID forid:manifest.json { "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.19/MicrosoftTeams.schema.json", "manifestVersion": "1.19", "version": "1.0.0", "id": "11111111-1111-1111-1111-111111111111", "developer": { "name": "ElevenLabs", "websiteUrl": "https://your-domain.com", "privacyUrl": "https://your-domain.com/privacy", "termsOfUseUrl": "https://your-domain.com/terms" }, "name": { "short": "Voice Agent", "full": "ElevenLabs Voice Agent" }, "description": { "short": "ElevenLabs voice agent", "full": "Embedded ElevenLabs voice agent" }, "icons": { "outline": "outline.png", "color": "color.png" }, "accentColor": "#000000", "staticTabs": [ { "entityId": "voice-agent", "name": "Voice Agent", "contentUrl": "https://your-domain.com/agent-widget.html", "websiteUrl": "https://your-domain.com/agent-widget.html", "scopes": ["personal"] } ], "devicePermissions": ["media"], "validDomains": ["your-domain.com", "unpkg.com", "elevenlabs.io", "*.elevenlabs.io"] }The key fields for voice are
devicePermissions: ["media"](microphone) and listing every domain the page touches invalidDomains(unpkg.comfor the widget script,*.elevenlabs.iofor the agent).Package the app
Add a
color.png(192×192) andoutline.png(32×32, transparent) next to the manifest, then zip the manifest and the two icons at the root of the archive:Bash zip -j voice-agent.zip manifest.json color.png outline.pngUpload and open
In Teams: Apps → Manage your apps → Upload an app → Upload a custom app, select
voice-agent.zip, then open the Voice Agent tab and grant microphone access when prompted.If no prompt appears, open the tab’s dropdown and choose App permissions to grant microphone access manually:

Tab dropdown → App permissions
Step 3 — Allow Teams to embed the page
Section titled “Step 3 — Allow Teams to embed the page”Your host must permit Teams to iframe the page. If you control response headers, set:
Content-Security-Policy: frame-ancestors 'self' https://teams.microsoft.com https://*.teams.microsoft.com https://*.cloud.microsoft;If Teams keeps opening the page in a browser instead of embedding it, the page is being blocked from iframe embedding — fix the CSP / X-Frame-Options on your host.
Troubleshooting
Section titled “Troubleshooting”The tab opens the page in a browser instead of embedding it
The page is blocked from being iframed. Remove any X-Frame-Options: DENY/SAMEORIGIN and set the frame-ancestors CSP shown above to allow the Teams domains. The custom tab app (Option B) is also more reliable than the built-in Website tab.
The widget loads but the microphone doesn't work
This is the Teams webview permission layer. Use the custom tab app with "devicePermissions": ["media"], and grant the app microphone permission in Teams (tab dropdown → App permissions). Teams web and Teams desktop behave differently — test both. As a fallback, offer an “Open in browser” link.
The widget never appears
Confirm the agent is public with authentication disabled (agent Advanced settings), and that unpkg.com and *.elevenlabs.io are in the manifest validDomains.