Naar inhoud
lightbulb Welkom op de nieuwe kennisbank | We hebben de docs volledig vernieuwd met meer dan 160 features. Bekijk wat nieuw isarrow_forward

Google Calendar API gebruiken in Python

Beheer agenda's en afspraken programmatisch met de Calendar API in Python: events maken, vrij/bezet opvragen en wijzigingen efficient volgen met een syncToken.

Planning is een dankbaar terrein voor automatisering. Met de Calendar API in Python maak je afspraken aan vanuit je eigen systemen, controleer je beschikbaarheid, stuur je uitnodigingen en synchroniseer je agenda's met externe bronnen. Of je nu een boekingssysteem bouwt of resources reserveert, deze API regelt het.

In dit artikel bouw je de kernfuncties stap voor stap op: een afspraak aanmaken, beschikbaarheid opvragen, een boekingsflow ontwerpen en efficient synchroniseren.

Verbinding maken

Je begint met een geauthenticeerde service-client. Voor server-naar-server-scenario's gebruik je doorgaans een serviceaccount met domeinbrede delegatie; voor een gebruikersgerichte app een OAuth-flow met het scope https://www.googleapis.com/auth/calendar.

from googleapiclient.discovery import build

service = build("calendar", "v3", credentials=credentials)

Een afspraak aanmaken

Een event heeft minimaal een begin- en eindtijd nodig. Geef tijdzones expliciet mee om verwarring te voorkomen.

event = {
    "summary": "Kennismakingsgesprek",
    "start": {"dateTime": "2026-06-10T10:00:00", "timeZone": "Europe/Amsterdam"},
    "end": {"dateTime": "2026-06-10T10:30:00", "timeZone": "Europe/Amsterdam"},
    "attendees": [{"email": "klant@voorbeeld.nl"}],
}
service.events().insert(
    calendarId="primary", body=event, sendUpdates="all"
).execute()
lightbulb

Stuur de uitnodiging echt mee

Zet sendUpdates op "all" zodat genodigden automatisch een uitnodiging per e-mail krijgen. Vergeet je dit, dan staat de afspraak wel in de agenda maar weet niemand ervan. Voor stille wijzigingen gebruik je "none".

Beschikbaarheid opvragen

Voordat je inplant, wil je weten of iemand vrij is. De freebusy().query()-aanroep geeft per agenda de bezette blokken terug.

body = {
    "timeMin": "2026-06-10T08:00:00Z",
    "timeMax": "2026-06-10T18:00:00Z",
    "items": [{"id": "collega@jouwdomein.nl"}],
}
resultaat = service.freebusy().query(body=body).execute()
bezet = resultaat["calendars"]["collega@jouwdomein.nl"]["busy"]
info

Freebusy respecteert privacy

Freebusy toont alleen of een tijdslot bezet is, niet de details van de afspraken. Dat is precies de bedoeling: je respecteert de privacy van de agenda terwijl je toch slim kunt plannen.

Een boekingsflow opbouwen

Een typisch boekingssysteem combineert beschikbaarheid checken en inplannen. De flow ziet er meestal zo uit:

  1. De klant kiest een gewenste datum.
  2. Je vraagt freebusy().query() op voor de betrokken agenda's.
  3. Je toont alleen de vrije tijdsloten.
  4. De klant kiest een slot.
  5. Je maakt het event aan met events().insert() en stuurt uitnodigingen.
  6. Bij annulering verwijder je het event met events().delete().
lightbulb

Voorkom dubbele boekingen

Tussen het tonen van een vrij slot en het bevestigen kan een ander iemand hetzelfde tijdstip kiezen. Vraag de beschikbaarheid daarom nog één keer op vlak voordat je insert() aanroept, of gebruik een korte reservering in je eigen database.

Efficient synchroniseren

Wil je een agenda gespiegeld houden in je eigen systeem? Haal niet steeds alles op, maar gebruik incrementele synchronisatie met een syncToken.

Zo synchroniseer je incrementeel

  1. Doe een eerste volledige events().list() en blader desnoods door alle pagina's heen.
  2. Bewaar de nextSyncToken uit het laatste antwoord (die staat alleen op de laatste pagina).
  3. Bij de volgende sync geef je die syncToken mee aan events().list().
  4. Je krijgt nu alleen de gewijzigde en verwijderde events terug.
  5. Bewaar de nieuwe nextSyncToken voor de volgende ronde.
warning

Vang een verlopen syncToken op

Een syncToken kan verlopen, bijvoorbeeld na lange inactiviteit. De API geeft dan een 410-fout (GONE). Vang die op, wis je lokale opslag en doe een volledige hersynchronisatie zonder token, anders loopt je gespiegelde agenda uit de pas.

Veelgestelde vragen

Hoe maak ik een terugkerende afspraak?

Voeg een recurrence-veld toe met een RRULE, bijvoorbeeld ["RRULE:FREQ=WEEKLY;COUNT=10"] voor tien wekelijkse herhalingen. Het veld is een lijst, zodat je meerdere regels kunt combineren.

Kan ik een Google Meet-link toevoegen?

Ja. Zet conferenceData in de body met een uniek createRequest, en geef conferenceDataVersion=1 mee aan insert(). De API genereert dan automatisch een Meet-link.

Welke calendarId gebruik ik?

Gebruik primary voor de hoofdagenda van de gebruiker, of het e-mailadres van een specifieke agenda waartoe je toegang hebt. Een gedeelde of resource-agenda heeft een eigen lange id die je via calendarList().list() opvraagt.

Hoe vermijd ik dubbele afspraken bij herhaalde runs?

Geef een eigen id mee of gebruik het iCalUID-veld om idempotent te werken, zodat een tweede insert dezelfde afspraak niet dupliceert. Bij een botsing krijg je dan een 409-fout die je kunt negeren.

Waarom krijg ik een 403 of 401?

Een 401 wijst meestal op een verlopen of ontbrekend token; ververs je credentials. Een 403 betekent vaak dat het juiste scope ontbreekt of dat het serviceaccount geen toegang heeft tot de agenda. Deel de agenda expliciet met het serviceaccount of stel domeinbrede delegatie correct in.

Hoe ga ik om met rate limits?

De API hanteert quota per project en per gebruiker. Vang een 403 of 429 met userRateLimitExceeded op en wacht met exponentiële back-off voordat je het opnieuw probeert.

Met de Calendar API in Python automatiseer je planning betrouwbaar, van losse afspraken tot een volledig boekingssysteem.