PulbotDocumentation

Connect Google Calendar and manage appointments through the API


Google Calendar has its own platform and connection, without Gmail permissions. Your assistant uses a Pulbot API key to generate a link; the user grants permissions in Google. Implemented locally on November 2, 2026: Google Cloud configuration, deployment, catalog seeding and real authorization still need verification.

Steps

  1. 1Call GET /api/v1/core/platforms/?search=Google and select Google Calendar. Do not use Google Workspace (Gmail) or Google (Gemini).
  2. 2Send POST /api/v1/resource-connectors/oauth2/start/ with X-API-Key and body {"platform_id":"<calendar_platform_id>"}. Give data.authorize_url to the user; expires_in is its validity, currently 600 seconds.
  3. 3The user selects an account and permissions in Google. The callback creates a Google Calendar resource for the user and organization that generated the link. A Gmail connection does not automatically gain Calendar access.
  4. 4Call GET /api/v1/resource-connectors/ and store the resource ID. Discover actions with GET /api/v1/tools/?category=all&platform=<calendar_platform_id>; inspect their inputs before execution.
  5. 5First test Listar calendarios and Listar eventos. Execute through POST /api/v1/tools/<tool_id>/execute/ with resource_connection_id and the inputs. This is a Pulbot simulation endpoint, but it can operate on real Google data.

Reference

Pulbot permissions
tool:write to generate the link and flow:simulate to execute tools; organization capabilities are evaluated separately. MCP is optional: start_connector_oauth2 works with the Calendar ID after deployment.
calendar.calendarlist.readonly
Requested by default to list calendars.
calendar.events.readonly
Requested by default to read events. Requested does not mean granted: Pulbot records the scope returned by Google.
calendar.events
Optional to create, modify and delete events. Overlaps read access; the user may grant management or read-only access through Google consent.
calendar.events.freebusy
Optional to query busy intervals. A separate permission because calendar.events.readonly and calendar.events do not automatically authorize the freeBusy endpoint.
scopes_extra
Omitted/null: presents all four configured scopes in Google. []: requests only the two default scopes. It requests neither full calendar access nor Gmail permissions. Google controls grouping and prior authorizations.
Tools available in source
Google Calendar - Listar calendarios; Listar eventos; Obtener evento; Consultar disponibilidad; Crear evento; Modificar evento; Eliminar evento. Full names use the Google Calendar - prefix; retrieve IDs from the catalog rather than hardcoding them.
Calendar and pagination
calendar_id defaults to primary. For another calendar use its ID, URL-encoding reserved characters. Calendar and event lists preserve nextPageToken; pass it as pageToken. Empty optional fields are omitted from the query.
Example: list events
{"resource_connection_id":"<connector_id>","calendar_id":"primary","timeMin":"2026-11-03T00:00:00-04:00","timeMax":"2026-11-04T00:00:00-04:00","timeZone":"America/Caracas","singleEvents":true,"orderBy":"startTime"}
Example: availability
{"resource_connection_id":"<connector_id>","time_min":"2026-11-03T13:00:00Z","time_max":"2026-11-03T18:00:00Z","time_zone":"America/Caracas","calendars":[{"id":"primary"}]}
Example: create appointment
{"resource_connection_id":"<connector_id>","calendar_id":"primary","sendUpdates":"none","event":{"id":"appt20261103001","summary":"Cita de prueba","start":{"dateTime":"2026-11-03T09:00:00-04:00","timeZone":"America/Caracas"},"end":{"dateTime":"2026-11-03T09:30:00-04:00","timeZone":"America/Caracas"}}}
Dates and timezone
Use RFC3339 dateTime with an offset and an IANA timeZone. For all-day events use start.date and end.date; the end is exclusive. For recurring events specify timezone and recurrence in event. Pulbot forwards the object; Google validates consistency and permissions.
Update and delete
Modificar evento takes calendar_id, event_id and changes (a partial object). Supplied arrays replace their entire contents. You can send If-Match with the retrieved etag. Eliminar evento takes calendar_id and event_id; status_code 204 without JSON means success.
Guests and notifications
event.attendees specifies guests. sendUpdates accepts none (default), all or externalOnly. all can send real invitations and updates; none does not guarantee that Google sends no email. Do not add guests in tests without authorization.
Retries and idempotency
Include a stable event.id per operation: 5–1024 base32hex characters (a–v, 0–9). After a timeout retrieve that ID before retrying; on 409 reconcile the existing event. No Pulbot idempotency header or local event-content validation was added.
Operator configuration
Enable Calendar API in Google Cloud and configure consent for these scopes. The backend reuses GOOGLE_WORKSPACE_CLIENT_ID and GOOGLE_WORKSPACE_CLIENT_SECRET, not the Google Sign-In client. Calendar does not query the Gmail profile. Redirect URIs must match the environment.
Validation status
All seven actions were tested through the real HTTP interpreter with mocked responses: filters, pagination, structured bodies, timezones, 403, 204, etags and token refresh. Real Google consent, deployment and operations on the user’s account remain pending.

Common errors

403
May indicate denied scopes or insufficient calendar access. freeBusy also needs its specific permission.
409 / 412
409 on creation: retrieve event.id and reconcile. 412: the etag changed; read again before updating or deleting.
Availability
HTTP 200 may include calendars.<id>.errors. Check each calendar’s errors before offering a slot. Querying availability does not reserve the appointment or prevent races.
401 / invalid_state
Check Pulbot credentials, token refresh or link validity. Generate another link if state expired or was consumed.

Next step

Continue with API → Integrate an assistant to combine Calendar, Gmail and WhatsApp. Do not announce production readiness before checking the real flow with test accounts.

¿Necesitas ayuda?