Meeting apps APIs

The meeting extensibility provides APIs to enhance meeting experience. You can perform the following with help of the listed APIs:

  • Build apps or integrate existing apps within meeting lifecycle.
  • Use APIs to make your app aware of meeting.
  • Select required APIs to improve the meeting experience.

Note

Use the Microsoft Teams JavaScript client library (TeamsJS) (Version: 1.10 and later) for single sign-on (SSO) to work in meeting side panel.

The following table provides a list of APIs available across the Microsoft Teams JavaScript library and Microsoft Bot Framework SDKs:

Method Description Source
Get user context Get contextual information to display relevant content in a Microsoft Teams tab. TeamsJS library
Get participant Fetch participant information by meeting ID and participant ID. Microsoft Bot Framework SDK
Send in-meeting notification Provides meeting signals using the existing conversation notification API for user-bot chat and allows the bot to notify user action that shows an in-meeting notification. Microsoft Bot Framework SDK
Get meeting details Get a meeting's static metadata. Microsoft Bot Framework SDK
Send real-time captions Send real-time captions to an ongoing meeting. TeamsJS library
Share app content to stage Share specific parts of the app to meeting stage from the app side panel in a meeting. TeamsJS library
Receive real-time Teams meeting events Receive real-time meeting events, such as meeting start and end or participant join and leave. Microsoft Bot Framework SDK
Get incoming audio state Allows an app to get the incoming audio state setting for the meeting user. TeamsJS library
Toggle incoming audio Allows an app to toggle the incoming audio state setting for the meeting user from mute to unmute or vice-versa. TeamsJS library

Get user context API

Important

  • By default, the new Teams client supports light theme for apps in Teams meetings. When the app.theme property in getContext API returns the default value, Teams client is in light theme.
  • Earlier version of Teams clients only support Dark and Contrast theme for apps in Teams meetings

To identify and retrieve contextual information for your tab content, see get context for your Teams tab. meetingId is used by a tab running in the meeting context and is added for the response payload.

Examples

The following are the TeamsJS v2 responses for Get user context API based on meeting type, user type, and call type:

  • Meeting type

    The following is a JSON payload response for a channel meeting for in-tenant users:

    {
        "app": {
        "locale": "en-us",
        "sessionId": "ff47ec00-e6a7-4dc1-a6ae-f44110f50c94",
        "theme": "default",
        "iconPositionVertical": 0,
        "osLocaleInfo": {
          "platform": "windows",
          "regionalFormat": "en-in",
          "shortDate": "dd-MM-yyyy",
          "longDate": "dd MMMM yyyy",
          "shortTime": "HH:mm",
          "longTime": "HH:mm:ss"
        },
        "parentMessageId": "1678109354022",
        "userClickTime": 1678109521159,
        "userFileOpenPreference": "inline",
        "host": {
          "name": "Teams",
          "clientType": "desktop",
          "sessionId": "c3c3c0a0-f7a1-b070-6b89-c8cd1f380042",
          "ringId": "ring1"
        },
        "appLaunchId": "7346ae66-5cac-47f9-8a0d-1228dac474cb"
        },
        "page": {
        "id": "Test",
        "frameContext": "sidePanel",
        "subPageId": "",
            "isFullScreen": false,
            "isMultiWindow": true,
            "sourceOrigin": ""
           },
           "user": {
            "id": "57efa5f3-273c-47e2-a871-4879e5d849cf",
            "displayName": "",
            "isCallingAllowed": undefined,
            "isPSTNCallingAllowed": undefined,
            "licenseType": "Unknown",
            "loginHint": "user@microsoft.com",
            "userPrincipalName": "user@microsoft.com",
            "tenant": {
             "id": "72f988bf-86f1-41af-91ab-2d7cd011db47",
             "teamsSku": "enterprise"
            }
           },
           "channel": {
            "id": "19:49683807ffce4318ad6d6d7a24dbde45@thread.tacv2",
            "displayName": undefined,
            "relativeUrl": undefined,
            "membershipType": undefined,
            "defaultOneNoteSectionId": undefined,
            "ownerGroupId": undefined,
            "ownerTenantId": undefined
           },
           "chat": {
            "id": "19:49683807ffce4318ad6d6d7a24dbde45@thread.tacv2"
           },
           "meeting": {
            "id": "MCMxOTo0OTY4MzgwN2ZmY2U0MzE4YWQ2ZDZkN2EyNGRiZGU0NUB0aHJlYWQudGFjdjIjMTY3ODEwOTM1NDAyMg=="
           },
           "sharepoint": undefined,
           "team": {
            "internalId": "19:b34aeec3f8e54240a5c283e86bfc4878@thread.tacv2",
            "displayName": undefined,
            "type": undefined,
            "groupId": undefined,
            "templateId": undefined,
            "isArchived": undefined,
            "userRole": 1
           },
           "sharePointSite": {
            "teamSiteUrl": "",
            "teamSiteDomain": "microsoft.sharepoint.com",
            "teamSitePath": "",
            "teamSiteId": "",
            "mySitePath": undefined,
            "mySiteDomain": undefined
           }
          }
    
  • User type

    The following is a JSON payload response in a scheduled private meeting for a guest user:

      {
            "app": {
             "locale": "en-us",
             "sessionId": "268beeb4-a52d-4ba8-b1c8-8b9f0b9b3492",
             "theme": "default",
             "iconPositionVertical": 23,
             "osLocaleInfo": {
              "platform": "windows",
              "regionalFormat": "en-in",
              "longDate": "dd MMMM yyyy",
              "shortDate": "dd-MM-yyyy",
              "longTime": "HH:mm:ss",
              "shortTime": "HH:mm"
             },
             "parentMessageId": "",
             "userClickTime": 1678023265131,
             "userFileOpenPreference": "inline",
             "host": {
              "name": "Teams",
              "clientType": "desktop",
              "sessionId": "967c980b-1e41-a2cd-eac0-a4bff8f73ce7",
              "ringId": "ring1"
             },
             "appLaunchId": "c35c4496-f28c-4107-8e6c-2dba09fb881a"
            },
            "page": {
             "id": "Test",
             "frameContext": "content",
             "subPageId": "",
             "isFullScreen": false,
             "isMultiWindow": false,
             "sourceOrigin": NULL
            },
            "user": {
             "id": "57efa5f3-273c-47e2-a871-4879e5d849cf",
             "displayName": undefined,
             "isCallingAllowed": undefined,
             "isPSTNCallingAllowed": undefined,
             "licenseType": "Unknown",
             "loginHint": "user@microsoft.com",
             "userPrincipalName": "user@microsoft.com",
             "tenant": {
              "id": "72f988bf-86f1-41af-91ab-2d7cd011db47",
              "teamsSku": "enterprise"
             }
            },
            "channel": undefined,
            "chat": {
             "id": "19:meeting_YmU5NWM3NGEtZjMyMi00ZDg4LTk4OGUtMjUzMGJkZjRhMDhm@thread.v2"
            },
            "meeting": {
             "id": "MCMxOTptZWV0aW5nX1ltVTVOV00zTkdFdFpqTXlNaTAwWkRnNExUazRPR1V0TWpVek1HSmtaalJoTURobUB0aHJlYWQudjIjMA=="
            },
            "sharepoint": undefined,
            "team": undefined,
            "sharePointSite": {
             "teamSiteUrl": "",
             "teamSiteDomain": "microsoft.sharepoint.com",
             "teamSitePath": "",
             "teamSiteId": undefined,
             "mySitePath": "/personal/user_microsoft_com",
             "mySiteDomain": "microsoft-my.sharepoint.com"
            }
      }
    
    
  • Call type

    The following is a JSON payload response for a one-on-one call for an in-tenant user:

          {
           "app": {
            "locale": "en-us",
            "sessionId": "1b3dc47e-f6ae-4fe2-8ed6-844a505f3186",
            "theme": "dark",
            "iconPositionVertical": null,
            "osLocaleInfo": {
             "platform": "windows",
             "regionalFormat": "en-in",
             "shortDate": "dd-MM-yyyy",
             "longDate": "dd MMMM yyyy",
             "shortTime": "HH:mm",
             "longTime": "HH:mm:ss"
            },
            "parentMessageId": "",
            "userClickTime": 1678088052473,
            "userFileOpenPreference": undefined,
            "host": {
             "name": "Teams",
             "clientType": "desktop",
             "sessionId": "",
             "ringId": "general"
            },
            "appLaunchId": undefined
           },
           "page": {
            "id": "Test",
            "frameContext": "sidePanel",
            "subPageId": "",
            "isFullScreen": undefined,
            "isMultiWindow": true,
            "sourceOrigin": ""
           },
           "user": {
            "id": "e652dd92-dd63-4fcc-b5b2-2005681e8e9f",
            "displayName": undefined,
            "isCallingAllowed": undefined,
            "isPSTNCallingAllowed": undefined,
            "licenseType": "Unknown",
            "loginHint": "user@microsoft.com",
            "userPrincipalName": "user@microsoft.com",
            "tenant": {
             "id": "aa923623-ae61-49ee-b401-81f414b6ad5a",
             "teamsSku": "unknown"
            }
           },
           "channel": undefined,
           "chat": {
            "id": "19:a74d8489-4455-4670-9581-7b38a8017c58_e652dd92-dd63-4fcc-b5b2-2005681e8e9f@unq.gbl.spaces"
           },
           "meeting": {
            "id": "MCMxOTphNzRkODQ4OS00NDU1LTQ2NzAtOTU4MS03YjM4YTgwMTdjNThfZTY1MmRkOTItZGQ2My00ZmNjLWI1YjItMjAwNTY4MWU4ZTlmQHVucS5nYmwuc3BhY2VzIzA="
           },
           "sharepoint": undefined,
           "team": undefined,
           "sharePointSite": {
            "teamSiteUrl": undefined,
            "teamSiteDomain": "microsoft.sharepoint.com",
            "teamSitePath": undefined,
            "teamSiteId": undefined,
            "mySitePath": undefined,
            "mySiteDomain": undefined
           }
          }
    
    

Get participant API

The GetParticipant API must have a bot registration and ID to generate auth tokens. For more information, see bot registration and ID.

Note

  • The user type isn't included in the getParticipantRole API.
  • Do not cache participant roles since the meeting organizer can change the roles any time.
  • The GetParticipant API is only supported for distributions lists or rosters with less than 350 participants.

Query parameters

Tip

Get participant IDs and tenant IDs from the tab SSO authentication.

The Meeting API must have meetingId, participantId, and tenantId as URL parameters. The parameters are available as part of the Microsoft Teams JavaScript client library (TeamsJS) library and bot activity.

The following table includes the query parameters:

Value Type Required Description
meetingId String Yes The meeting identifier is available through Bot Invoke and TeamsJS library.
participantId String Yes The participant ID is the user ID. It's available in Tab SSO, Bot Invoke, and TeamsJS library. It's recommended to get a participant ID from the Tab SSO.
tenantId String Yes The tenant ID is required for the tenant users. It's available in Tab SSO, Bot Invoke, and TeamsJS library. It's recommended to get a tenant ID from the Tab SSO.

Example

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
  // Gets the details for the given meeting participant. 
  // This only works in Teams meeting scoped conversations.
  TeamsMeetingParticipant participant = await TeamsInfo.GetMeetingParticipantAsync(turnContext, "yourMeetingId", "yourParticipantId", "yourParticipantTenantId").ConfigureAwait(false);
  TeamsChannelAccount member = participant.User;
  MeetingParticipantInfo meetingInfo = participant.Meeting;
  ConversationAccount conversation = participant.Conversation;

  // Sends a message activity to the sender of the incoming activity. 
  await turnContext.SendActivityAsync(MessageFactory.Text($"The participant role is: {meetingInfo.Role}"), cancellationToken);
}
Property name Description
user.id ID of the user.
user.aadObjectId Microsoft Entra object ID of the user.
user.name Name of the user.
user.givenName First Name of the user.
user.surname Last Name of the user.
user.email Mail ID of the user.
user.userPrincipalName UPN of the user.
user.tenantId Microsoft Entra tenant ID.
user.userRole Role of the user. For example, 'admin' or 'user'.
meeting.role The participant's role in the meeting. For example, 'Organizer' or 'Presenter' or 'Attendee'.
meeting.inMeeting The value indicating if the participant is in the meeting.
conversation.id The meeting chat ID.
conversation.isGroup Boolean indicating whether conversation has more than two participants.

Response codes

The following table provides the response codes:

Response code Description
403 Get participant information isn't shared with the app. If the app isn't installed in the meeting, it triggers the error response 403. If the admin disables or blocks the app during live site migration, it triggers the error response 403.
200 The participant information is successfully retrieved.
401 The app responds with an invalid token.
404 The meeting has either expired or participants aren't available.

Send an in-meeting notification

All users in a meeting receive the notifications sent through in-meeting notification payload. In-meeting notification payload triggers an in-meeting notification and enables you to provide meeting signals that are delivered using the existing conversation notification API for user-bot chat. You can send an in-meeting notification based on user action. The payload is available through Bot Services.

You can also send targeted in-meeting notification to a specific participant in a meeting. For more information, see Targeted in-meeting notification.

Note

  • When an in-meeting notification is invoked, the content is presented as a chat message.
  • You must invoke the submitTask() function to dismiss automatically after a user takes an action in the web view. This is a requirement for app submission. For more information, see Teams SDK task module.
  • If you want your app to support anonymous users, initial invoke request payload must rely on from.id request metadata in from object, not from.aadObjectId request metadata. from.id is the user ID and from.aadObjectId is the Microsoft Entra ID of the user. For more information, see using task modules in tabs and create and send the task module.

Query parameter

The following table includes the query parameter:

Value Type Required Description
conversationId String Yes The conversation identifier is available as part of Bot Invoke.

Examples

Bot ID is declared in the manifest and the bot receives a result object.

Note

  • The completionBotId parameter of the externalResourceUrl is optional in the requested payload example.
  • The externalResourceUrl width and height parameters must be in pixels. For more information, see design guidelines.
  • The URL is the page, which loads as <iframe> in the in-meeting notification. The domain must be in the apps' validDomains array in your app manifest.
// Specifies the type of text data in a message attachment.
Activity activity = MessageFactory.Text("This is a meeting signal test");

// Configures the current activity to generate a notification within Teams.
activity.TeamsNotifyUser(true, "https://teams.microsoft.com/l/bubble/APP_ID?url=<url>&height=<height>&width=<width>&title=<title>&completionBotId=BOT_APP_ID");

// Sends a message activity to the sender of the incoming activity. 
await turnContext.SendActivityAsync(activity).ConfigureAwait(false);
Property name Description
type Type of activity.
text The text content of the message.
summary The summary text of the message.
channelData.notification.alertInMeeting Boolean indicating if a notification is to be shown to the user while in a meeting.
channelData.notification.externalResourceUrl The value of the notification's external resource URL.
replyToId The ID of the parent or root message of the thread.
APP_ID App ID declared in manifest.
completionBotId Bot app ID.

Response codes

The following table includes the response codes:

Response code Description
201 The activity with signal is successfully sent.
401 The app responds with an invalid token.
403 The app is unable to send the signal. 403 response code can occur because of various reasons, such as the admin disables and blocks the app during live site migration. In this case, the payload contains a detailed error message.
404 The meeting chat doesn't exist.

Targeted meeting notification and app icon badging API

The targetedMeetingNotification API allows apps to send targeted in-meeting notifications and shows app icon badging to specific participants in a meeting. Apps send targeted in-meeting notifications and app icon badging based on user action. The API is available through bot API.

Prerequisite

You must configure your app manifest with RSC permissions under the webApplicationInfo property to send targeted in-meeting notifications and shows app icon badging to specific participants in a meeting. Use the following examples to configure your manifest:


For app manifest version 1.12 and later
"webApplicationInfo": {
    "id": "<<MICROSOFT-APP-ID>>",
    "resource": "https://RscBasedStoreApp"  },
  "authorization": {
    "permissions": {
      "resourceSpecific": [
            {
                "name": "OnlineMeetingNotification.Send.Chat",
                "type": "Application"
            }
        ]    
    }
}


For app manifest version 1.11 and earlier
"webApplicationInfo": {
    "id": "<<MICROSOFT-APP-ID>>",
    "resource": "https://RscBasedStoreApp",
    "applicationPermissions": [
      "OnlineMeetingNotification.Send.Chat"
    ]
}

Note

  • The API payload only permits a dialog with a URL.
  • The user ID formats aadObjectid and UPN aren't supported.

Get supported user ID format for targeted in-meeting notification and app icon badging:

Example

Following is an example of request payload for targeted in-meeting notification and app icon badging:

POST /v1/meetings/{meetingId}/notification
{

  "type": "targetedMeetingNotification",
  "value": {
    "recipients": [ 
"29:1I12M_iy2wTa97T6LbjTh4rJCWrtw2PZ3lxpD3yFv8j2YPnweY2lpCPPAn3RI0PP7rghfHauUz48I1t7ANhj4CA"
     ], 
    "surfaces": [ 
      { 
        "surface": "meetingStage", 
        "contentType": "task", 
        "content": { 
          "value": { 
            "height": "300", 
            "width": "400", 
            "title": "Targeted meeting Notification", 
            "url": "https://somevalidurl.com"           
}
        } 
      } 
    ] 
  },
  "channelData": { // optional if a developer doesn't want to support user attributes.
    "onBehalfOf": [ 
      { 
        "itemid": 0, 
        "mentionType": "person", 
        "mri": "29:1mDOCfGM9825lMHlwP8NjIVMJeQAbN-ojYBT5VzQfPpnst1IFQeYB1QXC8Zupn2RhgfLIW27HmynQk-4bdx_YhA", 
        "displayName": "yunny chung"      } 
    ] 
  }
}
Property name Description
meetingId The meeting ID is available through bot invoke and TeamsJS library.
type targetedMeetingNotification
recipients List of user IDs. Get user IDs for meeting participants through Get participant API. Get the entire list of chat roster using Get members API. An empty or null recipients list returns 400.
surface A type of surface. The supported surface types are meetingStage and meetingTabIcon.
surfaces List of surfaces where notifications can be rendered.
contentType Type of content that the targeted in-meeting notification renders. The supported value is task.
content TaskModuleContinueResponse
content.value.height Optional; requested height of the notification.
content.value.width Optional; requested width of the notification.
content.value.title Optional; title of the notification.
content.value.url Optional; URL to be rendered in the notification. Make sure the URL is part of validDomains in app manifest. If an empty string or no URL is provided, nothing is rendered on a meeting notification.
ChannelData.OnBehalfOf Optional; this is to support User attributes.
onBehalfOf.itemid Describes identification of the item. Its value must be 0.
onBehalfOf.mentionType person keyword. Describes the mention of a person.
onBehalfOf.mri User MRI shown as sender.
onBehalfOf.displayName Optional; name of the person. Used as fallback in case the name resolution is unavailable.

Note

If you provide an invalid input, the API returns the status code 400.

Response code

The following table includes the response codes:

Response code Description
202 Notification is successfully sent.
207 Notifications are sent only to a few participants.
400 Meeting notification request payload validation failed.
401 Bot token is invalid.
403 Bot isn't allowed to send the notification.
404 Meeting chat isn't found or none of the participants were found in the roster.

Get meeting details API

The meeting details API enables your app to get a meeting's static metadata. The metadata provides data points that don't change dynamically. The API is available through Bot Services. Both private scheduled or recurring meetings and channel scheduled or recurring meetings support API with different RSC permissions respectively.

The meeting details API must have a bot registration and bot ID. It requires Bot SDK to get TurnContext. To use the meeting details API, you must obtain different RSC permission based on the scope of any meeting, such as private meeting or channel meeting.

Note

The meeting details API is supported for scheduled private meetings, scheduled channel meeting, instant meetings (Meet now), one-on-one calls, and group calls in Teams desktop and mobile clients.

Prerequisite

To use the meeting details API, you must obtain different RSC permission based on the scope of any meeting, such as private meeting or channel meeting.


For app manifest version 1.12 and later

Use the following example to configure your app manifest's webApplicationInfo and authorization properties for any private meeting:

"webApplicationInfo": {
    "id": "<bot id>",
    "resource": "https://RscPermission",
},
"authorization": {
    "permissions": {
        "resourceSpecific": [
            {
                "name": "OnlineMeeting.ReadBasic.Chat",
                "type": "Application"
            }
        ]
    }
}

Use the following example to configure your app manifest's webApplicationInfo and authorization properties for any channel meeting:

"webApplicationInfo": {
    "id": "<bot id>",
    "resource": "https://RscPermission",
},
"authorization": {
    "permissions": {
        "resourceSpecific": [
            {
                "name": "ChannelMeeting.ReadBasic.Group",
                "type": "Application"
            }
        ]
    }
}


For app manifest version 1.11 and earlier

Use the following example to configure your app manifest's webApplicationInfo property for any private meeting:

"webApplicationInfo": {
    "id": "<bot id>",
    "resource": "https://RscPermission",
    "applicationPermissions": [
      "OnlineMeeting.ReadBasic.Chat"
    ]
}

Use the following example to configure your app manifest's webApplicationInfo property for any channel meeting:

"webApplicationInfo": {
    "id": "<bot id>",
    "resource": "https://RscPermission",
    "applicationPermissions": [
      "ChannelMeeting.ReadBasic.Group"
    ]
}

Note

  • If the ChannelMeeting.ReadBasic.Group permission is added to the manifest, the bot receives the meeting start or end events automatically from the channel meetings created in all the teams where the bot is added.
  • For a one-on-one call organizer is the initiator of the chat and for group calls organizer is the call initiator. For public channel meetings organizer is the person who created the channel post.

Query parameter

The following table lists the query parameter:

Value Type Required Description
meetingId String Yes The meeting identifier is available through Bot Invoke and the TeamsJS library.

Example

// Gets the information for the given meeting id.
MeetingInfo result = await TeamsInfo.GetMeetingInfoAsync(turnContext);

// Sends a message activity to the sender of the incoming activity. 
await turnContext.SendActivityAsync(JsonConvert.SerializeObject(result));
Property name Description
details.id The meeting's ID, encoded as a BASE64 string.
details.msGraphResourceId The MsGraphResourceId, used specifically for MS Graph API calls.
details.scheduledStartTime The meeting's scheduled start time, in UTC.
details.scheduledEndTime The meeting's scheduled end time, in UTC.
details.joinUrl The URL used to join the meeting.
details.title The title of the meeting.
details.type The meeting's type (OneToOneCall, GroupCall, Scheduled, Recurring, MeetNow, ChannelScheduled, and ChannelRecurring).
conversation.isGroup Boolean indicating whether conversation has more than two participants.
conversation.conversationType The conversation type.
conversation.id The meeting chat ID.
organizer.id The Organizer's user ID.
organizer.aadObjectId The Organizer's Microsoft Entra object ID.
organizer.tenantId The Organizer's Microsoft Entra tenant ID.

In case of recurring meeting type:

startDate: Specifies the date to start applying the pattern. The value of startDate must correspond to the date value of the start property on the event resource. The first occurrence of the meeting might not occur on this date if it doesn't fit the pattern.

endDate: Specifies the date to stop applying the pattern. The last occurrence of the meeting might not occur on this date if it doesn't fit the pattern.

Send real-time captions API

The send real-time captions API exposes a POST endpoint for Teams communication access real-time translation (CART) captions, human-typed closed captions. Text content sent to this endpoint appears to end users in a Teams meeting when they have captions enabled.

CART URL

You can get the CART URL for the POST endpoint from the Meeting options page in a Teams meeting. For more information, see CART captions in a Microsoft Teams meeting. You don't need to modify the CART URL to use CART captions.

Query Parameter

The CART URL includes the following query parameters:

Value Type Required Description
meetingId String Yes The meeting identifier is available through Bot Invoke and the TeamsJS library.
For example, meetingid=%7b%22tId%22%3a%2272f234bf-86f1-41af-91ab-2d7cd0321b47%22%2c%22oId%22%3a%22e071f268-4241-47f8-8cf3-fc6b84437f23%22%2c%22thId%22%3a%2219%3ameeting_NzJiMjNkMGQtYzk3NS00ZDI1LWJjN2QtMDgyODVhZmI3NzJj%40thread.v2%22%2c%22mId%22%3a%220%22%7d
token String Yes Authorization token.
For example, token=04751eac

Example

https://api.captions.office.microsoft.com/cartcaption?meetingid=%7b%22tId%22%3a%2272f234bf-86f1-41af-91ab-2d7cd0321b47%22%2c%22oId%22%3a%22e071f268-4241-47f8-8cf3-fc6b84437f23%22%2c%22thId%22%3a%2219%3ameeting_NzJiMjNkMGQtYzk3NS00ZDI1LWJjN2QtMDgyODVhZmI3NzJj%40thread.v2%22%2c%22mId%22%3a%220%22%7d&token=gjs44ra

Method

Resource Method Description
/cartcaption POST Handle captions for meeting, which was started

Note

Ensure that the content type for all requests is plain text with UTF-8 encoding. The body of request contains only captions.

Example

POST /cartcaption?meetingid=04751eac-30e6-47d9-9c3f-0b4ebe8e30d9&token=04751eac&lang=en-us HTTP/1.1
Host: api.captions.office.microsoft.com
Content-Type: text/plain
Content-Length: 22
Hello I’m Cortana, welcome to my meeting. 

Note

Each POST request generates a new line of captions. To ensure that the end user has enough time to read the content, limit each POST request body to 80-120 characters.

Error codes

The following table provides the error codes:

Error code Description
400 Bad request. The response body has more information. For example, not of all required parameters presented.
401 Unauthorized. Bad or expired token. If you receive this error, generate a new CART URL in Teams.
404 Meeting not found or not started. If you receive this error, ensure that you start the meeting and select start captions. After captions are enabled in the meeting, you can begin POSTing captions into the meeting.
500 Internal server error. For more information, contact support or provide feedback.

Receive real-time Teams meeting events

You can receive real-time meeting events such as meeting start and end or participant join and leave events.

Receive meeting start and end events

Note

Meeting start and end events are supported for scheduled and channel meetings.

The user can receive real-time meeting events. As soon as any app is associated with a meeting, the actual meeting start and end time are shared with the bot. The actual start and end time of a meeting are different from scheduled start and end time. The meeting details API provides the scheduled start and end time. The event provides the actual start and end time.

If the ChannelMeeting.ReadBasic.Group and OnlineMeeting.ReadBasic.Chat permissions are added in the manifest, the bot automatically starts receiving the meeting start or end events for the scheduled and channel meeting types.

Prerequisite

Your app manifest must have the webApplicationInfo property to receive the meeting start and end events. Use the following examples to configure your manifest:


For app manifest version 1.12 and later
"webApplicationInfo": {
    "id": "<bot id>",
    "resource": "https://RscPermission",
    },
"authorization": {
    "permissions": {
        "resourceSpecific": [
            {
                "name": "OnlineMeeting.ReadBasic.Chat",
                "type": "Application"
            }
            {
                "name": "ChannelMeeting.ReadBasic.Group",
                "type": "Application"
            }
        ]    
    }
}


For app manifest version 1.11 and earlier
"webApplicationInfo": {
    "id": "<bot id>",
    "resource": "https://RscPermission",
    "applicationPermissions": [
      "OnlineMeeting.ReadBasic.Chat",
      "ChannelMeeting.ReadBasic.Group"
    ]
}

Example of getting meeting start or end events

The bot receives the meeting start and meeting end events through the OnTeamsMeetingStartAsync and OnTeamsMeetingEndAsync handlers. The information related to the meeting event is part of the MeetingStartEventDetails object, which includes the metadata fields such as, meetingType, title, id, joinUrl, startTime, and EndTime.

Note

  • Get meeting ID from turnContext.ChannelData.
  • Do not use conversation ID as meeting ID.
  • Do not use meeting ID from meeting events payload turncontext.activity.value.

The following examples show how to capture the meeting start and end events:

Meeting Start Event

// Invoked when a Teams Meeting Start event activity is received from the connector.
protected override async Task OnTeamsMeetingStartAsync(MeetingStartEventDetails meeting, ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
{
    // Sends a message activity to the sender of the incoming activity. 
    await turnContext.SendActivityAsync(JsonConvert.SerializeObject(meeting));
}

Meeting End Event

// Invoked when a Teams Meeting End event activity is received from the connector.
protected override async Task OnTeamsMeetingEndAsync(MeetingEndEventDetails meeting, ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
{
    // Sends a message activity to the sender of the incoming activity.
    await turnContext.SendActivityAsync(JsonConvert.SerializeObject(meeting));
}

Example of meeting start event payload

The following code provides an example of meeting start event payload:

{
  "name": " application/vnd.microsoft.meetingStart",
  "type": "event",
  "timestamp": "2023-02-23T19:34:07.478Z",
  "localTimestamp": "2023-02-23T11:34:07.478-8",
  "channelId": "msteams",
  "serviceUrl": "https://smba.trafficmanager.net/teams/",
  "from": {
    "id": "user_id"
  },
  "conversation": {
    "isGroup": true,
    "conversationType": "groupchat",
    "id": "conversation_id"
  },
  "recipient": {
    "id": "28:65f50003-e15d-434a-9e14-0fcfeb3d7817"
  },
  "value": {
    "id": "meeting_id",
    "joinUrl": "join_url",
    "title": "Example meeting",
    "meetingType": "Scheduled",
    "startTime": "2023-02-23T19:34:07.478Z"
  },
  "channelData": {
    "tenant": {
      "id": "tenant_id"
    }
  }
}

Example of meeting end event payload

The following code provides an example of meeting end event payload:

{
  "name": " application/vnd.microsoft.meetingEnd",
  "type": "event",
  "timestamp": "2023-02-23T19:34:07.478Z",
  "localTimestamp": "2023-02-23T11:34:07.478-8",
  "channelId": "msteams",
  "serviceUrl": "https://smba.trafficmanager.net/teams/",
  "from": {
    "id": "user_id"
  },
  "conversation": {
    "isGroup": true,
    "conversationType": "groupchat",
    "id": "conversation_id"
  },
  "recipient": {
    "id": "28:65f50003-e15d-434a-9e14-0fcfeb3d7817"
  },
  "value": {
    "id": "meeting_id",
    "joinUrl": "join_url",
    "title": "Example meeting",
    "meetingType": "Scheduled",
    "EndTime": "2023-02-23T20:30:07.478Z"
  },
  "channelData": {
    "tenant": {
      "id": "tenant_id"
    }
  }
}
Property name Description
name Name of the user.
type Activity type.
timestamp Local date and time of the message, expressed in ISO-8601 format.
id ID for the activity.
channelId Channel this activity is associated with.
serviceUrl Service URL where responses to this activity should be sent.
from.id ID of the user that sent the request.
from.aadObjectId Microsoft Entra object ID of the user that sent the request.
conversation.isGroup Boolean indicating whether conversation has more than two participants.
conversation.tenantId Microsoft Entra tenant ID of the conversation or meeting.
conversation.id The meeting chat ID.
recipient.id ID of the user that receives the request.
recipient.name Name of the user that receives the request.
entities.locale entity that contains metadata about locale.
entities.country entity that contains metadata about country.
entities.type entity that contains metadata about client.
channelData.tenant.id Microsoft Entra tenant ID.
channelData.source The source name from where event is fired or invoked.
channelData.meeting.id The default ID associated with the meeting.
value.MeetingType The type of meeting.
value.Title The subject of the meeting.
value.Id The default ID associated with the meeting.
value.JoinUrl The join URL of the meeting.
value.StartTime The meeting start time in UTC.
value.EndTime The meeting end time in UTC.
locale The locale of the message set by the client.

Receive meeting participant events

Your bot can receive real-time meeting events such as participant join and leave events. A bot can receive the participant events only if subscribed to these events in Developer Portal.

Note

  • Participant events are supported only for scheduled meetings.
  • For a bot to receive participant events, ensure that you add the bot to the meeting before a participant joins or leaves the meeting.

To subscribe to participant events, follow these steps:

  1. In Developer Portal open your bot app or import an existing app.

  2. In the Meeting event subscriptions section, select the events:

    • Participant join
    • Participant leave
  3. Select Save

    Screenshot shows how developer portal display for participant events.

  4. Ensure that the OnlineMeetingParticipant.Read.Chat RSC permission is configured in your app manifest.

    If your app doesn't have the RSC permission, add it through the Configure > Permissions section of your app in Developer Portal. For more information, see RSC permissions.

The following examples show how to capture the participant join and leave events:

//Invoked on participant join a meeting
protected override async Task OnTeamsMeetingParticipantsJoinAsync(MeetingParticipantsEventDetails meeting, ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
{
  await turnContext.SendActivityAsync("Member has joined the meeting.");
  return;
}

Following are the examples of the participant join and leave event payloads:

The following is an example of the participant join event payload:

{ 

    "type": "event", 
    "name": "application/vnd.microsoft.meetingParticipantJoin",
    "timestamp": "2023-02-23T19:34:07.478Z", 
    "channelId": "msteams", 
    "serviceUrl": "https://smba.trafficmanager.net/amer/", 
    "from": { 
        "id": "29:id_xyz" 
    }, 
    "conversation": { 
        "isGroup": true, 
        "conversationType": "groupchat", 
        "id": "19:meeting_threadId@thread.v2" 
    }, 
    "recipient": { 
        "id": "28:botid" 
    },  
    "value": { 
       "members": [ 
       { 
        "user": { 
            "tenantId": "tenantid", 
            "objectId": "user_object_Id", 
            "id": "29:userId ", 
            "name": "Test User", 
            "aadObjectId": " user_object_Id " 
        },   
        "meeting": { 
            "inMeeting": true, 
            "role": "Organizer" //Attendee, Organizer, Presenter 
        },  
        }], 
    }, 
    "channelData": { 
        "tenant": { 
            "id": "tenantId" 
        }, 
        "meeting": { 
            "id": "encoded_meetingId" 
        } 
    } 
} 

Get incoming audio state

The getIncomingClientAudioState API allows an app to get the incoming audio state setting for the meeting user. The API is available through the TeamsJS library.

Note

  • The getIncomingClientAudioState API for mobile is available in Public Developer Preview.
  • The toggleIncomingClientAudio API is available in the new Teams client.
  • Resource specific consent is available for manifest version 1.12 and later versions, hence this API doesn't work for manifest version 1.11 and earlier versions.

Manifest

"authorization": {
    "permissions": {
      "resourceSpecific": [
        {
          "name": "OnlineMeetingParticipant.ToggleIncomingAudio.Chat",
          "type": "Delegated"
        }
      ]
    }
  }

Example

callback = (errcode, result) => {
        if (errcode) {
            // Handle error code
        }
        else {
            // Handle success code
        }
    }
// The getIncomingClientAudioState API shows the current audio state.
microsoftTeams.meeting.getIncomingClientAudioState(this.callback)

Query parameter

The following table includes the query parameter:

Value Type Required Description
callback String Yes Callback contains two parameters error and result. The error can either contain an error type SdkError or null when the audio fetch is successful. The result can either contain true or false value when the audio fetch is successful or null when the audio fetch fails. The incoming audio is muted if the result is true and unmuted if the result is false.

Response codes

The following table provides the response codes:

Response code Description
500 Internal error.
501 API isn't supported in the current context.
1000 App doesn't have proper permissions to allow share to stage.

Toggle incoming audio

The toggleIncomingClientAudio API allows an app to toggle the incoming audio state setting for the meeting user from mute to unmute or vice-versa. The API is available through the TeamsJS library.

Note

  • The toggleIncomingClientAudio API for mobile is available in Public Developer Preview.
  • Resource specific consent is available for manifest version 1.12 and later versions, hence this API doesn't work for manifest version 1.11 and earlier versions.

Manifest

"authorization": {
 "permissions": {
  "resourceSpecific": [
   {
    "name": "OnlineMeetingParticipant.ToggleIncomingAudio.Chat",
    "type": "Delegated"
   }
  ]
 }
}

Example

callback = (error, result) => {
        if (error) {
            // Handle error code
        }
        else {
            // Handle success code
        }
    }
// The toggleIncomingClientAudio API allows an app to toggle the incoming audio state.
microsoftTeams.meeting.toggleIncomingClientAudio(this.callback)

Query parameter

The following table includes the query parameter:

Value Type Required Description
callback String Yes Callback contains two parameters error and result. The error can either contain an error type SdkError or null when the toggle is successful. The result can either contain true or false value, when the toggle is successful or null when the toggle fails. The incoming audio is muted if the result is true and unmuted if the result is false.

Response code

The following table provides the response codes:

Response code Description
500 Internal error.
501 API isn't supported in the current context.
1000 App doesn't have proper permissions to allow share to stage.

Code sample

Sample name Description .NET Node.js Manifest
Meetings extensibility Teams meeting extensibility sample for passing tokens. View View View
In-meeting notification Demonstrates how to implement in-meeting notification using bot. View View View
Meeting side panel Teams meeting extensibility sample for interacting with the side panel in-meeting. View View
Details Tab in Meeting This sample app shows Teams meeting extensibility feature where user can create a poll, and members can answer the poll in meeting. View View View
Meeting Events Sample This sample shows real-time Teams meeting events using bot. View View View
Meeting Recruitment Sample This sample app shows a meeting experience for recruitment scenario using Apps In Meetings. View View View

See also