Skip to main content

Overview

The Calendar API provides operations to manage user calendars. Access through graphClient.Me.Calendar or graphClient.Users[userId].Calendar.

Request Builders

// Primary calendar for current user
public CalendarRequestBuilder Calendar { get; }
// Access: graphClient.Me.Calendar

// Primary calendar for specific user
public CalendarRequestBuilder Calendar { get; }
// Access: graphClient.Users["user-id"].Calendar

// Specific calendar
public CalendarRequestBuilder Calendar { get; }
// Access: graphClient.Me.Calendars["calendar-id"]

Operations

Get Calendar

Retrieve calendar properties.
var calendar = await graphClient.Me.Calendar.GetAsync();

Console.WriteLine($"Calendar: {calendar.Name}");
Console.WriteLine($"Owner: {calendar.Owner.Name}");
Console.WriteLine($"Can Edit: {calendar.CanEdit}");
Response Properties:
id
string
Calendar unique identifier
name
string
Calendar display name
color
string
Calendar color (e.g., “lightBlue”, “lightGreen”)
changeKey
string
Version identifier for the calendar
canEdit
bool
Whether the user can write to the calendar
canShare
bool
Whether the user can share the calendar
canViewPrivateItems
bool
Whether the user can see private items
owner
EmailAddress
Calendar owner information

Update Calendar

Update calendar properties.
var updateCalendar = new Calendar
{
    Name = "Work Calendar",
    Color = CalendarColor.LightBlue
};

await graphClient.Me.Calendar.PatchAsync(updateCalendar);

Calendar Collection

List Calendars

Get all calendars for a user.
var calendars = await graphClient.Me.Calendars.GetAsync();

foreach (var calendar in calendars.Value)
{
    Console.WriteLine($"{calendar.Name} - Owner: {calendar.Owner.Name}");
}

Create Calendar

Create a new calendar.
var newCalendar = new Calendar
{
    Name = "Project Calendar",
    Color = CalendarColor.LightGreen
};

var calendar = await graphClient.Me.Calendars.PostAsync(newCalendar);
Console.WriteLine($"Created calendar: {calendar.Id}");

Delete Calendar

Delete a calendar (except the default calendar).
await graphClient.Me.Calendars["calendar-id"].DeleteAsync();

Calendar Events

List Events

Get events from a calendar.
var events = await graphClient.Me.Calendar.Events.GetAsync();

foreach (var evt in events.Value)
{
    Console.WriteLine($"{evt.Subject} - {evt.Start.DateTime}");
}

// Filter events by date range
var upcomingEvents = await graphClient.Me.Calendar.Events.GetAsync(config =>
{
    config.QueryParameters.Filter = $"start/dateTime ge '{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ssZ}'";
    config.QueryParameters.Orderby = new[] { "start/dateTime" };
    config.QueryParameters.Top = 10;
});

Create Event

Create a new calendar event.
var newEvent = new Event
{
    Subject = "Team Meeting",
    Body = new ItemBody
    {
        ContentType = BodyType.Html,
        Content = "<h1>Agenda</h1><ul><li>Project updates</li></ul>"
    },
    Start = new DateTimeTimeZone
    {
        DateTime = "2024-03-15T14:00:00",
        TimeZone = "Pacific Standard Time"
    },
    End = new DateTimeTimeZone
    {
        DateTime = "2024-03-15T15:00:00",
        TimeZone = "Pacific Standard Time"
    },
    Location = new Location
    {
        DisplayName = "Conference Room A"
    },
    Attendees = new List<Attendee>
    {
        new Attendee
        {
            EmailAddress = new EmailAddress
            {
                Address = "[email protected]",
                Name = "John Doe"
            },
            Type = AttendeeType.Required
        },
        new Attendee
        {
            EmailAddress = new EmailAddress
            {
                Address = "[email protected]",
                Name = "Jane Smith"
            },
            Type = AttendeeType.Optional
        }
    },
    IsReminderOn = true,
    ReminderMinutesBeforeStart = 15
};

var evt = await graphClient.Me.Calendar.Events.PostAsync(newEvent);
Console.WriteLine($"Event created: {evt.Id}");

Calendar View

Get calendar view for a date range (returns instances of recurring events).
var startDate = DateTime.UtcNow;
var endDate = startDate.AddDays(7);

var calendarView = await graphClient.Me.Calendar.CalendarView.GetAsync(config =>
{
    config.QueryParameters.StartDateTime = startDate.ToString("yyyy-MM-ddTHH:mm:ssZ");
    config.QueryParameters.EndDateTime = endDate.ToString("yyyy-MM-ddTHH:mm:ssZ");
    config.QueryParameters.Orderby = new[] { "start/dateTime" };
});

foreach (var evt in calendarView.Value)
{
    Console.WriteLine($"{evt.Subject}");
    Console.WriteLine($"  Start: {evt.Start.DateTime}");
    Console.WriteLine($"  Recurrence: {evt.Type}"); // SingleInstance, Occurrence, Exception
}
Query Parameters:
startDateTime
string
required
Start of the date range (ISO 8601 format)
endDateTime
string
required
End of the date range (ISO 8601 format)
$select
string[]
Properties to include
$top
int
Number of events to return

Calendar Permissions

List Permissions

var permissions = await graphClient.Me.Calendar.CalendarPermissions.GetAsync();

foreach (var permission in permissions.Value)
{
    Console.WriteLine($"{permission.EmailAddress.Name}: {permission.Role}");
}

Share Calendar

var newPermission = new CalendarPermission
{
    EmailAddress = new EmailAddress
    {
        Address = "[email protected]",
        Name = "Colleague"
    },
    Role = CalendarRoleType.Read // Read, Write, FreeBusyRead, etc.
};

await graphClient.Me.Calendar.CalendarPermissions.PostAsync(newPermission);

Update Permission

var updatePermission = new CalendarPermission
{
    Role = CalendarRoleType.Write
};

await graphClient.Me.Calendar
    .CalendarPermissions["permission-id"]
    .PatchAsync(updatePermission);

Remove Permission

await graphClient.Me.Calendar
    .CalendarPermissions["permission-id"]
    .DeleteAsync();

Calendar Groups

List Calendar Groups

var calendarGroups = await graphClient.Me.CalendarGroups.GetAsync();

foreach (var group in calendarGroups.Value)
{
    Console.WriteLine($"Group: {group.Name}");
    
    // List calendars in group
    var calendars = await graphClient.Me
        .CalendarGroups[group.Id]
        .Calendars.GetAsync();
    
    foreach (var calendar in calendars.Value)
    {
        Console.WriteLine($"  - {calendar.Name}");
    }
}

Create Calendar Group

var newGroup = new CalendarGroup
{
    Name = "Project Calendars"
};

var group = await graphClient.Me.CalendarGroups.PostAsync(newGroup);

Find Meeting Times

Find available meeting times for attendees.
var findMeetingTimesBody = new FindMeetingTimesPostRequestBody
{
    Attendees = new List<AttendeeBase>
    {
        new AttendeeBase
        {
            EmailAddress = new EmailAddress { Address = "[email protected]" },
            Type = AttendeeType.Required
        },
        new AttendeeBase
        {
            EmailAddress = new EmailAddress { Address = "[email protected]" },
            Type = AttendeeType.Required
        }
    },
    TimeConstraint = new TimeConstraint
    {
        TimeSlots = new List<TimeSlot>
        {
            new TimeSlot
            {
                Start = new DateTimeTimeZone
                {
                    DateTime = "2024-03-15T09:00:00",
                    TimeZone = "Pacific Standard Time"
                },
                End = new DateTimeTimeZone
                {
                    DateTime = "2024-03-15T17:00:00",
                    TimeZone = "Pacific Standard Time"
                }
            }
        }
    },
    MeetingDuration = TimeSpan.FromHours(1),
    MaxCandidates = 5
};

var suggestions = await graphClient.Me.FindMeetingTimes.PostAsync(findMeetingTimesBody);

foreach (var suggestion in suggestions.MeetingTimeSuggestions)
{
    Console.WriteLine($"Confidence: {suggestion.Confidence}");
    Console.WriteLine($"Start: {suggestion.MeetingTimeSlot.Start.DateTime}");
    Console.WriteLine($"End: {suggestion.MeetingTimeSlot.End.DateTime}");
}

Get Schedule (Free/Busy)

Get free/busy information for users.
var getScheduleBody = new GetSchedulePostRequestBody
{
    Schedules = new List<string>
    {
        "[email protected]",
        "[email protected]",
        "[email protected]"
    },
    StartTime = new DateTimeTimeZone
    {
        DateTime = "2024-03-15T00:00:00",
        TimeZone = "Pacific Standard Time"
    },
    EndTime = new DateTimeTimeZone
    {
        DateTime = "2024-03-15T23:59:59",
        TimeZone = "Pacific Standard Time"
    },
    AvailabilityViewInterval = 60 // minutes
};

var schedules = await graphClient.Me.Calendar.GetSchedule.PostAsync(getScheduleBody);

foreach (var schedule in schedules.Value)
{
    Console.WriteLine($"{schedule.ScheduleId}: {schedule.AvailabilityView}");
    // 0=free, 1=tentative, 2=busy, 3=out of office, 4=working elsewhere
}

Common Use Cases

Create Recurring Meeting

var recurringEvent = new Event
{
    Subject = "Weekly Team Standup",
    Start = new DateTimeTimeZone
    {
        DateTime = "2024-03-18T10:00:00",
        TimeZone = "Pacific Standard Time"
    },
    End = new DateTimeTimeZone
    {
        DateTime = "2024-03-18T10:30:00",
        TimeZone = "Pacific Standard Time"
    },
    Recurrence = new PatternedRecurrence
    {
        Pattern = new RecurrencePattern
        {
            Type = RecurrencePatternType.Weekly,
            Interval = 1,
            DaysOfWeek = new[] { DayOfWeek.Monday }
        },
        Range = new RecurrenceRange
        {
            Type = RecurrenceRangeType.EndDate,
            StartDate = new Date(2024, 3, 18),
            EndDate = new Date(2024, 12, 31)
        }
    }
};

await graphClient.Me.Calendar.Events.PostAsync(recurringEvent);

Get Today’s Events

var today = DateTime.Today;
var tomorrow = today.AddDays(1);

var todayEvents = await graphClient.Me.Calendar.CalendarView.GetAsync(config =>
{
    config.QueryParameters.StartDateTime = today.ToString("yyyy-MM-ddTHH:mm:ssZ");
    config.QueryParameters.EndDateTime = tomorrow.ToString("yyyy-MM-ddTHH:mm:ssZ");
    config.QueryParameters.Orderby = new[] { "start/dateTime" };
});

Error Handling

using Microsoft.Graph.Models.ODataErrors;

try
{
    var calendar = await graphClient.Me.Calendar.GetAsync();
}
catch (ODataError error)
{
    if (error.Error.Code == "ErrorAccessDenied")
    {
        Console.WriteLine("Access denied to calendar");
    }
    else
    {
        Console.WriteLine($"Error: {error.Error.Message}");
    }
}

See Also

Calendar Model

Calendar resource properties

Events API

Event management operations

Messages API

Email message operations

Users API

User management

Build docs developers (and LLMs) love