Yesterday's find_events returned every upcoming block on a calendar. But reading a calendar is read-only. Today we flip it: you write to the calendar. One function, one call, and a new event appears in Google Calendar.
I remember find_events came back as a list of dicts — each event had a summary, start, and end. So creating one is just the reverse? I pass a summary, start, end, and it lands on the calendar?
Exactly that. The action is GOOGLECALENDAR_CREATE_EVENT. You pass calendar_id, summary for the title, and start_datetime plus end_datetime as ISO 8601 strings. Here's the core call:
result = toolset.execute_action(Action.GOOGLECALENDAR_CREATE_EVENT, {
"calendar_id": cal_id,
"summary": title,
"start_datetime": start,
"end_datetime": end,
})The parameter is summary, not title? Even though our function argument is called title?
Right — Composio uses Google Calendar's own field name, which is summary. Your function signature can stay clean with title on the outside; you just translate it inside the call. Same trick as recipient_email in send_email — your API, your names. Composio's API, its names.
So I could call create_event("primary", "QBR Prep", "2026-05-01T09:00:00Z", "2026-05-01T10:00:00Z") and it actually shows up in my Google Calendar? Without opening a browser?
It shows up. Refresh your calendar and it's there. That's not a simulation — that's your real account. Here's the full function:
def create_event(cal_id: str, title: str, start: str, end: str) -> dict:
result = toolset.execute_action(Action.GOOGLECALENDAR_CREATE_EVENT, {
"calendar_id": cal_id,
"summary": title,
"start_datetime": start,
"end_datetime": end,
})
print(f"Created event: {title} from {start} to {end}")
return resultCalendar events are just dicts too. I tell it the shape I want and it comes back confirmed. Everything in this track is dicts all the way down.
One rule for write actions: always test on your own calendar first, not a shared team calendar. In a real workflow you'd confirm the details before calling create_event — show the user what you're about to book, get approval, then fire. The function itself is stateless; the confirmation gate lives in the workflow around it.
GOOGLECALENDAR_CREATE_EVENT writes a new event to a Google Calendar and returns the created event dict. It is irreversible — the event appears immediately and must be deleted manually if created by mistake.
| Your arg | Composio key |
|---|---|
cal_id | calendar_id |
title | summary |
start | start_datetime |
end | end_datetime |
summary is Google Calendar's own field name for the event title. Keep your function signature readable; translate inside the call.
Always test against your personal calendar, not a shared team or room calendar. In production workflows, show the event details and confirm before calling create_event. The function is stateless — the confirmation gate belongs in the calling workflow.
Yesterday's find_events returned every upcoming block on a calendar. But reading a calendar is read-only. Today we flip it: you write to the calendar. One function, one call, and a new event appears in Google Calendar.
I remember find_events came back as a list of dicts — each event had a summary, start, and end. So creating one is just the reverse? I pass a summary, start, end, and it lands on the calendar?
Exactly that. The action is GOOGLECALENDAR_CREATE_EVENT. You pass calendar_id, summary for the title, and start_datetime plus end_datetime as ISO 8601 strings. Here's the core call:
result = toolset.execute_action(Action.GOOGLECALENDAR_CREATE_EVENT, {
"calendar_id": cal_id,
"summary": title,
"start_datetime": start,
"end_datetime": end,
})The parameter is summary, not title? Even though our function argument is called title?
Right — Composio uses Google Calendar's own field name, which is summary. Your function signature can stay clean with title on the outside; you just translate it inside the call. Same trick as recipient_email in send_email — your API, your names. Composio's API, its names.
So I could call create_event("primary", "QBR Prep", "2026-05-01T09:00:00Z", "2026-05-01T10:00:00Z") and it actually shows up in my Google Calendar? Without opening a browser?
It shows up. Refresh your calendar and it's there. That's not a simulation — that's your real account. Here's the full function:
def create_event(cal_id: str, title: str, start: str, end: str) -> dict:
result = toolset.execute_action(Action.GOOGLECALENDAR_CREATE_EVENT, {
"calendar_id": cal_id,
"summary": title,
"start_datetime": start,
"end_datetime": end,
})
print(f"Created event: {title} from {start} to {end}")
return resultCalendar events are just dicts too. I tell it the shape I want and it comes back confirmed. Everything in this track is dicts all the way down.
One rule for write actions: always test on your own calendar first, not a shared team calendar. In a real workflow you'd confirm the details before calling create_event — show the user what you're about to book, get approval, then fire. The function itself is stateless; the confirmation gate lives in the workflow around it.
GOOGLECALENDAR_CREATE_EVENT writes a new event to a Google Calendar and returns the created event dict. It is irreversible — the event appears immediately and must be deleted manually if created by mistake.
| Your arg | Composio key |
|---|---|
cal_id | calendar_id |
title | summary |
start | start_datetime |
end | end_datetime |
summary is Google Calendar's own field name for the event title. Keep your function signature readable; translate inside the call.
Always test against your personal calendar, not a shared team or room calendar. In production workflows, show the event details and confirm before calling create_event. The function is stateless — the confirmation gate belongs in the calling workflow.
Create a free account to get started. Paid plans unlock all tracks.