Microsoft Graph: Finding a Teams Meeting ID by Subject or Date
When working with Microsoft Graph, retrieving meeting artifacts like recordings, transcripts, or AI insights is a bit harder than it should be because you can’t query an onlineMeeting directly by subject or date.
Instead, you have to go through the calendar events first, then use the join URL to resolve the meeting ID. This post walks through exactly how to do that.
All Scheduled Meetings Are Events — But Not All Events Are Meetings
In Microsoft Graph, an event and an onlineMeeting are related but not the same thing.
- 📆 An
eventis simply a calendar item — it can be a personal appointment, reminder, or scheduled time block, etc. - 🗣️
onlineMeetingrepresents the real-time meeting session - contains the data that only exists once the meeting actually runs, such as recordings, transcripts, and attendance information.
How to Get a Meeting ID from a Calendar Event
Search for an Event by Subject
The easiest way to get an event by subject is to use the Events API (Get-MgUserEvent) to first retrieve an event using a filter:
Get-MgUserEvent -userId "ckarawani@easy365.io" -Filter "Contains(subject, 'Blog')"Graph Powershell SDK - Getting Event by Subject Containing "Blog"
GET https://graph.microsoft.com/v1.0/users/ckarawani@easy365.io/events?$filter=contains(subject,'Blog')
Authorization: Bearer {access_token}Msft Graph - GET Event by Subject Containing "Blog"
Search for Events by Date Range
Alternatively, you can get events by date range instead using the CalendarView API. Unlike filtering /events directly, calendarView expands recurring meetings into individual occurrences — so a weekly standup will appear as a separate entry for each occurrence within your window, rather than a single master event.
Get-MgUserCalendarView -UserId $userUpn -StartDateTime "2026-03-01T00:00:00" -EndDateTime "2026-03-07T23:59:59"Graph PowerShell SDK - Getting Events by Date Range
GET https://graph.microsoft.com/v1.0/users/ckarawani@easy365.io/calendarView?startDateTime=2026-03-01T00:00:00&endDateTime=2026-03-07T23:59:59
Authorization: Bearer {access_token}Msft Graph - GET Events by Date Range
Get the Join Url from your Search Results
In both cases (getting by subject or by date range) the response will contain events that have a onlineMeeting.joinUrl which you can then use to get your meeting ID.
{
"id": "AAMkAGNhbGVuZGFyLWV2ZW50LWlkLWV4YW1wbGUAAA=",
"subject": "Product / Architect Sync",
"isOnlineMeeting": true,
"onlineMeeting": {
"joinUrl": "https://teams.microsoft.com/l/me..." // ⬅️ join URL of the onlineMeeting
}
}Event JSON response containing the joinUrl of the associated onlineMeeting
Get an onlineMeeting ID via the JoinUrl
Using the joinUrl from the event, you can query /onlineMeetings and filter by JoinWebUrl to retrieve the corresponding onlineMeeting resource — which is what you need to access recordings, transcripts, and attendance reports. The two properties (joinUrl and JoinWebUrl) refer to the same value; Microsoft just added "Web" in one and not the other.
Get-MgUserOnlineMeeting -UserId $userGuid -Filter "JoinWebUrl eq '$joinWebUrl'"Graph PowerShell SDK - Get OnlineMeeting by JoinWebUrl
GET https://graph.microsoft.com/v1.0/me/onlineMeetings?$filter=JoinWebUrl eq 'https://teams.microsoft.com/l/mee...'
Authorization: Bearer {access_token}
# Uses the join URL from the event to resolve the onlineMeeting resourceMsft Graph - GET OnlineMeeting by JoinWebUrl
The response contains the onlineMeeting id
{
"id": "FAKE_ID_1vbmxpbmVt...", // ⬅️ OnlineMeetingId
"joinWebUrl": "https://teams.microsoft.com/l/meetup-join/19%3ameeting_FAKE-ID%40thread.v2/0?context=...", // same URL used in filter
"subject": "Blog Sync"
}Wrapping it up
The script below ties everything together — starting from a meeting subject, it walks through the full lookup flow and returns the OnlineMeetingId you need to access transcripts, recordings, attendance reports, and AI insights.
Here's a little PowerShell script that ties all together..
<#
.SYNOPSIS
Retrieves the online meeting ID for a Teams meeting by searching your calendar by subject.
.DESCRIPTION
This standalone script demonstrates how to use Microsoft Graph PowerShell to:
1. Search your Outlook/Teams calendar for a meeting by subject keyword
2. Resolve the join URL to an online meeting ID
This is useful when you need a meeting ID for downstream Graph API calls
(e.g. fetching AI insights, transcripts, or recordings).
.REQUIREMENTS
Install-Module Microsoft.Graph -Scope CurrentUser
#>
# Connect to Microsoft Graph with the required scopes
Connect-MgGraph -Scopes "User.Read", "Calendars.Read", "OnlineMeetings.Read"
# Resolve the signed-in user's UPN and GUID
$userUpn = (Get-MgContext).Account
$userGuid = (Get-MgUser -UserId $userUpn).Id
# Prompt for a partial subject match
$meetingSubject = Read-Host -Prompt "Enter the meeting subject (partial match)"
# Search calendar events where subject contains the input
$events = Get-MgUserEvent -UserId $userUpn -Filter "Contains(subject,'$meetingSubject')"
if ($events.Count -eq 0) {
Write-Host "No meetings found matching '$meetingSubject'." -ForegroundColor Yellow
return
}
# If multiple matches, let the user pick one
if ($events.Count -gt 1) {
Write-Host "`nMultiple meetings found:" -ForegroundColor Cyan
for ($i = 0; $i -lt $events.Count; $i++) {
Write-Host "$i : $($events[$i].Subject) — $($events[$i].Start.DateTime)"
}
$selectionInput = Read-Host -Prompt "Enter the index of the meeting to use"
[int]$selection = 0
if (-not [int]::TryParse($selectionInput, [ref]$selection) -or $selection -lt 0 -or $selection -ge $events.Count) {
Write-Host "Invalid selection." -ForegroundColor Red
return
}
$event = $events[$selection]
} else {
$event = $events[0]
}
# Extract the Teams join URL from the calendar event
$joinWebUrl = $event.OnlineMeeting.JoinUrl
if (-not $joinWebUrl) {
Write-Host "No Teams join URL found on this event. Is it an online meeting?" -ForegroundColor Yellow
return
}
Write-Host "Join URL: $joinWebUrl"
# Use the join URL to look up the online meeting and retrieve its ID
$onlineMeeting = Get-MgUserOnlineMeeting -UserId $userGuid -Filter "JoinWebUrl eq '$joinWebUrl'"
Write-Host "`nMeeting ID: $($onlineMeeting.Id)"
Limitations & What's Next
Meetings you didn't organize or attend
This flow works for any meeting on your calendar — whether you organised it or were invited to it. Both appear in your calendar and both will have a joinUrl you can use to resolve the OnlineMeetingId. It won't work for meetings on calendars you don't have access to — that would require delegated or admin-level permissions.
Ad-hoc and "Meet Now" meetings
Meetings started directly in Teams without scheduling don't have a calendar event, so the Event → JoinUrl path doesn't apply. Your options are to filter /onlineMeetings directly using the join URL if you have it, or use the videoTeleconferenceId, or joinMeetingId. A real bummer and something I'd like to explore further.
What to do with the Meeting ID
This post only covers how to retrieve the OnlineMeetingId. What you actually do with it — fetching transcripts, recordings, attendance reports, or AI insights — is a topic for a follow-up post.