According to the Graph docs, this should be possible via the $expand=exceptionOccurrences parameter. So I tested the following query on a sample recurring event:
GET https://graph.microsoft.com/beta/me/events/AAMkADY1YWY4NDZlLWIwMGQtNDk3Ny04YzIwLTZkMTBhYjljMWQ3MABGAAAAAADmjcfnadEETLlwdmHxPiAhBwDRsoMe4QPhT703YoP1io2cAAAAAAENAADRsoMe4QPhT703YoP1io2cAAEdfgJMAAA=?
$select=subject,start,end,occurrenceId,exceptionOccurrences,cancelledOccurrences
&$expand=exceptionOccurrences
Here’s what I was asking Graph for:
subject, start, end → core meeting info
occurrenceId → unique identifier for a specific occurrence
exceptionOccurrences → should list the modified/rescheduled instances
cancelledOccurrences → should list which slots were cancelled
The Response
When I ran the query, I did get back the main event details along with some recurrence metadata. Here’s a snippet of what Graph returned
{
"@odata.context": "https://graph.microsoft.com/beta/$metadata#users('130dbf6d-8a11-451b-bdd2-f9a5f620f526')/events/$entity",
"@odata.etag": "W/"0bKDHuED4U+9N2KD9YqNnAABHJ/sEA=="",
"id": "AAMkADY1YWY4NDZlLWIwMGQtNDk3Ny04YzIwLTZkMTBhYjljMWQ3MABGAAAAAADmjcfnadEETLlwdmHxPiAhBwDRsoMe4QPhT703YoP1io2cAAAAAAENAADRsoMe4QPhT703YoP1io2cAAEdfgJMAAA=",
"createdDateTime": "2025-08-26T07:41:49.4443207Z",
"lastModifiedDateTime": "2025-08-26T11:13:46.470247Z",
"changeKey": "0bKDHuED4U+9N2KD9YqNnAABHJ/sEA==",
"categories": [],
"transactionId": "localevent:d3fa2faf-64b8-2df8-1b16-4bb64ee4e2c3",
"originalStartTimeZone": "India Standard Time",
"originalEndTimeZone": "India Standard Time",
"iCalUId": "040000008200E00074C5B7101A82E00800000000488EBEE15C16DC0100000000000000001000000045C9FC6D54F33F41B380736C02CD275A",
"uid": "040000008200E00074C5B7101A82E00800000000488EBEE15C16DC0100000000000000001000000045C9FC6D54F33F41B380736C02CD275A",
"iCalUId_v2": "040000008200E00074C5B7101A82E00800000000488EBEE15C16DC0100000000000000001000000045C9FC6D54F33F41B380736C02CD275A",
"reminderMinutesBeforeStart": 15,
"isReminderOn": true,
"hasAttachments": false,
"subject": "recur bug check",
"bodyPreview": "_____________________________________________**************************************************************\r\nMicrosoft Teams Need help?\r\nJoin the meeting now\r\nMeeting ID: 453 124 749 177 1\r\nPasscode: 4yt3xh3u\r\n**************************************************************\r\nFor organizers: Meeting options\r\n",
"importance": "normal",
"sensitivity": "normal",
"isAllDay": false,
"isCancelled": false,
"isOrganizer": true,
"responseRequested": true,
"seriesMasterId": null,
"showAs": "busy",
"type": "seriesMaster",
"webLink": "https://outlook.office365.com/owa/?itemid=AAMkADY1YWY4NDZlLWIwMGQtNDk3Ny04YzIwLTZkMTBhYjljMWQ3MABGAAAAAADmjcfnadEETLlwdmHxPiAhBwDRsoMe4QPhT703YoP1io2cAAAAAAENAADRsoMe4QPhT703YoP1io2cAAEdfgJMAAA%3D&exvsurl=1&path=/calendar/item",
"onlineMeetingUrl": null,
"isOnlineMeeting": true,
"onlineMeetingProvider": "teamsForBusiness",
"allowNewTimeProposals": true,
"occurrenceId": null,
"isDraft": false,
"hideAttendees": false,
"responseStatus": {
"response": "organizer",
"time": "0001-01-01T00:00:00Z"
},
"body": {
"contentType": "html",
"content": "<html>\r\n<head>\r\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\r\n</head>\r\n<body>\r\n<br>\r\n<div class="me-email-text" lang="en-US" style="max-width:600px; color:#242424; font-family:'Segoe UI','Helvetica Neue',Helvetica,Arial,sans-serif">\r\n<div aria-hidden="true" style="margin-bottom:24px; overflow:hidden; white-space:nowrap">\r\n________________________________________________________________________________</div>\r\n<div style="margin-bottom:12px"><span class="me-email-text" style="font-size:24px; font-weight:700; margin-right:12px">Microsoft Teams</span>\r\n<a href="https://aka.ms/JoinTeamsMeeting?omkt=en-US" id="meet_invite_block.action.help" class="me-email-link" style="font-size:14px; text-decoration:underline; color:#5B5FC7">\r\nNeed help?</a> </div>\r\n<div style="margin-bottom:6px"><a href="https://teams.microsoft.com/l/meetup-join/19%3ameeting_NDI3N2I1MjItY2NhMi00YmYyLWFmMWYtZTFmYTgwNTVjYjY1%40thread.v2/0?context=%7b%22Tid%22%3a%222d0dd113-df9d-413b-8850-f949c022ce8e%22%2c%22Oid%22%3a%22130dbf6d-8a11-451b-bdd2-f9a5f620f526%22%7d" id="meet_invite_block.action.join_link" title="Meeting join link" class="me-email-headline" style="font-size:20px; font-weight:600; text-decoration:underline; color:#5B5FC7">Join\r\n the meeting now</a> </div>\r\n<div style="margin-bottom:6px"><span class="me-email-text-secondary" style="font-size:14px; color:#616161">Meeting ID:\r\n</span><span class="me-email-text" style="font-size:14px; color:#242424">453 124 749 177 1</span>\r\n</div>\r\n<div style="margin-bottom:24px"><span class="me-email-text-secondary" style="font-size:14px; color:#616161">Passcode:\r\n</span><span class="me-email-text" style="font-size:14px; color:#242424">4yt3xh3u</span>\r\n</div>\r\n<div style="margin-bottom:24px; max-width:532px">\r\n<hr style="border:0; background:#D1D1D1; height:1px">\r\n</div>\r\n<div><span class="me-email-text-secondary" style="font-size:14px; color:#616161">For organizers:\r\n</span><a href="https://teams.microsoft.com/meetingOptions/?organizerId=130dbf6d-8a11-451b-bdd2-f9a5f620f526&tenantId=2d0dd113-df9d-413b-8850-f949c022ce8e&threadId=19_meeting_NDI3N2I1MjItY2NhMi00YmYyLWFmMWYtZTFmYTgwNTVjYjY1@thread.v2&messageId=0&language=en-US" id="meet_invite_block.action.organizer_meet_options" class="me-email-link" style="font-size:14px; text-decoration:underline; color:#5B5FC7">Meeting\r\n options</a> </div>\r\n<div style="margin-top:24px; margin-bottom:6px"></div>\r\n<div style="margin-bottom:24px"></div>\r\n<div aria-hidden="true" style="margin-bottom:24px; overflow:hidden; white-space:nowrap">\r\n________________________________________________________________________________</div>\r\n</div>\r\n</body>\r\n</html>\r\n"
},
"start": {
"dateTime": "2025-08-26T09:30:00.0000000",
"timeZone": "UTC"
},
"end": {
"dateTime": "2025-08-26T10:00:00.0000000",
"timeZone": "UTC"
},
"location": {
"displayName": "Microsoft Teams Meeting",
"locationType": "default",
"uniqueId": "Microsoft Teams Meeting",
"uniqueIdType": "private"
},
"locations": [
{
"displayName": "Microsoft Teams Meeting",
"locationType": "default",
"uniqueId": "Microsoft Teams Meeting",
"uniqueIdType": "private"
}
],
"recurrence": {
"pattern": {
"type": "daily",
"interval": 1,
"month": 0,
"dayOfMonth": 0,
"firstDayOfWeek": "sunday",
"index": "first"
},
"range": {
"type": "endDate",
"startDate": "2025-08-26",
"endDate": "2025-11-26",
"recurrenceTimeZone": "India Standard Time",
"numberOfOccurrences": 0
}
},
"attendees": [
{
"type": "required",
"status": {
"response": "none",
"time": "0001-01-01T00:00:00Z"
},
"emailAddress": {
"name": "Misha Sachdeva",
"address": "******@soais.com"
}
}
],
"organizer": {
"emailAddress": {
"name": "Ankur Gupta",
"address": "******@soais.com"
}
},
"onlineMeeting": {
"joinUrl": "https://teams.microsoft.com/l/meetup-join/19%3ameeting_NDI3N2I1MjItY2NhMi00YmYyLWFmMWYtZTFmYTgwNTVjYjY1%40thread.v2/0?context=%7b%22Tid%22%3a%222d0dd113-df9d-413b-8850-f949c022ce8e%22%2c%22Oid%22%3a%22130dbf6d-8a11-451b-bdd2-f9a5f620f526%22%7d"
},
"calendar@odata.associationLink": "https://graph.microsoft.com/beta/users('130dbf6d-8a11-451b-bdd2-f9a5f620f526')/calendars('AAMkADY1YWY4NDZlLWIwMGQtNDk3Ny04YzIwLTZkMTBhYjljMWQ3MAAuAAAAAADmjcfnadEETLlwdmHxPiAhAQDRsoMe4QPhT703YoP1io2cAAAAAAENAAA=')/$ref",
"calendar@odata.navigationLink": "https://graph.microsoft.com/beta/users('130dbf6d-8a11-451b-bdd2-f9a5f620f526')/calendars('AAMkADY1YWY4NDZlLWIwMGQtNDk3Ny04YzIwLTZkMTBhYjljMWQ3MAAuAAAAAADmjcfnadEETLlwdmHxPiAhAQDRsoMe4QPhT703YoP1io2cAAAAAAENAAA=')"
}
I have tried using similar v1.0 apis too, but it also gives the same type of result.
I have one deleted, one cancelled and one event shifted from the series. Still i don't get any cancelled or exception occurrences here. What is the issue here?
Another option is to use calendarview api like this
curl -X GET \
-H "Authorization: Bearer <YOUR_TOKEN>" \
"https://graph.microsoft.com/v1.0/me/calendar/calendarView?startDateTime=2025-08-01T00:00:00Z&endDateTime=2025-09-01T00:00:00Z&$expand=instances&$select=id,subject,start,end,seriesMasterId,type"
This also gives me just the exception occurences for the whole range of timeline but still no clue about the cancelled occurrences.