Microsoft Teams
Connecting Microsoft Teams puts Ema inside the chat app your people already use. They send a direct message in Teams, Ema answers there, and no one has to open the Ema web app.
This page covers both connection scopes, both bot options, and everything a Microsoft 365 administrator needs to approve the integration.
Two ways to connect
Pick the scope first. It decides which Ema answers in Teams, and it changes where you do the setup.
| Workspace connection | AI Employee connection | |
|---|---|---|
| Who answers in Teams | Autopilot, which routes each question to the right AI Employee in your workspace | One specific AI Employee that you choose |
| Where you set it up | Workspace Management → App Connections | Integrations → Channels |
| How many per workspace | One Teams connection for the whole workspace | One per AI Employee |
| Bot options | Ema-provided bot, or your own Azure bot | Your own Azure bot |
| Who can set it up | system_admin | system_admin |
A workspace connection is the faster path and the one most customers want. You connect Teams once, and Autopilot decides which AI Employee handles each question. You do not connect each AI Employee separately.
Choose an AI Employee connection when one named AI Employee must own the conversation, for example a single finance assistant that should answer every message in that Teams app regardless of what is asked.
The two scopes can coexist. A workspace connection and an AI Employee connection are separate bots with separate app packages, so people in Teams see them as two different apps.
Choose a bot
Both scopes need a bot registered in Microsoft Entra ID. The question is who owns that registration.
| Ema-provided bot | Your own Azure bot | |
|---|---|---|
| Who owns the app registration | Ema | You, in your own Microsoft tenant |
| Setup effort | Approve a consent screen, then upload one package | Around 10 steps in the Azure portal, plus a credential handover |
| Credentials you hand over | None | Client ID, client secret, and directory (tenant) ID |
| Bot appears in Teams as | Ema | Any name you choose |
| Available for | Workspace connections | Workspace and AI Employee connections |
| Secret rotation | Ema handles it | You handle it, and you re-enter the new secret in Ema |
Use your own Azure bot when your security policy requires the bot registration to live under your own governance, when you need a custom name and icons in the Teams catalog, or when you are connecting a single AI Employee rather than the whole workspace.
Connect with the Ema-provided bot
This is the workspace connection. It takes two steps in Ema and one upload in the Teams admin center.
Before you start
- You need the
system_adminrole in Ema. - You need a Microsoft 365 account that can grant admin consent for your organization, normally Global Administrator or Privileged Role Administrator.
- You need access to the Teams admin center to upload a custom app.
Step 1: Start the connection
- In Ema, go to Workspace Management → App Connections.
- Under Channels, select Connect Microsoft Teams.
- Select Connect to use the Ema-provided bot. (Connect your own bot is the other path, covered below.)
Ema sends you to Microsoft's consent page.
Step 2: Approve the permissions
Sign in as a Microsoft 365 administrator and review the permission request. Ema asks for four delegated permissions and no application permissions:
| Permission | Type | Why Ema asks for it |
|---|---|---|
openid | Delegated | Identifies which Microsoft organization is consenting |
profile | Delegated | Reads basic profile information from the sign-in token |
offline_access | Delegated | Keeps the connection working without repeated sign-in |
User.Read | Delegated | Reads the signed-in user's own profile |
After you approve, Microsoft returns you to Ema and the connection is recorded against your Microsoft organization. Ema derives your Microsoft tenant ID from the token Microsoft returns, so no one can bind a different organization by editing a URL.
Step 3: Install the app package in Teams
Microsoft has no way for Ema to install an app into your Teams catalog on your behalf, so an administrator does this part by hand.
- On the App Connections tab, select Download Teams Bot Package. You get
Ema-Teams-Bot.zip. - In the Teams admin center, go to Teams apps → Manage apps and upload the zip as a custom app.
- In Teams, open Apps, find Ema under Built for your org, and add it.
Upload through the Teams admin center, not the Teams client. A client-side upload works for a quick test but is not picked up by app setup policies, so you cannot push it out to your organization.
Microsoft can take anywhere from a few minutes to about an hour to roll a newly uploaded app out to your organization's catalog. Ema does not appear in Teams search until that finishes. The delay is on Microsoft's side.
Step 4: Verify
Open a direct message with Ema in Teams and send a question. You should get a reply in the same chat.
The Ema-provided app package is scoped to personal chat, so Ema answers direct messages. It is not added to team channels or group chats.
Connect with your own Azure bot
Use this path when the bot registration must live in your own Microsoft tenant. The Azure work is the same for both connection scopes. An AI Employee connection needs extra single sign-on configuration, covered at the end of this section.
What you give Ema: the client ID, the client secret, and your directory (tenant) ID.
What Ema gives you: the messaging endpoint to paste into your bot.
Step 1: Create the Azure bot
- In the Azure portal, select Create a resource, search for Azure Bot, and select Create.
- Fill in the details:
- Bot handle: your bot's name.
- Subscription and Resource group: per your own Azure policy.
- Data residency: Global.
- Pricing tier: select Change plan and choose the free tier.
- Type of App: Single Tenant.
- Select Review and create. Deployment usually finishes in under five minutes.
Step 2: Enable the Teams channel
- Open the bot and go to Settings → Channels.
- Select Microsoft Teams under Available Channels, accept the terms, and select Apply.
Step 3: Note the identifiers and set the messaging endpoint
- Go to Settings → Configuration.
- Record the Microsoft App ID and the App Tenant ID. You need both.
- Set Messaging endpoint to the URL Ema gives you.
The messaging endpoint is:
https://app.ema.ai/api/v1/chat/channels/teams/webhook
Replace app.ema.ai with your own Ema URL if your workspace runs on a dedicated Ema environment. Ema also shows this URL in the app when you create the channel, so you can copy it from there.
Step 4: Create a client secret
- On the Configuration page, select Manage Password next to the Microsoft App ID. This opens Certificates & secrets.
- Select New client secret.
- Enter a description, for example
Ema-on-teams, and set Expires to 730 days. - Copy the secret Value immediately. Microsoft shows it once. You do not need the Secret ID.
Record the secret's expiry date. When it expires the bot stops replying in Teams, and the fix is to create a new secret and re-enter it in Ema.
Step 5: Give the credentials to Ema
For a workspace connection:
- Go to Workspace Management → App Connections.
- Select Connect Microsoft Teams, then Connect your own bot.
- Enter the Bot App ID, Bot App Secret, and Azure Tenant ID, then select Connect.
For an AI Employee connection:
- Go to Integrations → Channels and add a Microsoft Teams channel.
- Select the AI Employee the channel belongs to, and enter the same three values.
- Save. Ema shows the webhook URL to register as your bot's messaging endpoint.
Step 6: Build and upload the Teams app package
Create a manifest.json from the template below, replacing every <ClientId> with your Microsoft App ID:
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.19/MicrosoftTeams.schema.json",
"manifestVersion": "1.19",
"version": "1.0.0",
"id": "<ClientId>",
"developer": {
"name": "<Your organization>",
"websiteUrl": "https://www.ema.ai",
"privacyUrl": "https://www.ema.co/privacy-policy",
"termsOfUseUrl": "https://www.ema.co/privacy-policy"
},
"name": {
"short": "<Bot name>",
"full": "<Bot name>"
},
"description": {
"short": "<Short description>",
"full": "<Full description>"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"accentColor": "#FFFFFF",
"bots": [
{
"botId": "<ClientId>",
"scopes": ["personal"],
"isNotificationOnly": false,
"supportsFiles": false
}
],
"permissions": ["identity", "messageTeamMembers"],
"validDomains": [],
"webApplicationInfo": {
"id": "<ClientId>",
"resource": "api://botid-<ClientId>"
}
}
You also need two icons in the same folder: color.png (192x192) and outline.png (32x32, a white glyph on a transparent background).
Select manifest.json, color.png, and outline.png, compress them into a zip, then upload the zip in the Teams admin center under Teams apps → Manage apps.
Zip the three files directly, not the folder that contains them. Teams rejects a package whose manifest.json is inside a subfolder.
Additional setup for an AI Employee connection
An AI Employee connection reads the sender's profile from Microsoft Graph, so it needs Teams single sign-on configured on your app registration. A workspace connection does not: it reads the sender's name and email from the Teams conversation roster instead, which needs no extra consent and no single sign-on.
Complete these steps only for an AI Employee connection.
Add the redirect URI
In your app registration, select Authentication → Add a platform → Web, and add this redirect URI:
https://token.botframework.com/.auth/web/redirect
Leave the front-channel logout URL empty, and select both Access tokens and ID tokens.
Grant the Graph permissions
Select API permissions → Add a permission → Microsoft Graph → Delegated permissions, and add email, offline_access, openid, profile, and User.Read. Then select Grant admin consent for default directory.
If Grant admin consent is greyed out, your account cannot consent for the directory. Have a Global Administrator do it. Skipping this leaves the bot unable to read profiles, and it fails later rather than at setup time.
Expose the API
Select Expose an API, then set the Application ID URI to api://botid-<Microsoft App ID>.
Select Add a scope and fill it in:
| Field | Value |
|---|---|
| Scope name | access_as_user |
| Who can consent | Admins and users |
| Admin consent display name | Teams can access user's profile |
| Admin consent description | Teams can call the app's API as the current user |
| User consent display name | Teams can access your profile |
| User consent description | Teams can call the app's API as you |
| State | Enabled |
Then select Add a client application and authorize that scope for each of these Microsoft-owned client IDs, which are the Teams desktop, web, and mobile clients:
1fec8e78-bce4-4aaf-ab1b-5451cc387264
5e3ce6c0-2b1f-4285-8d4b-75ee78787346
8f947e5d-dd97-4fbe-9384-26878dd73a0a
Add the OAuth connection
Go back to the bot's Configuration page and select Add OAuth Connection Settings. Fill it in:
| Field | Value |
|---|---|
| Name | EmaTeamsSSO (exactly this) |
| Service Provider | Azure Active Directory V2 |
| Client ID | Your Microsoft App ID |
| Client secret | The secret value you created earlier |
| Token Exchange URL | api://botid-<Microsoft App ID> |
| Tenant ID | Your directory (tenant) ID, or common for a multi-tenant app |
| Scopes | openid profile User.Read |
Save, then use Test connection to confirm a token comes back.
The connection name must be exactly EmaTeamsSSO. Ema matches on this string, and any other name silently fails the sign-in exchange.
What your Microsoft administrator needs to know
Use this section for a security review. Everything here is what the integration actually does.
Permissions Ema requests
For the Ema-provided bot, admin consent grants four delegated Microsoft Graph permissions: openid, profile, offline_access, and User.Read. Ema requests no application permissions, so there is no tenant-wide directory read, no mailbox access, and no access to Teams message history. Ema pins this exact permission set on the consent request rather than requesting whatever the app registration happens to hold, so the granted set cannot widen later without a new consent.
For your own Azure bot, you own the registration and grant only what the steps above describe.
Where messages travel
| Direction | Endpoint | Purpose |
|---|---|---|
| Microsoft to Ema | https://app.ema.ai/api/v1/chat/channels/teams/webhook | Delivers messages a person sends to the bot |
| Ema to Microsoft | https://smba.trafficmanager.net and *.botframework.com | Sends replies through the Bot Connector service |
| Ema to Microsoft | https://login.microsoftonline.com | Acquires the bot's access token |
| Ema to Microsoft | https://login.botframework.com | Fetches Microsoft's public keys to verify inbound requests |
| Browser to Ema | https://app.ema.ai/api/v1/chat/channels/teams/connect/callback | Receives the admin consent result (Ema-provided bot only) |
Ema verifies every inbound request against Microsoft's published signing keys before acting on it, and checks that the request was issued for the specific bot registered on your connection. Ema only accepts replies addressed to Microsoft-owned service hosts.
Data handling
Message content is processed by Ema to produce a reply and is retained under your workspace's configured retention policy. See Security and compliance for retention, deletion, and residency, and PII and governance for how sensitive categories are masked before they reach a model or an external system.
File attachments sent in a Teams message are not read by Ema today. Only the message text reaches the AI Employee.
Manage the connection
The App Connections tab shows the current state of the Teams connection and lets you remove it.
Select Disconnect to stop Ema answering in Teams. The connection is deactivated rather than deleted, so reconnecting later does not need a fresh consent. Disconnecting does not remove the app from your Teams catalog. Remove it in the Teams admin center if you want it gone from your users' app list.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Ema does not appear in Teams search after upload | Microsoft is still rolling the app out to your catalog. Wait up to an hour. |
| The app uploaded but setup policies cannot find it | It was uploaded from the Teams client instead of the Teams admin center. Upload it again in the admin center. |
| Messages get no reply, own Azure bot | The messaging endpoint is wrong or missing on the Azure bot, or the client secret has expired. |
| Messages get no reply, Ema-provided bot | The connection was disconnected in Ema, or admin consent was never completed. |
| Replies arrive but the person sees less than expected | Their Teams email does not match an active member of the Ema workspace, so the conversation is running with the setup administrator's permissions. Add them as a workspace member. |
| Sign-in prompts loop, AI Employee connection | The OAuth connection is not named EmaTeamsSSO, or admin consent was not granted on the API permissions. |
| Connecting returns an error about the organization already being connected | That Microsoft organization is already bound to a different Ema workspace. Disconnect it there first. |
Related pages
- Embeddable Chat SDK for putting Ema on your own website instead.
- Autopilot for what answers a workspace-level Teams connection.
- Governance and permissions for the
system_adminrole.