Calendar sync for your product, from $49 a month
One API to read and write your users’ Google, Microsoft and Apple iCloud calendars. Hosted connect pages, free/busy, events with guests, repeats and meeting links, and signed webhooks.One API to read and write your users’ Google, Microsoft and Apple iCloud calendars.
- GoogleAvailable
- MicrosoftAvailable
- Apple iCloudAvailable
Run it in your project folder. It signs you in, creates a test application, writes your keys and teaches your AI coding agent the calmonkey commands.
npx calmonkey init
# Then your agent (or you) can run:
calmonkey events list
calmonkey freebusy
calmonkey docs search webhooks
# No terminal? Use the MCP server:
# https://mcp.calmonkey.com/mcp
Send your user to the hosted connect page. They pick Google, Microsoft or iCloud and come back with a code.
# 1. Redirect the user
https://app.calmonkey.com/oauth/authorize
?response_type=code
&client_id=$CLIENT_ID
&redirect_uri=https://yourapp.example/callback
&scope=read_write
&state=$STATE
# 2. Swap the code for tokens
curl https://api.calmonkey.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "$CLIENT_ID",
"client_secret": "$CLIENT_SECRET",
"grant_type": "authorization_code",
"code": "$CODE",
"redirect_uri": "https://yourapp.example/callback"
}'
The same shape for every provider.
curl https://api.calmonkey.com/v1/calendars \
-H "Authorization: Bearer $ACCESS_TOKEN"
{
"calendars": [
{
"provider_name": "google",
"profile_name": "dana@example.com",
"calendar_id": "cal_8Kq2mVx4T1",
"calendar_name": "Dana",
"calendar_primary": true,
"calendar_readonly": false,
"calendar_deleted": false
}
]
}
Busy times across the calendars you ask for. Events your app wrote are left out unless you ask for them.
curl "https://api.calmonkey.com/v1/free_busy?tzid=Australia/Melbourne\
&from=2026-11-02&to=2026-11-03" \
-H "Authorization: Bearer $ACCESS_TOKEN"
{
"pages": { "current": 1, "total": 1 },
"free_busy": [
{
"calendar_id": "cal_8Kq2mVx4T1",
"start": "2026-11-01T22:00:00Z",
"end": "2026-11-02T00:00:00Z",
"free_busy_status": "busy"
}
]
}
Create or update by your own id. Sending it twice leaves one event.
curl https://api.calmonkey.com/v1/calendars/cal_8Kq2mVx4T1/events \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"event_id": "booking-1042",
"summary": "Lash lift with Grace",
"start": "2026-11-02T00:00:00Z",
"end": "2026-11-02T01:00:00Z",
"tzid": "Australia/Melbourne",
"location": { "description": "12 Harbour St" }
}'
HTTP/1.1 202 Accepted
Three calendars in, one answer out
A user’s Monday across three connected calendars, and what GET /v1/free_busy returns. The booking your own app wrote at 11 is left out, so you can move it without it blocking itself.
Every calendar, one set of calls
Each calendar connects and reports changes in its own way. Your code sees the same calendars, events and notifications for all of them.
- Google CalendarPersonal Gmail and Google Workspace. Guests invited by Google, with their replies; repeating events; Google Meet links; changes pushed as they happen.
- Microsoft 365Work and school accounts. Guests invited by Microsoft, with their replies; repeating events; Microsoft Teams links on calendars that allow online meetings; changes pushed as they happen. No on-premises Exchange.
- Outlook.comPersonal Outlook.com, Hotmail and Live accounts. Guests; repeating events; Microsoft Teams links; changes pushed as they happen.
- Apple iCloudConnects with an app-specific password. Guests get Apple’s invitation, and their answers to it come back; repeating events. Changes are checked every five minutes.
- Application calendarsHosted by CalMonkey, with no sign-in and no real account. Repeating events, and guests stored without any email sent. For tests and CI.
How it works
Your user connects a calendar
Send them to CalMonkey’s hosted connect page. They choose a provider, approve access, and land back in your product with a code you exchange for tokens. You build no provider sign-in screens.
You call one API
Read their events, live, with their title, times, place, guests and replies, meeting links and repeats, or just free/busy. Write events by your own id, and get a webhook when anything changes. The same calls for Google, Microsoft and iCloud.
CalMonkey tells you what changed
When the user adds or moves something in their own calendar, your callback gets a signed notification. Changes you made through the API do not come back as noise.
What the API does
The whole job of working with your users’ calendars, in one API: when they are busy, events with guests, repeats and meeting links, and word of every change.
- Free/busy that ignores your own events
- Busy times are worked out the same way for every provider. Events your app wrote are left out by default, so a booking never blocks its own slot when you move it.
- Writes by your id, safe to repeat
- Create, update and delete events with your own event id. Sending the same event twice leaves one event in the calendar, and your next read already shows it.
- Guests, invited by the calendar itself
- Add guests to an event and Google, Microsoft or Apple sends the invitation, the updates and the cancellation from the user’s own calendar. Their replies come back through the API, next to the guest list.
- Repeating events, down to one occurrence
- Write a daily, weekly, monthly or yearly series with one call. Skip a single date or give one occurrence its own time, and the series keeps its local time when the clocks change.
- Meeting links from the calendar
- One field asks the calendar for its own link: Google Meet on Google calendars, Microsoft Teams on Microsoft 365 and Outlook.com. The join address comes back with the event.
- Signed webhooks with replay protection
- Each notification is signed with a time stamp and a secret per channel, and carries a delivery id that stays the same across retries. Failed deliveries are retried for about 23 hours.
- Application calendars for tests
- Calendars that live only in CalMonkey, created with one call and no human sign-in. Run your whole test suite against them, in CI, without touching a real account.
- Your own brand on the sign-in screen
- On the Scale plan, Google’s and Microsoft’s sign-in screens can name your app instead of CalMonkey, on a connect address of your own. You set it up in the dashboard whenever you are ready.
- Endpoints existing integrations already know
- The v1 API uses paths, parameters, response shapes and error shapes that many existing calendar integrations already call (the endpoints are listed below). Such an integration moves over by changing the host and credentials, then asking users to reconnect.
The endpoints existing integrations already know
GET /oauth/authorizePOST /oauth/tokenPOST /oauth/token/revokePOST /v1/application_calendarsGET /v1/calendarsPOST /v1/calendars/{id}/eventsDELETE /v1/calendars/{id}/eventsGET /v1/eventsGET /v1/free_busyGET /v1/channelsPOST /v1/channelsDELETE /v1/channels/{id}GET /v1/profilesGET /v1/accountGET /v1/userinfoPOST /v1/link_tokens
Checked by a contract script that compares status codes, response shapes and error wording with recorded reference responses.
What CalMonkey does with calendar data
When someone connects a Google, Microsoft or Apple iCloud calendar to an app that uses CalMonkey, CalMonkey asks for access to their events and their list of calendars. It uses that access only to give that app the calendar features the person asked for.
- ReadThe calendar list and the person’s events: when they are busy, so the app can offer free times and avoid clashes, and who is invited to an event and how they replied.
- WriteOnly the events the connected app creates, such as a booking, and later changes or cancellations of them. When the app adds guests or a meeting link to one of its events, the person’s calendar sends the invitations and makes the link.
- Notice changesWhen something in a connected calendar changes, so the app stays up to date.
- NeverSold, used for advertising, shared with anyone except the connected app, or used to train AI models. Google data follows Google’s Limited Use rules.
- Disconnect any timeIn the connected app or in the Google, Microsoft or Apple account settings. CalMonkey then deletes the stored access and events.
Pricing by connected account
A flat monthly plan with a number of connected accounts included, and a per-account price above that. No per-request fees.
Developer
$0US / month
Build and test your integration.
5 connected accounts
A fixed limit. No charge for going over.
- Unlimited application calendars for tests
- A “Test mode” label on the connect page
- Request log kept for 7 days
Starter
$49US / month
Go to production.
100 connected accounts
Then $0.40 for each extra account.
- No test label on the connect page
- Google, Microsoft and Apple iCloud connections
- Request log kept for 30 days
Growth
$199US / month
For a growing user base.
750 connected accounts
Then $0.25 for each extra account.
- Everything in Starter
- A lower price for each extra account
Scale
$499US / month
For larger user bases.
3,000 connected accounts
Then $0.15 for each extra account.
- Everything in Growth
- Your own brand on the sign-in screen
- Priority support
- Signed data processing agreement
A connected account is one of your users with at least one real calendar account (Google, Microsoft or iCloud) linked at any time in the month. Application calendars used for tests are not counted.
Prices are in US dollars and exclude tax.
Questions
Can I use CalMonkey in production today?
Yes. Google Calendar, Microsoft 365, Outlook.com and Apple iCloud connections, the API and application calendars are all available. Sign up, create your application in the dashboard and follow the quickstart.
Build and test on the free Developer plan, then choose a paid plan in the dashboard when you go to production.
What counts as a connected account?
A connected account is one of your users with at least one real calendar account (Google, Microsoft or iCloud) linked at any time in the month. Application calendars used for tests are not counted.
A user who links two calendar accounts is still one connected account.
Can I move an existing calendar integration over?
Often with a change of host and credentials. For the endpoints listed above, CalMonkey’s v1 API uses the paths, parameter names, response shapes and error shapes that many existing calendar integrations already call, including attendees, recurring events and conferencing on events. An application can also switch on a compatibility mode that matches finer details, such as the webhook signature header.
Connections cannot be transferred, so your users connect their calendars again. The migration guide in the docs lists every difference.
Who sends the invitations when my app adds guests?
The user’s own calendar does. On Google Calendar, Microsoft 365, Outlook.com and Apple iCloud, the guests you add get the invitation, every update and the cancellation from Google, Microsoft or Apple, with the user as the organiser, exactly as if the user had invited them. CalMonkey sends no email of its own.
Guests answer in their own calendar or mail. Their replies come back through the API with the event, and a webhook tells you when one arrives. On iCloud, a guest’s answer comes back when they answer from Apple’s invitation.
Can I change one occurrence of a repeating event?
Yes. A repeating event is written once, with a rule. After that you can skip one date or give one occurrence a different time or title with a single call, and the rest of the series stays as it is. Changing the series later keeps the occurrences you changed.
Repeating events work on Google, Microsoft and Apple iCloud calendars and on application calendars.
How do iCloud calendars connect?
Apple has no sign-in flow for calendars, so the user creates an app-specific password in their Apple account and enters it on CalMonkey’s connect page. CalMonkey stores it encrypted and uses it only for calendars. Changes are picked up by checking every five minutes.
Where is the data, and what do you keep?
Everything is stored in Australia, in accordance with Australian law. For each connected calendar CalMonkey keeps the calendar’s name and the events from 42 days back to 201 days ahead: their times and status, and, encrypted, their title, description, location, guests with their replies, and meeting link.
When a connection is revoked, its events are deleted straight away and its credentials and calendars soon after.
How do webhooks behave?
You register an https callback per connected account. CalMonkey sends a signed notification when something changes in the calendars you named, and you then read what changed. You are not notified about changes your own app made through the API.
A delivery that fails is retried at growing intervals for about 23 hours. A reply of 410 closes the channel.
How does billing work?
The Developer plan is free. Paid plans are billed monthly in advance in US dollars, and connected accounts above your plan’s allowance are billed at the end of the month. Payments are handled by Stripe.
You choose, change or cancel your plan in the dashboard. A cancelled plan runs to the end of the period already paid for.
Start building
Sign up with your Google or Microsoft work account, create an application and make your first call in a few minutes.
- What you getAPI credentials, application calendars for your tests, Google, Microsoft and iCloud connections, a request log and a webhook log.
- What it costsNothing on the Developer plan. Paid plans start at $49 a month.
Would rather talk first? Tell us what you are building.

