Share via

Cannot create subscription for communications/onlineMeetings/meetingCallEvents

mo z 0 Reputation points
2026-04-01T09:46:12.4633333+00:00

Environment:

  • Multi-tenant Azure AD app (registered in tenant A, users in tenant B)
  • Using Microsoft Graph API v1.0

What works:

  • Creating calendar events with isOnlineMeeting: true (delegated token) ✅
  • Creating subscriptions for communications/onlineMeetings/{id}/recordings (delegated token) ✅
  • Auto-recording via PATCH /me/onlineMeetings/{id} with recordAutomatically: true

What fails:

  • Creating a subscription for meeting end detection

Attempts:

POST /subscriptions with delegated user token:

{
  "changeType": "updated",
  "resource": "communications/onlineMeetings/{meetingId}",
  "notificationUrl": "https://myapp.example.com/hooks/microsoft-teams",
  "expirationDateTime": "2026-03-31T10:00:00Z",
  "clientState": "secret"
}

Result: 400 Bad Request (empty error body)

POST /subscriptions with delegated user token:

{
  "changeType": "updated",
  "resource": "communications/onlineMeetings(joinWebUrl='{encodedJoinUrl}')/meetingCallEvents",
  "notificationUrl": "https://myapp.example.com/hooks/microsoft-teams",
  "expirationDateTime": "2026-03-31T10:00:00Z",
  "clientState": "secret"
}

Result: 400 Bad Request (empty error body)

Same as #2 but with app-only token (client credentials flow, OnlineMeetings.ReadWrite.All application permission granted with admin consent): Result: Not yet tested / pending

Permissions granted (all with admin consent):

  • Delegated: OnlineMeetings.ReadWrite, Calendars.ReadWrite, OnlineMeetingRecording.Read.All
  • Application: OnlineMeetings.ReadWrite.All

Questions:

  1. Does communications/onlineMeetings(joinWebUrl='{url}')/meetingCallEvents require an app-only token (client credentials) or can it work with a delegated token?
  2. Are there additional permissions beyond OnlineMeetings.ReadWrite.All needed for meetingCallEvents subscriptions?
  3. Is there a simpler way to get notified when a Teams online meeting ends? We need this to advance a candidate's progress in our recruiting pipeline after an interview concludes.
  4. The 400 error responses have empty bodies — is there a way to get more detailed error information?

Context: We're building a recruiting platform that schedules Teams interviews. We need to detect when a meeting ends to automatically advance the candidate to the next stage. Recording subscriptions work, but meetings aren't always recorded, so we need a separate meeting-end signal.

Microsoft Security | Microsoft Graph
0 comments No comments

1 answer

Sort by: Most helpful
  1. Q&A Assist
    2026-04-01T09:46:41.1633333+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more
    1. communications/onlineMeetings(joinWebUrl='{joinWebUrl}')/meetingCallEvents requires an application-only token.

    The change notifications for online meeting call events explicitly support only application permissions:

    • Supported permission type: Application only
    • Required permissions: OnlineMeetings.Read.All or OnlineMeetings.ReadWrite.All
    • Delegated (work or school) and delegated (personal) are not supported for this resource.

    Therefore, attempts with a delegated user token will fail, regardless of scopes.

    From the documentation: for meeting call events, only application permissions are supported, and the supported permissions are OnlineMeetings.Read.All and OnlineMeetings.ReadWrite.All.

    1. No additional permissions beyond OnlineMeetings.ReadWrite.All are documented for meetingCallEvents.

    For subscriptions to online meeting call events, the documented minimum permissions are:

    • Application: OnlineMeetings.Read.All or OnlineMeetings.ReadWrite.All

    No other permissions are listed as required for /communications/onlineMeetings(joinWebUrl='{joinWebUrl}')/meetingCallEvents.

    1. The supported way to get notified when a Teams online meeting ends is via meeting call event change notifications.

    The online meeting call events change notifications are designed to notify on:

    • Call started
    • Call ended
    • Roster updated

    To use this for “meeting ended” detection:

    1. Obtain the meeting joinWebUrl (from the onlineMeeting resource or Teams client).
    2. URL-encode it as described in the documentation.
    3. Create a subscription with an application token to:
      • resource: /communications/onlineMeetings(joinWebUrl='{encodedJoinUrl}')/meetingCallEvents
      • changeType: updated
      • expirationDateTime: within the allowed maximum (3 days; renew as needed).
    4. Listen for the call-ended event in the notification payload and trigger the pipeline advancement when that event is received.

    The documentation also notes:

    • Maximum subscription expiry is 3 days; renew using PATCH /subscriptions/{id} to keep it active.
    • This resource supports notifications with resource data, so the event details can be obtained directly from the notification.

    There is no simpler, separate Teams signal documented for “meeting ended” beyond these call event notifications and post-meeting artifacts (recordings/transcripts). Recordings and transcripts are covered by separate change notifications (callRecording, callTranscript), but as noted, they are not guaranteed to exist for every meeting.

    1. About the 400 Bad Request with empty body and how to get more detail.

    From the provided context, there is no additional guidance on empty-body 400 responses for POST /subscriptions. However, the behavior observed (400 with delegated tokens) is consistent with using an unsupported permission type for this resource:

    • Meeting call events support only application permissions.
    • Delegated tokens are not supported and will cause subscription creation to fail.

    To move forward and get meaningful responses:

    • Switch to an app-only token with OnlineMeetings.Read.All or OnlineMeetings.ReadWrite.All.
    • Ensure the resource is correctly formed with the properly URL-encoded joinWebUrl as shown in the documentation example.
    • Respect the maximum expirationDateTime of 3 days for meeting call events subscriptions.

    Once using the correct permission model and resource format, the API should return standard error payloads if there are other issues (for example, malformed resource string or invalid URL encoding).


    References:

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.