Events API
List Events
Retrieves calendar events from all connected providers (Google Calendar, Microsoft Outlook, Apple Calendar, CalDAV) for the authenticated user.
Fetches events from multiple calendar providers simultaneously with support for pagination, filtering by date range and specific calendars, and handling of recurring events. Returns events from all supported calendar providers, sorted by start time within each page, with "load more" functionality using nextPageToken tokens.
Endpoint: GET /events
Request Parameters
Number of events to fetch per request. Maximum value is capped at 1000.
250ISO date string to filter events starting from this date. Date strings are automatically normalized to handle malformed ISO 8601 formats. When omitted, the range starts 30 days before the time of the request — except for Google accounts under the free-busy scope, where it starts at the time of the request.
ISO date string to filter events ending before this date. Date strings are automatically normalized to handle malformed ISO 8601 formats. When omitted, the range ends 90 days after the time of the request — except for Google accounts under the free-busy scope, where it ends 30 days after it.
JSON stringified object of calendar IDs per provider. If not provided, events from all calendars will be fetched.
Calendar IDs that are not associated with the authenticated user's connected accounts will be silently ignored.
'{"google":["john.andrew@mobiscroll.com"],"microsoft":[],"apple":[],"caldav":[]}'
undefinedBase64 encoded JSON pagination state object containing token information for each provider (Google, Microsoft, Apple, CalDAV). This parameter should be passed as-is from the previous response when loading more events. It does not carry the other filters: send the same start, end, calendarIds and singleEvents with every page.
undefinedControls how recurring events are returned:
true- Expands recurring events into individual instances within the specified time rangefalse- Returns only the master recurring event (series definition) without individual occurrences
trueResponse
Array of calendar events from all supported calendar providers, sorted chronologically by start time within this page. Each CalendarEvent object contains:
Provider name: 'google', 'microsoft', 'apple', or 'caldav'
Event ID
Calendar ID
Event title/summary
Event description or notes (optional)
Event start date/time
Event end date/time
True if all-day event
ID of the recurring event series (if this is an instance of a recurring event) (optional)
Event background color (optional)
Event location (optional)
Array of event attendees (optional).
For Google this mirrors the event's guest list exactly as Google returns it: nothing is added and nothing is inferred. An event with no guests has an empty array, and the organizer appears only when Google itself lists them among the guests.
One consequence worth planning for: when an event is organised by a group calendar, Google often does list that calendar's address among the guests, flagged organizer: true. Those addresses end in @group.calendar.google.com with a varying prefix, and they are not mailboxes. If you render or count guests, or send mail to them, filter them out on your side — this happens whenever the event was organised by a group calendar, regardless of which calendar you read the event from.
For Microsoft, iCloud and CalDAV, where the protocol keeps the organizer outside the guest list, the organizer is added as an entry flagged organizer: true. The provider's full organizer record is always available under original.
Each object contains:
Attendee email address
Response status: 'accepted', 'declined', 'tentative', or 'none'
True if this attendee is the event organizer (optional)
Custom key-value pairs for additional event data (optional)
Conference meeting URL (optional).
Provider-specific conference metadata returned by the API (optional). Use this when you need details beyond the conference link.
Conference provider identifier, which depends on the calendar provider. Google: the conference solution type Google reports, for example hangoutsMeet for Google Meet or addOn for a link added through the API or an add-on, and google-meet when Google reports no type. Microsoft: teams. Apple and CalDAV: caldav.
Additional fields vary by provider and are returned as-is when available. Typical examples:
- Google:
entryPoints,conferenceSolution,conferenceId - Microsoft: provider meeting details from Graph (for example join URL-related fields)
- Apple/CalDAV: usually only
provider
Event availability: 'busy' or 'free' (optional)
Event privacy: 'public', 'private', or 'confidential' (optional)
Event status: 'confirmed', 'tentative', or 'cancelled' (optional)
ISO 8601 timestamp of when the event was last modified (optional)
Public event link (optional)
Original event object from the provider
Number of events per page.
Base64 encoded pagination state for the next request. Pass this value as the nextPageToken parameter when loading more events. Only included in the response if more events are available.
Status of each provider queried for this page, keyed by provider name, for example "google": "Google returned results" and "microsoft": "No Microsoft account connected". A provider that returned an error appears here with its error message; its events are left out of this page, and later pages of the same listing do not query it again. The values are informational text — do not parse them. Providers that were not queried for this page are absent.
Error Responses
- 400 - Bad Request. Invalid nextPageToken parameters
- 401 - Unauthorized. Invalid or missing bearer token
- 500 - Internal Server Error. Provider error or unexpected failure
Examples
- REST
- Node.js SDK
- Python SDK
- PHP SDK
- .NET SDK
- Java SDK
- Go SDK
- Ruby SDK
GET /events?pageSize=50&start=2025-10-01T00:00:00Z&end=2025-10-31T23:59:59Z
{
"events": [
{
"id": "event123",
"title": "Team Meeting",
"start": "2025-10-15T10:00:00Z",
"end": "2025-10-15T11:00:00Z",
"provider": "google",
"allDay": false,
"location": "Conference Room A",
"color": "#9fc6e7",
"lastModified": "2026-03-10T13:36:08.000Z"
}
],
"pageSize": 50,
"nextPageToken": "eyJnb29nbGUiOnsidG9rZW4iOnsiY2FsMTIzIjp7Im5leHRQYWdlVG9rZW4iOiJhYmMifX0sImlzRGVwbGV0ZWQiOmZhbHNlfX0=",
"info": {
"google": "Google returned results",
"microsoft": "No Microsoft account connected",
"apple": "No Apple account connected",
"caldav": "Caldav returned no events"
}
}
GET /events?pageSize=50&start=2025-10-01T00:00:00Z&end=2025-10-31T23:59:59Z&nextPageToken=eyJnb29nbGUiOnsidG9rZW4iOnsiY2FsMTIzIjp7Im5leHRQYWdlVG9rZW4iOiJhYmMifX0sImlzRGVwbGV0ZWQiOmZhbHNlfX0=
GET /events?pageSize=25&calendarIds=%7B%22google%22:%5B%22john.andrew%40mobiscroll.com%22%5D,%22microsoft%22:%5B%5D,%22apple%22:%5B%5D,%22caldav%22:%5B%5D%7D
GET /events?pageSize=50&singleEvents=false
// Fetch initial events with date range filter
const response = await client.events.list({
pageSize: 50,
start: '2025-10-01T00:00:00Z',
end: '2025-10-31T23:59:59Z'
});
console.log(response.events);
// Load more events using nextPageToken
// Send the same filters with every page
const nextResponse = await client.events.list({
pageSize: 50,
start: '2025-10-01T00:00:00Z',
end: '2025-10-31T23:59:59Z',
nextPageToken: response.nextPageToken
});
// Filter by specific calendars
const filteredEvents = await client.events.list({
pageSize: 25,
calendarIds: { google: ['personal@gmail.com', 'work@company.com'] }
});
// Get recurring event series masters (not expanded)
const masters = await client.events.list({
pageSize: 50,
singleEvents: false
});
# Fetch initial events with date range filter
response = client.events.list(
page_size=50,
start='2025-10-01T00:00:00Z',
end='2025-10-31T23:59:59Z',
)
# Load more events using next_page_token
# Send the same filters with every page
next_response = client.events.list(
page_size=50,
start='2025-10-01T00:00:00Z',
end='2025-10-31T23:59:59Z',
next_page_token=response.next_page_token,
)
# Filter by specific calendars
filtered_events = client.events.list(
page_size=25,
calendar_ids={'google': ['personal@gmail.com', 'work@company.com']},
)
# Get recurring event series masters (not expanded)
masters = client.events.list(
page_size=50,
single_events=False,
)
// Fetch initial events with date range filter
$response = $client->events()->list([
'pageSize' => 50,
'start' => '2025-10-01T00:00:00Z',
'end' => '2025-10-31T23:59:59Z',
]);
$events = $response['events'];
// Load more events using nextPageToken
// Send the same filters with every page
$nextResponse = $client->events()->list([
'pageSize' => 50,
'start' => '2025-10-01T00:00:00Z',
'end' => '2025-10-31T23:59:59Z',
'nextPageToken' => $response['nextPageToken'] ?? null,
]);
// Filter by specific calendars
$filteredEvents = $client->events()->list([
'pageSize' => 25,
'calendarIds' => ['google' => ['personal@gmail.com', 'work@company.com']],
]);
// Get recurring event series masters (not expanded)
$masters = $client->events()->list([
'pageSize' => 50,
'singleEvents' => false,
]);
// Fetch initial events with date range filter
var response = await client.Events.ListAsync(new EventListParams
{
PageSize = 50,
Start = new DateTime(2025, 10, 1, 0, 0, 0, DateTimeKind.Utc),
End = new DateTime(2025, 10, 31, 23, 59, 59, DateTimeKind.Utc),
});
// Load more events using NextPageToken
// Send the same filters with every page
var nextResponse = await client.Events.ListAsync(new EventListParams
{
PageSize = 50,
Start = new DateTime(2025, 10, 1, 0, 0, 0, DateTimeKind.Utc),
End = new DateTime(2025, 10, 31, 23, 59, 59, DateTimeKind.Utc),
NextPageToken = response.NextPageToken,
});
// Filter by specific calendars
var filteredEvents = await client.Events.ListAsync(new EventListParams
{
PageSize = 25,
CalendarIds = new Dictionary<string, List<string>>
{
{ "google", new List<string> { "personal@gmail.com", "work@company.com" } }
},
});
// Get recurring event series masters (not expanded)
var masters = await client.Events.ListAsync(new EventListParams
{
PageSize = 50,
SingleEvents = false,
});
import com.mobiscroll.connect.Provider;
import com.mobiscroll.connect.models.EventListParams;
import com.mobiscroll.connect.models.EventsListResponse;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Map;
// Fetch initial events with date range filter
EventsListResponse response = client.events().list(EventListParams.builder()
.pageSize(50)
.start(OffsetDateTime.parse("2025-10-01T00:00:00Z"))
.end(OffsetDateTime.parse("2025-10-31T23:59:59Z"))
.build());
// Load more events using nextPageToken
// Send the same filters with every page
EventsListResponse nextResponse = client.events().list(EventListParams.builder()
.pageSize(50)
.start(OffsetDateTime.parse("2025-10-01T00:00:00Z"))
.end(OffsetDateTime.parse("2025-10-31T23:59:59Z"))
.nextPageToken(response.getNextPageToken())
.build());
// Filter by specific calendars
EventsListResponse filtered = client.events().list(EventListParams.builder()
.pageSize(25)
.calendarIds(Map.of(
Provider.GOOGLE, List.of("personal@gmail.com", "work@company.com")
))
.build());
// Get recurring event series masters (not expanded)
EventsListResponse masters = client.events().list(EventListParams.builder()
.pageSize(50)
.singleEvents(false)
.build());
import (
"time"
mobiscroll "github.com/acidb/mobiscroll-connect-sdks/sdks/go"
)
start, _ := time.Parse(time.RFC3339, "2025-10-01T00:00:00Z")
end, _ := time.Parse(time.RFC3339, "2025-10-31T23:59:59Z")
// Fetch initial events with date range filter
response, err := client.Events().List(ctx, &mobiscroll.EventListParams{
PageSize: mobiscroll.Ptr(50),
Start: &start,
End: &end,
})
if err != nil {
// handle error
return
}
// Load more events using NextPageToken
// Send the same filters with every page
nextResponse, err := client.Events().List(ctx, &mobiscroll.EventListParams{
PageSize: mobiscroll.Ptr(50),
Start: &start,
End: &end,
NextPageToken: response.NextPageToken,
})
// Filter by specific calendars
filtered, err := client.Events().List(ctx, &mobiscroll.EventListParams{
PageSize: mobiscroll.Ptr(25),
CalendarIDs: map[mobiscroll.Provider][]string{
mobiscroll.ProviderGoogle: {"personal@gmail.com", "work@company.com"},
},
})
// Get recurring event series masters (not expanded)
masters, err := client.Events().List(ctx, &mobiscroll.EventListParams{
PageSize: mobiscroll.Ptr(50),
SingleEvents: mobiscroll.Ptr(false),
})
# Fetch initial events with date range filter
response = client.events.list(
page_size: 50,
start: '2025-10-01T00:00:00Z',
end: '2025-10-31T23:59:59Z'
)
# Load more events using next_page_token
# Send the same filters with every page
next_response = client.events.list(
page_size: 50,
start: '2025-10-01T00:00:00Z',
end: '2025-10-31T23:59:59Z',
next_page_token: response.next_page_token
)
# Filter by specific calendars
filtered = client.events.list(
page_size: 25,
calendar_ids: {
Mobiscroll::Connect::Provider::GOOGLE => ['personal@gmail.com', 'work@company.com']
}
)
# Get recurring event series masters (not expanded)
masters = client.events.list(
page_size: 50,
single_events: false
)
- Events are sorted by start time within each page only. Providers fill a page one after another (Google, Microsoft, Apple, then CalDAV), so a later page can contain events that start before events on an earlier page. If the order across pages matters, fetch every page and sort the combined result
- The
pageSizeis shared by all providers, not applied per provider - Send the same
start,end,calendarIdsandsingleEventswith every page — thenextPageTokendoes not carry them - A provider that fails does not fail the request: its events are left out, the response is still
200, andinforeports the error for that provider. Checkinfobefore treating a short or empty page as complete - Maximum
pageSizeis capped at 1000 events - The
nextPageTokentoken is Base64 encoded and should be passed as-is to subsequent requests - Each provider (Google, Microsoft, Apple, CalDAV) tracks its own pagination state independently
- The
nextPageTokenparameter is only included in the response when more events are available - Date strings are automatically normalized to handle malformed ISO 8601 formats before parsing
- The
colorproperty contains the background color value directly (not an object) - Conference links are returned in the
conferencestring field - All event endpoints return events in the unified CalendarEvent format across all supported calendar providers
The conferenceData field stores provider-specific raw meeting metadata.
{
"conferenceData": {
"conferenceId": "abc-defg-hij",
"entryPoints": [
{
"entryPointType": "video",
"uri": "https://meet.google.com/abc-defg-hij"
}
]
}
}
{
"onlineMeeting": {
"joinUrl": "https://teams.microsoft.com/l/meetup-join/...",
"conferenceId": "123456789"
}
}
Create Event
Creates a new calendar event in the specified calendar for the authenticated user.
Supports creating single events or recurring events with recurrence rules. The event is created in the provider's calendar system (Google Calendar, Microsoft Outlook, Apple Calendar, or CalDAV) based on the calendar ID.
Endpoint: POST /event
Request Body
Calendar provider where the event will be created. One of: 'google', 'microsoft', 'apple', or 'caldav'.
The calendar identifier where the event will be created.
The event title/summary.
ISO date string for the event start time.
ISO date string for the event end time.
Event description or notes.
undefinedEvent location (address, meeting room, etc.).
undefinedWhether this is an all-day event.
falseArray of attendee email addresses.
undefinedRecurrence rule for creating a recurring event series. Object with the following properties:
Recurrence frequency: 'DAILY', 'WEEKLY', 'MONTHLY', or 'YEARLY'
Interval between occurrences (e.g., 2 for every 2 weeks)
Number of occurrences. Use either count or until, not both.
Last date of the series, in the iCalendar (RFC 5545) basic format YYYYMMDDTHHMMSSZ in UTC, for example 20261231T235959Z — not ISO 8601 with dashes and colons. For Google, Apple and CalDAV the value is written into the recurrence rule unchanged, so another format can be rejected by the provider or produce a wrong series. Microsoft uses only the date part. Use either count or until, not both: Connect does not check this, and the providers handle the combination differently.
Array of weekday codes: ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']
Array of days of the month (1-31)
Array of months (1-12)
undefinedCustom key-value pairs for additional event data.
undefinedIf you need to associate provider-generated event IDs with your own domain entities, store your external/business ID in custom (for example custom.externalEventId = "icoll-rdv-123").
Conference meeting URL (optional). Backward compatibility is preserved for legacy conference string usage.
undefinedExtra conference options and provider-specific metadata (optional).
Optional. Not used when the event is written — the calendar provider decides the conference type. In the response, conferenceData.provider is the value the provider reports, as described for GET /events.
Set to true to auto-generate a provider meeting link when supported.
When autoGenerate is true, conference and other conferenceData fields are ignored.
undefinedEvent availability: 'free' or 'busy'.
undefinedEvent privacy: 'public', 'private', or 'confidential'.
undefinedEvent status: 'confirmed', 'tentative', or 'cancelled'.
undefinedResponse
Returns 201 Created with the created event as a CalendarEvent object at the root of the body, with no wrapper. As in GET /events, conference is the meeting URL as a string and conferenceData is an object with the conference provider and the provider-specific details. The most used fields:
The event ID — the same identifier GET /events returns and PUT /event and DELETE /event accept. Store it as-is and pass it back unchanged.
The event title.
The event start date/time.
The event end date/time.
Error Responses
A 400 response has a message field with the reason.
- 400 - Bad Request. Missing
provider,calendarId,title,startorend, an invalidprovider, or the provider could not create the event — for exampleCalendar not found,No connected Google account has access to this calendarorFailed to create event - 401 - Unauthorized. Invalid or missing bearer token
- 403 - Forbidden. The access token's scope does not allow writes (
Write access denied for current scope), or no connected account granted calendar access — see Scopes - 500 - Internal Server Error. Unexpected failure
Examples
- REST
- Node.js SDK
- Python SDK
- PHP SDK
- .NET SDK
- Java SDK
- Go SDK
- Ruby SDK
POST /event
Content-Type: application/json
{
"provider": "google",
"calendarId": "primary",
"title": "Team Meeting",
"description": "Discuss project updates",
"start": "2025-11-01T10:00:00Z",
"end": "2025-11-01T11:00:00Z",
"location": "Conference Room A",
"conference": {
"url": "https://meet.google.com/abc-defg-hij",
"provider": "google-meet"
}
}
{
"provider": "google",
"id": "event123abc",
"calendarId": "primary",
"title": "Team Meeting",
"start": "2025-11-01T10:00:00.000Z",
"end": "2025-11-01T11:00:00.000Z",
"allDay": false,
"location": "Conference Room A",
"conference": "https://meet.google.com/abc-defg-hij",
"conferenceData": {
"provider": "addOn",
"entryPoints": [
{ "entryPointType": "video", "uri": "https://meet.google.com/abc-defg-hij" }
],
"conferenceSolution": { "key": { "type": "addOn" } }
},
"attendees": [],
"color": "#9fc6e7",
"availability": "busy",
"privacy": "public",
"status": "confirmed",
"lastModified": "2026-03-10T13:36:08.000Z",
"link": "https://calendar.google.com/calendar/event?eid=...",
"original": {
"kind": "calendar#event",
"etag": "\"3366428166344000\"",
"id": "event123abc",
"summary": "Team Meeting"
...
}
}
POST /event
Content-Type: application/json
{
"provider": "microsoft",
"calendarId": "AAMkAGVmMDEz...",
"title": "Weekly Standup",
"start": "2025-11-01T09:00:00Z",
"end": "2025-11-01T09:30:00Z",
"allDay": false,
"recurrence": {
"frequency": "WEEKLY",
"interval": 1,
"count": 10,
"byDay": ["MO", "WE", "FR"]
}
}
POST /event
Content-Type: application/json
{
"provider": "apple",
"calendarId": "https://caldav.icloud.com/.../calendars/...",
"title": "Conference",
"start": "2025-11-15T00:00:00Z",
"end": "2025-11-16T00:00:00Z",
"allDay": true,
"description": "Annual tech conference"
}
// Create a simple event
const event = await client.events.create({
provider: 'google',
calendarId: 'primary',
title: 'Team Meeting',
description: 'Discuss project updates',
start: '2025-11-01T10:00:00Z',
end: '2025-11-01T11:00:00Z',
location: 'Conference Room A'
});
// Create a recurring event
const recurringEvent = await client.events.create({
provider: 'microsoft',
calendarId: 'AAMkAGVmMDEz...',
title: 'Weekly Standup',
start: '2025-11-01T09:00:00Z',
end: '2025-11-01T09:30:00Z',
allDay: false,
recurrence: {
frequency: 'WEEKLY',
interval: 1,
count: 10,
byDay: ['MO', 'WE', 'FR']
}
});
// Create an all-day event
const allDayEvent = await client.events.create({
provider: 'apple',
calendarId: 'https://caldav.icloud.com/.../calendars/...',
title: 'Conference',
start: '2025-11-15T00:00:00Z',
end: '2025-11-16T00:00:00Z',
allDay: true,
description: 'Annual tech conference'
});
# Create a simple event
event = client.events.create({
'provider': 'google',
'calendarId': 'primary',
'title': 'Team Meeting',
'description': 'Discuss project updates',
'start': '2025-11-01T10:00:00Z',
'end': '2025-11-01T11:00:00Z',
'location': 'Conference Room A',
})
# Create a recurring event
recurring_event = client.events.create({
'provider': 'microsoft',
'calendarId': 'AAMkAGVmMDEz...',
'title': 'Weekly Standup',
'start': '2025-11-01T09:00:00Z',
'end': '2025-11-01T09:30:00Z',
'allDay': False,
'recurrence': {
'frequency': 'WEEKLY',
'interval': 1,
'count': 10,
'byDay': ['MO', 'WE', 'FR'],
},
})
# Create an all-day event
all_day_event = client.events.create({
'provider': 'apple',
'calendarId': 'https://caldav.icloud.com/.../calendars/...',
'title': 'Conference',
'start': '2025-11-15T00:00:00Z',
'end': '2025-11-16T00:00:00Z',
'allDay': True,
'description': 'Annual tech conference',
})
// Create a simple event
$event = $client->events()->create([
'provider' => 'google',
'calendarId' => 'primary',
'title' => 'Team Meeting',
'description' => 'Discuss project updates',
'start' => '2025-11-01T10:00:00Z',
'end' => '2025-11-01T11:00:00Z',
'location' => 'Conference Room A',
]);
// Create a recurring event
$recurringEvent = $client->events()->create([
'provider' => 'microsoft',
'calendarId' => 'AAMkAGVmMDEz...',
'title' => 'Weekly Standup',
'start' => '2025-11-01T09:00:00Z',
'end' => '2025-11-01T09:30:00Z',
'allDay' => false,
'recurrence' => [
'frequency' => 'WEEKLY',
'interval' => 1,
'count' => 10,
'byDay' => ['MO', 'WE', 'FR'],
],
]);
// Create an all-day event
$allDayEvent = $client->events()->create([
'provider' => 'apple',
'calendarId' => 'https://caldav.icloud.com/.../calendars/...',
'title' => 'Conference',
'start' => '2025-11-15T00:00:00Z',
'end' => '2025-11-16T00:00:00Z',
'allDay' => true,
'description' => 'Annual tech conference',
]);
// Create a simple event
var newEvent = await client.Events.CreateAsync(new EventCreateData
{
Provider = Provider.Google,
CalendarId = "primary",
Title = "Team Meeting",
Description = "Discuss project updates",
Start = new DateTime(2025, 11, 1, 10, 0, 0, DateTimeKind.Utc),
End = new DateTime(2025, 11, 1, 11, 0, 0, DateTimeKind.Utc),
Location = "Conference Room A",
});
// Create a recurring event
var recurringEvent = await client.Events.CreateAsync(new EventCreateData
{
Provider = Provider.Microsoft,
CalendarId = "AAMkAGVmMDEz...",
Title = "Weekly Standup",
Start = new DateTime(2025, 11, 1, 9, 0, 0, DateTimeKind.Utc),
End = new DateTime(2025, 11, 1, 9, 30, 0, DateTimeKind.Utc),
AllDay = false,
Recurrence = new RecurrenceRule
{
Frequency = "WEEKLY",
Interval = 1,
Count = 10,
ByDay = new List<string> { "MO", "WE", "FR" },
},
});
// Create an all-day event
var allDayEvent = await client.Events.CreateAsync(new EventCreateData
{
Provider = Provider.Apple,
CalendarId = "https://caldav.icloud.com/.../calendars/...",
Title = "Conference",
Start = new DateTime(2025, 11, 15, 0, 0, 0, DateTimeKind.Utc),
End = new DateTime(2025, 11, 16, 0, 0, 0, DateTimeKind.Utc),
AllDay = true,
Description = "Annual tech conference",
});
import com.mobiscroll.connect.Provider;
import com.mobiscroll.connect.models.CalendarEvent;
import com.mobiscroll.connect.models.EventCreateData;
import com.mobiscroll.connect.models.RecurrenceRule;
import java.time.OffsetDateTime;
import java.util.List;
// Create a simple event
CalendarEvent event = client.events().create(EventCreateData.builder()
.provider(Provider.GOOGLE)
.calendarId("primary")
.title("Team Meeting")
.description("Discuss project updates")
.start(OffsetDateTime.parse("2025-11-01T10:00:00Z"))
.end(OffsetDateTime.parse("2025-11-01T11:00:00Z"))
.location("Conference Room A")
.build());
// Create a recurring event
CalendarEvent recurringEvent = client.events().create(EventCreateData.builder()
.provider(Provider.MICROSOFT)
.calendarId("AAMkAGVmMDEz...")
.title("Weekly Standup")
.start(OffsetDateTime.parse("2025-11-01T09:00:00Z"))
.end(OffsetDateTime.parse("2025-11-01T09:30:00Z"))
.allDay(false)
.recurrence(RecurrenceRule.builder()
.frequency("WEEKLY")
.interval(1)
.count(10)
.byDay(List.of("MO", "WE", "FR"))
.build())
.build());
// Create an all-day event
CalendarEvent allDayEvent = client.events().create(EventCreateData.builder()
.provider(Provider.APPLE)
.calendarId("https://caldav.icloud.com/.../calendars/...")
.title("Conference")
.start(OffsetDateTime.parse("2025-11-15T00:00:00Z"))
.end(OffsetDateTime.parse("2025-11-16T00:00:00Z"))
.allDay(true)
.description("Annual tech conference")
.build());
import (
"time"
mobiscroll "github.com/acidb/mobiscroll-connect-sdks/sdks/go"
)
start, _ := time.Parse(time.RFC3339, "2025-11-01T10:00:00Z")
end, _ := time.Parse(time.RFC3339, "2025-11-01T11:00:00Z")
// Create a simple event
event, err := client.Events().Create(ctx, &mobiscroll.EventCreateData{
Provider: mobiscroll.ProviderGoogle,
CalendarID: "primary",
Title: "Team Meeting",
Description: "Discuss project updates",
Start: start,
End: end,
Location: "Conference Room A",
})
// Create a recurring event
recurringStart, _ := time.Parse(time.RFC3339, "2025-11-01T09:00:00Z")
recurringEnd, _ := time.Parse(time.RFC3339, "2025-11-01T09:30:00Z")
recurringEvent, err := client.Events().Create(ctx, &mobiscroll.EventCreateData{
Provider: mobiscroll.ProviderMicrosoft,
CalendarID: "AAMkAGVmMDEz...",
Title: "Weekly Standup",
Start: recurringStart,
End: recurringEnd,
AllDay: mobiscroll.Ptr(false),
Recurrence: &mobiscroll.RecurrenceRule{
Frequency: "WEEKLY",
Interval: mobiscroll.Ptr(1),
Count: mobiscroll.Ptr(10),
ByDay: []string{"MO", "WE", "FR"},
},
})
// Create an all-day event
allDayStart, _ := time.Parse(time.RFC3339, "2025-11-15T00:00:00Z")
allDayEnd, _ := time.Parse(time.RFC3339, "2025-11-16T00:00:00Z")
allDayEvent, err := client.Events().Create(ctx, &mobiscroll.EventCreateData{
Provider: mobiscroll.ProviderApple,
CalendarID: "https://caldav.icloud.com/.../calendars/...",
Title: "Conference",
Start: allDayStart,
End: allDayEnd,
AllDay: mobiscroll.Ptr(true),
Description: "Annual tech conference",
})
# Create a simple event
event = client.events.create(
provider: Mobiscroll::Connect::Provider::GOOGLE,
calendar_id: 'primary',
title: 'Team Meeting',
description: 'Discuss project updates',
start: '2025-11-01T10:00:00Z',
end: '2025-11-01T11:00:00Z',
location: 'Conference Room A'
)
# Create a recurring event
recurring_event = client.events.create(
provider: Mobiscroll::Connect::Provider::MICROSOFT,
calendar_id: 'AAMkAGVmMDEz...',
title: 'Weekly Standup',
start: '2025-11-01T09:00:00Z',
end: '2025-11-01T09:30:00Z',
all_day: false,
recurrence: Mobiscroll::Connect::RecurrenceRule.new(
frequency: 'WEEKLY',
interval: 1,
count: 10,
by_day: %w[MO WE FR]
)
)
# Create an all-day event
all_day_event = client.events.create(
provider: Mobiscroll::Connect::Provider::APPLE,
calendar_id: 'https://caldav.icloud.com/.../calendars/...',
title: 'Conference',
start: '2025-11-15T00:00:00Z',
end: '2025-11-16T00:00:00Z',
all_day: true,
description: 'Annual tech conference'
)
- The
providerparameter must match the calendar provider of thecalendarId - For recurring events, either
countoruntilcan be specified, but not both - The
byDayproperty is typically used withWEEKLYfrequency - All-day events should have start and end times at midnight (00:00:00)
- The fields present in the returned event, and the contents of
originalandconferenceData, vary by provider (Google, Microsoft, Apple, CalDAV)
Update Event
Updates an existing calendar event.
Supports updating single events, recurring event series, or individual instances of recurring events. For recurring events, you can specify whether to update only the current instance, all following instances, or the entire series.
Endpoint: PUT /event
Request Body
Calendar provider where the event exists. One of: 'google', 'microsoft', 'apple', or 'caldav'.
The event identifier to update — the id returned by GET /events or POST /event.
The calendar identifier containing the event.
The ID of the recurring event series. Required when updating an instance of a recurring event.
undefinedControls which events in a recurring series are updated:
'this'- Update only this specific instance'following'- Update this and all following instances'all'- Update all instances in the series
Only applicable for recurring events. If not specified, updates the single event or series master.
undefinedThe event title/summary.
ISO date string for the event start time.
ISO date string for the event end time.
Event description or notes.
Event location.
Whether this is an all-day event.
Array of attendee email addresses.
Custom key-value pairs for additional event data.
Conference meeting URL update (optional).
Extra conference options and provider-specific metadata update (optional).
Optional. Not used when the event is written — the calendar provider decides the conference type. In the response, conferenceData.provider is the value the provider reports, as described for GET /events.
Set to true to auto-generate a provider meeting link when supported.
When autoGenerate is true, conference and other conferenceData fields are ignored.
google: supportsconferenceandconferenceData.autoGeneratemicrosoft: supportsconferenceData.autoGenerate(Teams link generation); manualconferenceis ignored for online meeting generationappleandcaldav: supportconference;conferenceData.autoGenerateis ignoredconferenceData.autoGeneratetakes precedence overconferencewhen both are providedconferenceData.provideris not used when writing; responses report the provider's own value (for examplehangoutsMeet,addOn,teamsorcaldav)
Event availability: 'free' or 'busy'.
Event privacy: 'public', 'private', or 'confidential'.
Event status: 'confirmed', 'tentative', or 'cancelled'.
Recurrence rule for updating recurring event properties. Same structure as create recurrence.
Response
Returns 200 OK with the updated event as a CalendarEvent object at the root of the body, with no wrapper — the same shape as the Create Event response.
Error Responses
A 400 response has a message field with the reason.
- 400 - Bad Request. Missing
provider,eventIdorcalendarId, an invalidprovider, or the provider could not update the event — for exampleEvent not found,Calendar not foundorFailed to update event - 401 - Unauthorized. Invalid or missing bearer token
- 403 - Forbidden. The access token's scope does not allow writes (
Write access denied for current scope), or no connected account granted calendar access — see Scopes - 500 - Internal Server Error. Unexpected failure
Examples
- REST
- Node.js SDK
- Python SDK
- PHP SDK
- .NET SDK
- Java SDK
- Go SDK
- Ruby SDK
PUT /event
Content-Type: application/json
{
"provider": "google",
"eventId": "event123abc",
"calendarId": "primary",
"title": "Updated Team Meeting",
"start": "2025-11-01T14:00:00Z",
"end": "2025-11-01T15:00:00Z",
"conference": {
"url": "https://meet.google.com/new-room-link",
"provider": "google-meet"
}
}
PUT /event
Content-Type: application/json
{
"provider": "microsoft",
"eventId": "instance456",
"recurringEventId": "series123",
"calendarId": "AAMkAGVmMDEz...",
"updateMode": "this",
"title": "Standup - Special Topic Today",
"start": "2025-11-01T09:00:00Z",
"end": "2025-11-01T10:00:00Z"
}
PUT /event
Content-Type: application/json
{
"provider": "apple",
"eventId": "recurring-event-id",
"calendarId": "https://caldav.icloud.com/.../calendars/...",
"updateMode": "following",
"location": "New Conference Room B"
}
// Update a simple event
const updatedEvent = await client.events.update({
provider: 'google',
calendarId: 'primary',
eventId: 'event123abc',
title: 'Updated Team Meeting',
start: '2025-11-01T14:00:00Z',
end: '2025-11-01T15:00:00Z'
});
// Update a single instance of a recurring event
const updatedInstance = await client.events.update({
provider: 'microsoft',
eventId: 'instance456',
recurringEventId: 'series123',
calendarId: 'AAMkAGVmMDEz...',
updateMode: 'this',
title: 'Standup - Special Topic Today',
start: '2025-11-01T09:00:00Z',
end: '2025-11-01T10:00:00Z'
});
// Update all future occurrences
const updatedFuture = await client.events.update({
provider: 'apple',
eventId: 'recurring-event-id',
calendarId: 'https://caldav.icloud.com/.../calendars/...',
updateMode: 'following',
location: 'New Conference Room B'
});
# Update a simple event
updated_event = client.events.update({
'provider': 'google',
'calendarId': 'primary',
'eventId': 'event123abc',
'title': 'Updated Team Meeting',
'start': '2025-11-01T14:00:00Z',
'end': '2025-11-01T15:00:00Z',
})
# Update a single instance of a recurring event
updated_instance = client.events.update({
'provider': 'microsoft',
'eventId': 'instance456',
'recurringEventId': 'series123',
'calendarId': 'AAMkAGVmMDEz...',
'updateMode': 'this',
'title': 'Standup - Special Topic Today',
'start': '2025-11-01T09:00:00Z',
'end': '2025-11-01T10:00:00Z',
})
# Update all future occurrences
updated_future = client.events.update({
'provider': 'apple',
'eventId': 'recurring-event-id',
'calendarId': 'https://caldav.icloud.com/.../calendars/...',
'updateMode': 'following',
'location': 'New Conference Room B',
})
// Update a simple event
$updatedEvent = $client->events()->update([
'provider' => 'google',
'calendarId' => 'primary',
'eventId' => 'event123abc',
'title' => 'Updated Team Meeting',
'start' => '2025-11-01T14:00:00Z',
'end' => '2025-11-01T15:00:00Z',
]);
// Update a single instance of a recurring event
$updatedInstance = $client->events()->update([
'provider' => 'microsoft',
'eventId' => 'instance456',
'recurringEventId' => 'series123',
'calendarId' => 'AAMkAGVmMDEz...',
'updateMode' => 'this',
'title' => 'Standup - Special Topic Today',
'start' => '2025-11-01T09:00:00Z',
'end' => '2025-11-01T10:00:00Z',
]);
// Update all future occurrences
$updatedFuture = $client->events()->update([
'provider' => 'apple',
'eventId' => 'recurring-event-id',
'calendarId' => 'https://caldav.icloud.com/.../calendars/...',
'updateMode' => 'following',
'location' => 'New Conference Room B',
]);
// Update a simple event
var updatedEvent = await client.Events.UpdateAsync(new EventUpdateData
{
Provider = Provider.Google,
CalendarId = "primary",
EventId = "event123abc",
Title = "Updated Team Meeting",
Start = new DateTime(2025, 11, 1, 14, 0, 0, DateTimeKind.Utc),
End = new DateTime(2025, 11, 1, 15, 0, 0, DateTimeKind.Utc),
});
// Update a single instance of a recurring event
var updatedInstance = await client.Events.UpdateAsync(new EventUpdateData
{
Provider = Provider.Microsoft,
EventId = "instance456",
RecurringEventId = "series123",
CalendarId = "AAMkAGVmMDEz...",
UpdateMode = "this",
Title = "Standup - Special Topic Today",
Start = new DateTime(2025, 11, 1, 9, 0, 0, DateTimeKind.Utc),
End = new DateTime(2025, 11, 1, 10, 0, 0, DateTimeKind.Utc),
});
// Update all future occurrences
var updatedFuture = await client.Events.UpdateAsync(new EventUpdateData
{
Provider = Provider.Apple,
EventId = "recurring-event-id",
CalendarId = "https://caldav.icloud.com/.../calendars/...",
UpdateMode = "following",
Location = "New Conference Room B",
// Title, Start and End are always sent, so pass the event's current values
Title = "Weekly Standup",
Start = new DateTime(2025, 11, 1, 9, 0, 0, DateTimeKind.Utc),
End = new DateTime(2025, 11, 1, 9, 30, 0, DateTimeKind.Utc),
});
import com.mobiscroll.connect.Provider;
import com.mobiscroll.connect.models.CalendarEvent;
import com.mobiscroll.connect.models.EventUpdateData;
import java.time.OffsetDateTime;
// Update a simple event
CalendarEvent updatedEvent = client.events().update(EventUpdateData.builder()
.provider(Provider.GOOGLE)
.calendarId("primary")
.eventId("event123abc")
.title("Updated Team Meeting")
.start(OffsetDateTime.parse("2025-11-01T14:00:00Z"))
.end(OffsetDateTime.parse("2025-11-01T15:00:00Z"))
.build());
// Update a single instance of a recurring event
CalendarEvent updatedInstance = client.events().update(EventUpdateData.builder()
.provider(Provider.MICROSOFT)
.eventId("instance456")
.recurringEventId("series123")
.calendarId("AAMkAGVmMDEz...")
.updateMode("this")
.title("Standup - Special Topic Today")
.start(OffsetDateTime.parse("2025-11-01T09:00:00Z"))
.end(OffsetDateTime.parse("2025-11-01T10:00:00Z"))
.build());
// Update all future occurrences
CalendarEvent updatedFuture = client.events().update(EventUpdateData.builder()
.provider(Provider.APPLE)
.eventId("recurring-event-id")
.calendarId("https://caldav.icloud.com/.../calendars/...")
.updateMode("following")
.location("New Conference Room B")
.build());
import (
"time"
mobiscroll "github.com/acidb/mobiscroll-connect-sdks/sdks/go"
)
start, _ := time.Parse(time.RFC3339, "2025-11-01T14:00:00Z")
end, _ := time.Parse(time.RFC3339, "2025-11-01T15:00:00Z")
// Update a simple event
updatedEvent, err := client.Events().Update(ctx, &mobiscroll.EventUpdateData{
Provider: mobiscroll.ProviderGoogle,
CalendarID: "primary",
EventID: "event123abc",
Title: "Updated Team Meeting",
Start: &start,
End: &end,
})
// Update a single instance of a recurring event
instanceStart, _ := time.Parse(time.RFC3339, "2025-11-01T09:00:00Z")
instanceEnd, _ := time.Parse(time.RFC3339, "2025-11-01T10:00:00Z")
updatedInstance, err := client.Events().Update(ctx, &mobiscroll.EventUpdateData{
Provider: mobiscroll.ProviderMicrosoft,
EventID: "instance456",
RecurringEventID: "series123",
CalendarID: "AAMkAGVmMDEz...",
UpdateMode: "this",
Title: "Standup - Special Topic Today",
Start: &instanceStart,
End: &instanceEnd,
})
// Update all future occurrences
updatedFuture, err := client.Events().Update(ctx, &mobiscroll.EventUpdateData{
Provider: mobiscroll.ProviderApple,
EventID: "recurring-event-id",
CalendarID: "https://caldav.icloud.com/.../calendars/...",
UpdateMode: "following",
Location: "New Conference Room B",
})
# Update a simple event
updated_event = client.events.update(
provider: Mobiscroll::Connect::Provider::GOOGLE,
calendar_id: 'primary',
event_id: 'event123abc',
title: 'Updated Team Meeting',
start: '2025-11-01T14:00:00Z',
end: '2025-11-01T15:00:00Z'
)
# Update a single instance of a recurring event
updated_instance = client.events.update(
provider: Mobiscroll::Connect::Provider::MICROSOFT,
event_id: 'instance456',
recurring_event_id: 'series123',
calendar_id: 'AAMkAGVmMDEz...',
update_mode: 'this',
title: 'Standup - Special Topic Today',
start: '2025-11-01T09:00:00Z',
end: '2025-11-01T10:00:00Z'
)
# Update all future occurrences
updated_future = client.events.update(
provider: Mobiscroll::Connect::Provider::APPLE,
event_id: 'recurring-event-id',
calendar_id: 'https://caldav.icloud.com/.../calendars/...',
update_mode: 'following',
location: 'New Conference Room B'
)
- The
providerparameter must match the calendar provider where the event exists - For recurring events, use
recurringEventIdandupdateModeto control update scope - Only include fields you want to update; omitted fields remain unchanged
- When using
updateMode: 'this'on a recurring event, a new exception instance may be created - The
updateModeparameter behavior may vary slightly between providers
For apple and caldav, "omitted fields remain unchanged" applies only to custom, and only for apple — resending custom on an apple update merges it with the stored value, but on caldav it replaces the stored value instead, so include the complete object each time. Every other omitted field, and any calendar property set directly in Apple Calendar that Connect does not expose (alarms, categories, organizer details), is not preserved and is removed by the update. To avoid losing data on these two providers, read the event with GET /events first and include every field you want kept in the update call, not only the ones you are changing.
Delete Event
Deletes a calendar event.
Supports deleting single events, recurring event series, or individual instances of recurring events. For recurring events, you can specify whether to delete only the current instance, all following instances, or the entire series.
Endpoint: DELETE /event
Request Body
Send the parameters as a JSON body. If the body is empty, they are read from the query string instead, for example DELETE /event?provider=google&calendarId=primary&eventId=event123abc. A non-empty body takes precedence, and the query string is then ignored.
Calendar provider where the event exists. One of: 'google', 'microsoft', 'apple', or 'caldav'.
The event identifier to delete — the id returned by GET /events or POST /event.
The calendar identifier containing the event.
The ID of the recurring event series. Required when deleting an instance of a recurring event.
undefinedControls which events in a recurring series are deleted:
'this'- Delete only this specific instance'following'- Delete this and all following instances'all'- Delete all instances in the series
Only applicable for recurring events. If not specified, deletes the single event or entire series.
undefinedResponse
Returns 204 No Content with an empty body.
Error Responses
A 400 response has a message field with the reason.
- 400 - Bad Request. Missing
provider,eventIdorcalendarId, an invalidprovider, or the provider could not delete the event — for exampleEvent not found,Calendar not foundorFailed to delete event - 401 - Unauthorized. Invalid or missing bearer token
- 403 - Forbidden. The access token's scope does not allow writes (
Write access denied for current scope), or no connected account granted calendar access — see Scopes - 500 - Internal Server Error. Unexpected failure
Examples
- REST
- Node.js SDK
- Python SDK
- PHP SDK
- .NET SDK
- Java SDK
- Go SDK
- Ruby SDK
DELETE /event
Content-Type: application/json
{
"provider": "google",
"eventId": "event123abc",
"calendarId": "primary"
}
HTTP/1.1 204 No Content
DELETE /event
Content-Type: application/json
{
"provider": "microsoft",
"eventId": "instance456",
"recurringEventId": "series123",
"calendarId": "AAMkAGVmMDEz...",
"deleteMode": "this"
}
DELETE /event
Content-Type: application/json
{
"provider": "apple",
"eventId": "recurring-event-id",
"calendarId": "https://caldav.icloud.com/.../calendars/...",
"deleteMode": "all"
}
// Delete a simple event
await client.events.delete({
provider: 'google',
calendarId: 'primary',
eventId: 'event123abc'
});
// Delete a single instance of a recurring event
await client.events.delete({
provider: 'microsoft',
calendarId: 'AAMkAGVmMDEz...',
eventId: 'instance456',
recurringEventId: 'series123',
deleteMode: 'this'
});
// Delete entire recurring series
await client.events.delete({
provider: 'apple',
calendarId: 'https://caldav.icloud.com/.../calendars/...',
eventId: 'recurring-event-id',
deleteMode: 'all'
});
# Delete a simple event
client.events.delete({
'provider': 'google',
'calendarId': 'primary',
'eventId': 'event123abc',
})
# Delete a single instance of a recurring event
client.events.delete({
'provider': 'microsoft',
'calendarId': 'AAMkAGVmMDEz...',
'eventId': 'instance456',
'recurringEventId': 'series123',
'deleteMode': 'this',
})
# Delete entire recurring series
client.events.delete({
'provider': 'apple',
'calendarId': 'https://caldav.icloud.com/.../calendars/...',
'eventId': 'recurring-event-id',
'deleteMode': 'all',
})
// Delete a simple event
$client->events()->delete([
'provider' => 'google',
'calendarId' => 'primary',
'eventId' => 'event123abc',
]);
// Delete a single instance of a recurring event
$client->events()->delete([
'provider' => 'microsoft',
'calendarId' => 'AAMkAGVmMDEz...',
'eventId' => 'instance456',
'recurringEventId' => 'series123',
'deleteMode' => 'this',
]);
// Delete entire recurring series
$client->events()->delete([
'provider' => 'apple',
'calendarId' => 'https://caldav.icloud.com/.../calendars/...',
'eventId' => 'recurring-event-id',
'deleteMode' => 'all',
]);
// Delete a simple event
await client.Events.DeleteAsync(new EventDeleteParams
{
Provider = Provider.Google,
CalendarId = "primary",
EventId = "event123abc",
});
// Delete a single instance of a recurring event
await client.Events.DeleteAsync(new EventDeleteParams
{
Provider = Provider.Microsoft,
CalendarId = "AAMkAGVmMDEz...",
EventId = "instance456",
RecurringEventId = "series123",
DeleteMode = "this",
});
// Delete entire recurring series
await client.Events.DeleteAsync(new EventDeleteParams
{
Provider = Provider.Apple,
CalendarId = "https://caldav.icloud.com/.../calendars/...",
EventId = "recurring-event-id",
DeleteMode = "all",
});
import com.mobiscroll.connect.Provider;
import com.mobiscroll.connect.models.EventDeleteParams;
// Delete a simple event
client.events().delete(EventDeleteParams.builder()
.provider(Provider.GOOGLE)
.calendarId("primary")
.eventId("event123abc")
.build());
// Delete a single instance of a recurring event
client.events().delete(EventDeleteParams.builder()
.provider(Provider.MICROSOFT)
.calendarId("AAMkAGVmMDEz...")
.eventId("instance456")
.recurringEventId("series123")
.deleteMode("this")
.build());
// Delete entire recurring series
client.events().delete(EventDeleteParams.builder()
.provider(Provider.APPLE)
.calendarId("https://caldav.icloud.com/.../calendars/...")
.eventId("recurring-event-id")
.deleteMode("all")
.build());
// Delete a simple event
err := client.Events().Delete(ctx, &mobiscroll.EventDeleteParams{
Provider: mobiscroll.ProviderGoogle,
CalendarID: "primary",
EventID: "event123abc",
})
// Delete a single instance of a recurring event
err = client.Events().Delete(ctx, &mobiscroll.EventDeleteParams{
Provider: mobiscroll.ProviderMicrosoft,
CalendarID: "AAMkAGVmMDEz...",
EventID: "instance456",
RecurringEventID: "series123",
DeleteMode: "this",
})
// Delete entire recurring series
err = client.Events().Delete(ctx, &mobiscroll.EventDeleteParams{
Provider: mobiscroll.ProviderApple,
CalendarID: "https://caldav.icloud.com/.../calendars/...",
EventID: "recurring-event-id",
DeleteMode: "all",
})
# Delete a simple event
client.events.delete(
provider: Mobiscroll::Connect::Provider::GOOGLE,
calendar_id: 'primary',
event_id: 'event123abc'
)
# Delete a single instance of a recurring event
client.events.delete(
provider: Mobiscroll::Connect::Provider::MICROSOFT,
calendar_id: 'AAMkAGVmMDEz...',
event_id: 'instance456',
recurring_event_id: 'series123',
delete_mode: 'this'
)
# Delete entire recurring series
client.events.delete(
provider: Mobiscroll::Connect::Provider::APPLE,
calendar_id: 'https://caldav.icloud.com/.../calendars/...',
event_id: 'recurring-event-id',
delete_mode: 'all'
)
- The
providerparameter must match the calendar provider where the event exists - For recurring events, use
recurringEventIdanddeleteModeto control deletion scope - Deleting with
deleteMode: 'this'creates an exception (cancelled instance) in the series - Deleting with
deleteMode: 'all'removes the entire recurring series - Deleted events cannot be recovered through the API
- The
deleteModeparameter behavior may vary slightly between providers