Skip to content

Instantly share code, notes, and snippets.

@tyler-dane
Last active January 24, 2026 02:40
Show Gist options
  • Select an option

  • Save tyler-dane/f90243ecc79743943256a65685207c9a to your computer and use it in GitHub Desktop.

Select an option

Save tyler-dane/f90243ecc79743943256a65685207c9a to your computer and use it in GitHub Desktop.
Google Calendar API: Sync Feature PRD

PRD: Google Calendar Sync API

Document Type: Product Requirements Document (PRD)
TDD: https://gist.github.com/tyler-dane/5d18ecdab29edeabf526ee55cd584b32
Document Status: Draft
Author: fullstack.zip
Last Updated: January 2026
Reviewers: AI
Context: For an article on https://newsletter.fullstack.zip


1. Requirement Overview

The Calendar Sync API enables third-party calendar applications to synchronize event data with Google Calendar through a robust, real-time synchronization protocol. This system provides push-based change notifications, incremental synchronization capabilities, and conflict resolution mechanisms that allow API clients to maintain accurate, up-to-date copies of user calendar data without resorting to expensive full-calendar polling.

This capability is critical to Google Calendar's ecosystem strategy: by providing best-in-class sync primitives, we enable a thriving third-party application ecosystem that increases user engagement with Google Calendar as their authoritative calendar source while respecting user privacy and maintaining system reliability at scale.


2. Functional Requirements

2.1 Push-Based Notifications

API clients must receive real-time change notifications without resorting to polling. The system implements a webhook-based push notification architecture.

Requirement Specification
Notification Delivery Webhook POST to client-registered HTTPS endpoint
Notification Latency Target: < 5 seconds from change commit to webhook delivery
Payload Format Lightweight notification (change signal only, not full event data)
Channel Expiration Configurable TTL up to 30 days; clients must renew before expiration
Delivery Guarantees At-least-once delivery; clients must handle duplicate notifications
Verification Domain verification required; signature validation on all payloads

2.2 Incremental Sync

Synchronization must be efficient, transferring only changed data since the last sync operation.

Requirement Specification
Sync Token Opaque, server-issued token representing sync state
Token Validity Minimum 7 days; may be invalidated earlier under exceptional circumstances
Delta Response Only events modified since token issuance
Deleted Events Returned with status: "cancelled" in delta response
Token Invalidation HTTP 410 Gone triggers full sync requirement
Page Token Separate from sync token; used for paginating large result sets

Incremental Sync Request:

GET /calendar/v3/calendars/primary/events?syncToken=CPDAlvWDx4oCEPDAlvWDx4oCGAEggL3t

2.3 Cross-Platform Support

The API must function consistently across all client platforms.

Platform Transport Authentication Push Support
Web HTTPS REST OAuth 2.0 Webhook to server
iOS HTTPS REST OAuth 2.0 Webhook → APNs relay
Android HTTPS REST OAuth 2.0 Webhook → FCM relay
Desktop HTTPS REST OAuth 2.0 Webhook to local server or long-poll fallback

Platform-Specific Considerations:

  • Mobile clients should implement a server-side webhook receiver that relays to FCM/APNs, as direct webhook delivery to mobile devices is not reliable
  • Desktop clients may implement a local HTTP server for webhook receipt or use Server-Sent Events (SSE) as a fallback (future consideration)
  • All platforms must implement exponential backoff for retry logic and respect Retry-After headers

2.4 Calendar Scope

The API must support all calendar types within a user's account.

Calendar Type Identifier Pattern Sync Support Write Support
Primary primary or user email Full Full
Sub-calendars Calendar ID (hash) Full Full
Shared calendars Calendar ID (hash) Full Per ACL
Public calendars Calendar ID (hash) Read-only None
Resource calendars resource.calendar.google.com Full Per ACL
Holiday calendars #[email protected] Read-only None

Calendar List Endpoint:

GET /calendar/v3/users/me/calendarList

Returns all calendars the user has added to their list, with access roles and sync capabilities indicated per calendar.

2.5 Consistency Model

The system operates under an eventual consistency model with defined propagation bounds.

Metric Target Maximum
Read-after-write (same region) < 1 second 3 seconds
Cross-region propagation < 3 seconds 10 seconds
Push notification delivery < 5 seconds 30 seconds
Sync token freshness Real-time 5 seconds staleness

Consistency Guarantees:

  • Changes are durably committed before API response returns
  • Sync tokens are monotonically advancing within a calendar
  • Event sequence numbers (sequence field) provide per-event ordering
  • updated timestamps use server time, not client time

2.6 Reliability

The system must be highly available with graceful degradation under load.

Requirement Specification
Availability Target 99.95% monthly uptime
Degradation Strategy Shed push notifications before sync; shed writes before reads
Circuit Breaker Per-client rate limiting with automatic recovery
Regional Failover Automatic failover to secondary region within 60 seconds
Data Durability 99.999999999% (11 nines) for committed event data

3. Use Cases

3.1 Incremental Sync After Remote Change

Scenario: A user modifies an event in Google Calendar (web or mobile), and a third-party calendar app needs to reflect this change.

Implementation Considerations:

  • Clients should debounce rapid webhook notifications (coalesce within 500ms window)
  • The webhook only signals that changes exist; client must fetch actual changes
  • Clients must handle the case where multiple changes occurred since last sync
  • If sync token is invalid (410), client must perform full sync and rebuild local state

Error Handling:

Error Response Client Action
410 Gone Sync token expired Clear local syncToken, perform full sync
429 Too Many Requests Rate limited Exponential backoff per Retry-After header
503 Service Unavailable Temporary outage Retry with exponential backoff
401 Unauthorized Token expired Refresh OAuth token, retry

3.2 Access Revocation Handling

Scenario: A user revokes OAuth access for a calendar app via Google Account settings. The app must detect this and clean up appropriately.

Detection Mechanisms:

Mechanism Trigger Response Time
API Call Failure 401 with invalid_grant Immediate
Push Channel Termination Channel stopped server-side < 1 minute
Token Introspection Explicit check via tokeninfo endpoint On-demand

Required Client Behavior:

  1. Detect revocation via 401 response with error invalid_grant or invalid_token
  2. Clear stored credentials including access token, refresh token, and sync tokens
  3. Purge cached calendar data per data retention policy (user expectation)
  4. Stop all sync operations and pending webhook listeners
  5. Present re-authentication flow if user returns to the app

Revocation Notification Payload:

{
  "kind": "calendar#notification",
  "resourceId": "calendar-resource-id",
  "channelId": "client-channel-uuid",
  "resourceState": "sync_disabled",
  "reason": "access_revoked"
}

3.3 Initial Full Sync

Scenario: A user connects their Google account to a new calendar app for the first time. The app needs to import all existing events.

Pagination Parameters:

Parameter Default Maximum Description
maxResults 250 2500 Events per page
pageToken Continuation token
timeMin Lower bound for event start
timeMax Upper bound for event start
singleEvents false Expand recurring events

Best Practices:

  • Use showDeleted=false for initial sync (no need for tombstones)
  • Set reasonable timeMin (e.g., 1 year ago) to limit historical data
  • Use singleEvents=true if app cannot handle recurrence rules
  • Process pages in order; final page contains authoritative nextSyncToken
  • Implement progress indication for user (may take 30+ seconds for large calendars)

Time Boundaries Recommendation:

timeMin: NOW - 6 months
timeMax: NOW + 2 years

3.4 Conflict Resolution

Scenario: A user modifies an event in both Google Calendar and a third-party app while offline. When connectivity is restored, the changes conflict.

Conflict Detection:

Conflicts are detected using the sequence number and updated timestamp on each event. The API uses optimistic concurrency control.

Field Purpose
sequence Increments on each organizer modification
etag Opaque version identifier for conditional requests
updated Server timestamp of last modification

Recommended Implementation:

PATCH /calendar/v3/calendars/primary/events/{eventId}
If-Match: "etag-value-from-last-fetch"
Content-Type: application/json

{
  "summary": "Updated Meeting Title",
  "sequence": 3
}

Response Codes:

Code Meaning Client Action
200 Update succeeded Store new etag, continue
412 Precondition failed (conflict) Fetch latest, resolve, retry
409 Conflict (sequence number) Increment sequence, retry

Merge Strategy Guidance:

For field-level merging, clients should consider:

Field Merge Strategy
summary Last-writer-wins or user choice
start/end Last-writer-wins (time changes are significant)
description Concatenate with conflict markers or user choice
attendees Union of both lists
reminders Local preference (user-specific)

3.5 Batch Operations

Scenario: A user imports events from another calendar system (e.g., Outlook, iCal file), requiring efficient bulk creation.

Batch Limits:

Limit Value Notes
Requests per batch 50 Hard limit
Batch request size 1 MB Total payload
Batches per second 10 Per-user rate limit
Events per calendar per day 10,000 Import quota

Best Practices:

  • Pre-deduplicate imports using iCalUID to avoid conflicts
  • Use conferenceDataVersion=1 only if importing video conference data
  • Set sendUpdates=none for bulk imports to avoid notification spam
  • Implement client-side rate limiting (100ms between batches minimum)
  • Track import progress and allow resume on failure

Import Deduplication:

POST /calendar/v3/calendars/primary/events?conferenceDataVersion=0
Content-Type: application/json

{
  "iCalUID": "[email protected]",
  "summary": "Imported Event",
  ...
}

If an event with the same iCalUID exists, the API returns 409 Conflict, allowing the client to decide whether to update or skip.


4. Non-Functional Requirements

4.1 API Response Latency

Endpoint Category p50 p95 p99
Single event read 50ms 150ms 300ms
Single event write 100ms 300ms 500ms
Event list (≤100 events) 100ms 300ms 600ms
Event list (≤1000 events) 300ms 800ms 1500ms
Batch request (50 ops) 500ms 1500ms 3000ms
Calendar list 75ms 200ms 400ms
Watch channel setup 100ms 300ms 500ms

4.2 System Availability

Metric Target Measurement
Monthly uptime 99.95% (total_minutes - downtime_minutes) / total_minutes
Error rate (5xx) < 0.1% 5xx_responses / total_responses
Planned maintenance < 4 hours/year Announced 7 days in advance
Regional failover < 60 seconds Time to redirect traffic

Uptime Calculation:

  • Downtime = API returns 5xx or is unreachable for > 1 minute
  • Partial degradation (elevated latency) does not count as downtime
  • Maintenance windows excluded if announced per SLA

4.3 Rate Limiting and Quotas

Quota Type Default Limit Increase Available
Queries per day 1,000,000 Yes (request)
Queries per user per second 10 No
Queries per user per 100 seconds 500 No
Push channels per user 100 Yes (request)
Events per calendar 100,000 No
Calendars per user 10,000 No
Batch requests per second 10 No

Rate Limit Response:

{
  "error": {
    "code": 429,
    "message": "Rate Limit Exceeded",
    "errors": [{
      "domain": "usageLimits",
      "reason": "rateLimitExceeded"
    }]
  }
}

Headers included: Retry-After: 30 (seconds until retry is allowed)

4.4 Data Retention and Token Expiration

Data Type Retention Notes
Event data Indefinite Until user deletes
Deleted events (tombstones) 30 days For sync purposes
Sync tokens 7 days minimum May be invalidated earlier
Push channel registrations Per TTL (max 30 days) Must be renewed
API request logs 30 days For debugging
Audit logs 6 months For compliance

Token Expiration Handling:

  • Sync token expiration returns HTTP 410 Gone
  • Push channel expiration sends termination notification
  • OAuth tokens follow standard Google OAuth expiration (1 hour access, rotating refresh)

4.5 Security Requirements

Authentication:

Requirement Specification
Protocol OAuth 2.0
Token type Bearer token
Token lifetime 1 hour (access), rotating (refresh)
PKCE Required for mobile/desktop apps

Transport Security:

Requirement Specification
Protocol TLS 1.2+ required
Certificate validation Required; no self-signed
HSTS Enforced
Certificate pinning Recommended for mobile apps

Webhook Security:

Requirement Specification
Domain verification Required via Search Console
HTTPS Required; no HTTP callbacks
Signature validation HMAC-SHA256 signature in header
IP allowlisting Optional; Google IP ranges published

Data Encryption:

State Encryption
In transit TLS 1.2+
At rest AES-256 (Google-managed keys)
Client-side Optional (not supported by API)

5. Success Metrics

5.1 Primary KPIs

Metric Target Measurement Method
Sync latency (change → notification) p50 < 3s, p99 < 10s End-to-end instrumentation
API availability 99.95% monthly Uptime monitoring
Push notification delivery rate > 99.5% Delivered / Sent
Incremental sync efficiency > 95% delta syncs Delta syncs / Total syncs
Client adoption rate 80% of top 100 apps Developer console metrics

5.2 Secondary KPIs

Metric Target Measurement Method
Error rate by endpoint < 0.5% client errors, < 0.1% server errors API logs
Average sync payload size < 50 KB Response size aggregation
Full sync frequency < 1 per user per week Sync token invalidation rate
Batch operation success rate > 99% Batch response analysis
OAuth token refresh success > 99.9% Auth server metrics

5.3 Developer Experience KPIs

Metric Target Measurement Method
Time to first successful sync < 30 minutes Developer onboarding funnel
Documentation satisfaction > 4.0/5.0 Developer survey
Support ticket volume < 100/month Support system
API client library adoption > 70% User-agent analysis

5.4 Monitoring Dashboard

Key metrics to display in real-time:

  • Request volume (QPS) by endpoint
  • Latency distribution (p50, p95, p99)
  • Error rate by type (4xx, 5xx)
  • Push notification queue depth
  • Active push channels
  • Rate limit triggers per minute
  • Regional traffic distribution

6. Out of Scope

The following items are explicitly not covered by this PRD:

Item Reason Future Consideration
CalDAV protocol support Legacy protocol; REST API is strategic direction No
Real-time collaborative editing Different product (Google Docs model) No
End-to-end encryption Requires client key management; architectural change Yes (separate PRD)
Offline-first architecture Client concern N/A
Free/busy aggregation across orgs Enterprise feature (separate API) Yes (Workspace PRD)
Natural language event creation AI/ML feature (separate roadmap) Yes (future PRD)
Video conferencing integration details Covered by Meet API PRD N/A
Admin console / domain-wide delegation Workspace Admin SDK scope N/A
GDPR data export Covered by Takeout integration N/A
Push notification relay infrastructure FCM/APNs team ownership N/A
Long-polling / SSE fallback Future consideration for desktop clients Yes (Phase 2)

7. Open Questions

7.1 Technical Design

Question Options Recommendation Owner Status
Should we support Server-Sent Events as push fallback? (A) Webhook only, (B) Add SSE, (C) Add WebSocket (B) Add SSE for desktop clients without webhook capability Platform Team Pending
How should we handle sync token invalidation during schema migrations? (A) Mass invalidate, (B) Dual-write period, (C) Transparent migration (B) Dual-write with 30-day overlap Storage Team Pending
Should batch operations support transactions? (A) All-or-nothing, (B) Best-effort (current), (C) Partial with rollback (B) Best-effort with detailed per-item status API Team Decided

7.2 Product Decisions

Question Context Stakeholder Status
Should we expose conflict resolution hints to clients? Clients currently must implement their own merge logic PM Pending
What is the minimum sync token validity period? 7 days is current; some partners request 30 days PM, Partnerships Pending
Should we offer premium SLA tiers for enterprise partners? Higher quotas, dedicated support, guaranteed latency Partnerships, Finance Pending

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment