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 voor afsprakenbeheer

Gebruik de Google Calendar API om afspraken programmatisch aan te maken, te lezen en te beheren vanuit je eigen applicatie of script.

Waarom de Google Calendar API?

De Google Calendar API geeft je programmatische toegang tot Google Agenda: je kunt afspraken aanmaken, lezen, bijwerken en verwijderen vanuit je eigen applicatie. Dit is handig voor:

  • CRM-systemen die automatisch agenda-items aanmaken bij een verkoop
  • Booking-applicaties die beschikbaarheid controleren en afspraken vastleggen
  • Geautomatiseerde herinneringen of terugkerende planning
  • Rapporten over vergadertijd en agenda-gebruik
info

Gratis tot een quotum

De Google Calendar API is gratis tot een ruim quotum (zie de FAQ onderaan voor de actuele cijfers). Google heeft aangekondigd dat verbruik boven de limieten later in 2026 kosten kan gaan opleveren via je Google Cloud-factuur. Controleer de actuele limieten en eventuele tarieven altijd in de Google Cloud Console.

Stap 1: API inschakelen en authenticatie opzetten

API activeren in de Cloud Console

  1. Ga naar console.cloud.google.com.
  2. Maak een nieuw project aan of selecteer een bestaand project.
  3. Ga naar API's en services > Bibliotheek en zoek naar Google Calendar API.
  4. Klik op Inschakelen.
  5. Ga naar Inloggegevens en maak de juiste credentials aan: een OAuth 2.0 Client-ID voor applicaties die namens een gebruiker werken, of een Serviceaccount voor server-to-server authenticatie zonder gebruikersinteractie.

OAuth 2.0 of serviceaccount?

Onderstaande tabel helpt je kiezen tussen de twee authenticatiemethodes.

Situatie Kies dit
Je voert acties uit namens een specifieke gebruiker OAuth 2.0
De gebruiker moet zelf toestemming geven OAuth 2.0
Je benadert agenda's van verschillende externe gebruikers OAuth 2.0
Je draait een server-side proces zonder gebruikersinteractie Serviceaccount
Je beheert agenda's binnen je eigen Workspace-domein Serviceaccount met domeinbrede delegatie
Je bouwt een achtergrondproces dat automatisch agenda's beheert Serviceaccount

Stap 2: Authenticatie implementeren (Python)

Onderstaand voorbeeld gebruikt de officiele Google-clientbibliotheken (google-auth-oauthlib en google-api-python-client). Het slaat het token lokaal op zodat de gebruiker niet bij elke run opnieuw hoeft in te loggen.

from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
import os

SCOPES = ['https://www.googleapis.com/auth/calendar']

def get_calendar_service():
    creds = None
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)

    if not creds or not creds.valid:
        flow = InstalledAppFlow.from_client_secrets_file(
            'credentials.json', SCOPES
        )
        creds = flow.run_local_server(port=0)
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    return build('calendar', 'v3', credentials=creds)
warning

Houd je credentials uit je repository

Zet credentials.json en token.json nooit in versiebeheer. Voeg ze toe aan je .gitignore en bewaar geheimen in productie in een secrets manager. Een gelekte refresh token geeft directe toegang tot de agenda.

Stap 3: Afspraken aanmaken

def create_event(service, calendar_id, titel, start_dt, end_dt, deelnemers=None):
    event = {
        'summary': titel,
        'start': {
            'dateTime': start_dt.isoformat(),
            'timeZone': 'Europe/Amsterdam',
        },
        'end': {
            'dateTime': end_dt.isoformat(),
            'timeZone': 'Europe/Amsterdam',
        },
    }

    if deelnemers:
        event['attendees'] = [{'email': email} for email in deelnemers]

    result = service.events().insert(
        calendarId=calendar_id,
        body=event,
        sendUpdates='all'
    ).execute()

    return result.get('htmlLink')

Met sendUpdates='all' krijgen alle deelnemers automatisch een uitnodiging. Gebruik 'none' als je geen mails wilt versturen, bijvoorbeeld bij een bulk-import.

Stap 4: Afspraken ophalen

from datetime import datetime, timezone

def get_upcoming_events(service, calendar_id, max_results=10):
    now = datetime.now(timezone.utc).isoformat()

    events_result = service.events().list(
        calendarId=calendar_id,
        timeMin=now,
        maxResults=max_results,
        singleEvents=True,
        orderBy='startTime'
    ).execute()

    return events_result.get('items', [])

Zet singleEvents=True zodat terugkerende afspraken worden uitgesplitst naar losse instanties. Alleen dan werkt orderBy='startTime' correct.

Beschikbaarheid controleren met FreeBusy

De FreeBusy-query is ideaal om beschikbaarheid te controleren voordat je een afspraak plant. Je krijgt per agenda de bezette tijdsblokken terug, zonder de details van de afspraken zelf.

def check_availability(service, email_addresses, start_dt, end_dt):
    body = {
        'timeMin': start_dt.isoformat(),
        'timeMax': end_dt.isoformat(),
        'timeZone': 'Europe/Amsterdam',
        'items': [{'id': email} for email in email_addresses]
    }

    result = service.freebusy().query(body=body).execute()
    return result.get('calendars', {})
lightbulb

Voorkom dubbele boekingen

Roep FreeBusy aan vlak voordat je een afspraak vastlegt en controleer de teruggegeven busy-blokken. Combineer dit met een korte lock of database-controle in je eigen app, zodat twee gelijktijdige boekingen niet allebei in hetzelfde gat vallen.

Webhooks voor real-time updates

In plaats van periodiek de API te pollen, kun je een notificatiekanaal instellen dat je applicatie een POST-verzoek stuurt zodra er iets in de agenda wijzigt.

def setup_calendar_watch(service, calendar_id, webhook_url):
    channel = {
        'id': 'mijn-unieke-channel-id',
        'type': 'web_hook',
        'address': webhook_url,
    }

    result = service.events().watch(
        calendarId=calendar_id,
        body=channel
    ).execute()

    return result

Het kanaal verloopt na verloop van tijd (de vervaldatum staat in het antwoord). Plan een proces dat het kanaal op tijd vernieuwt en de oude weer afsluit met service.channels().stop(). Je webhook_url moet publiek bereikbaar zijn via HTTPS met een geldig certificaat.

Hoe lang zijn OAuth-tokens geldig?

Access tokens zijn standaard 1 uur geldig. Refresh tokens blijven in productie geldig totdat ze worden ingetrokken, maar vervallen automatisch na zes maanden zonder gebruik. Let op: zolang je OAuth-toestemmingsscherm op de status Testing staat met gebruikerstype Extern, vervalt de refresh token al na 7 dagen. Zet de publicatiestatus op In productie om dat te voorkomen.

Kan ik de API gebruiken voor agenda's van andere gebruikers in mijn organisatie?

Met een serviceaccount en domeinbrede delegatie kun je namens alle gebruikers in je Workspace-domein acties uitvoeren. Dit moet een beheerder eerst goedkeuren in de Admin-console.

Is er een limiet aan het aantal API-aanroepen?

Ja. De Calendar API kent een drempel van ongeveer 1.000.000 verzoeken per dag per project en 600 verzoeken per minuut per gebruiker. Projecten die op of na 1 mei 2026 zijn aangemaakt vallen onder een herziene quotumstructuur, dus controleer de actuele cijfers altijd in de Cloud Console.

Kan ik terugkerende evenementen aanmaken?

Ja, gebruik het veld recurrence in de event-body met RRULE-syntax. Bijvoorbeeld RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR voor een wekelijkse afspraak op maandag, woensdag en vrijdag.

Hoe verwijder ik een afspraak via de API?

Gebruik service.events().delete(calendarId=calendar_id, eventId=event_id).execute(). Verwijderen is permanent. Wil je een afspraak alleen annuleren zonder hem te verwijderen, zet dan het veld status op cancelled.

Waarom krijg ik foutmelding 403 "usage limits exceeded"?

Je raakt dan een snelheidslimiet, meestal de limiet per gebruiker per minuut. Bouw exponentiele back-off met retries in en spreid bulk-bewerkingen over de tijd. Per gebruiker een eigen quota-identifier meesturen helpt om verzoeken eerlijk te verdelen.