Reference Architecture · agent

Calendar Scheduling Agent

Last updated: April 16, 2026

Quick answer

The production pattern is Claude Sonnet 4 as the orchestrator with structured tool calls to Google/Microsoft Calendar APIs, Haiku 4 for fast natural-language slot parsing, and a hard deterministic layer for timezone + DST math (never let the LLM do timezone arithmetic). Expect $0.04–$0.15 per meeting booked with 1–3s latency per turn. Handles 85%+ of scheduling requests without human intervention.

The problem

Scheduling a meeting across two timezones, two calendars, and one ambiguous 'how about Tuesday afternoon' is a surprisingly hard problem. You need an agent that understands natural language availability (including hedges like 'mostly free'), respects meeting preferences (no-meeting-mornings, buffer time), books across calendar providers, and handles reschedules without infinite-looping with another AI on the other side.

Architecture

free/busyon confirmationInbound RequestINPUTAvailability ParserLLMTimezone ResolverINFRACalendar Tool LayerINFRAScheduling OrchestratorLLMPreference StoreDATAResponse ComposerLLMEvent CreatorOUTPUT
input
llm
data
infra
output

Inbound Request

Email, Slack DM, or web form. 'Can we meet next week to discuss X?' or an existing thread with availability proposals.

Alternatives: SMS, Voice via Twilio + STT, Web widget

Availability Parser

Extracts proposed times, duration, attendees, location/video preference, urgency. Outputs structured JSON.

Alternatives: GPT-4o-mini, Gemini 2.0 Flash

Timezone Resolver

Deterministic code — uses Luxon/date-fns-tz to convert all times to UTC with correct DST handling. Never the LLM.

Alternatives: Luxon, Temporal API, date-fns-tz

Calendar Tool Layer

Queries free/busy via Google Calendar, Microsoft Graph, CalDAV. Respects working hours and meeting preferences per user.

Alternatives: Microsoft Graph, Cronofy, Nylas

Scheduling Orchestrator

Sonnet 4 reasons over free/busy windows, preferences, and politeness to propose 2–3 slots or confirm a specific time.

Alternatives: GPT-4o, Gemini 2.5 Pro

Preference Store

Per-user prefs: working hours, lunch block, no-meeting days, buffer time, preferred video tool, decline patterns.

Alternatives: Supabase, Redis for hot reads

Response Composer

Drafts reply in user's tone with 2–3 proposed slots or confirmation. Writes ICS invite on confirm.

Alternatives: GPT-4o, Gemini 2.5 Pro

Event Creator

Creates event on both calendars with video link (Zoom/Meet/Teams), sends ICS, handles declines gracefully.

Alternatives: Cal.com API, Chili Piper, Direct provider APIs

The stack

Orchestrator LLMClaude Sonnet 4

Scheduling needs reliable multi-turn tool use — Sonnet 4's function-calling error rate is materially lower than GPT-4o for chained calendar/preference lookups.

Alternatives: GPT-4o, Gemini 2.5 Pro

Parser LLMClaude Haiku 4

Fast structured extraction on inbound messages. Run on every turn, keep cost near-zero.

Alternatives: GPT-4o-mini, Gemini 2.0 Flash

Timezone mathLuxon or Temporal API

Never let the LLM do timezone arithmetic. DST boundaries and non-standard zones (India +5:30, Nepal +5:45) are where hallucinated bookings happen.

Alternatives: date-fns-tz, moment-timezone

Calendar APICronofy or Nylas

Abstracts Google + Microsoft + iCloud + CalDAV with one API and consistent free/busy semantics. Saves months of edge-case handling.

Alternatives: Direct Google + Graph, Cal.com API

Preference storePostgres + Redis cache

Preferences are read on every scheduling turn — Redis cache keeps latency low. Postgres is source of truth.

Alternatives: Supabase, Prefs in user row

Video conferencingZoom/Meet/Teams auto-create

Create the video link at booking time, not before — link-then-reschedule creates stale links. All three majors have REST APIs for dynamic link creation.

Alternatives: Whereby, Around, Dial-in numbers

Cost at each scale

Prototype

200 meetings/mo, 1 user

$25/mo

Sonnet 4 orchestration + writer$10
Haiku 4 parser$1
Cronofy starter$10
Supabase free tier$0
Infra (Vercel Hobby)$0
Observability$4

Startup

20,000 meetings/mo, 1,000 users

$2,600/mo

Sonnet 4 (with caching)$950
Haiku 4 parser$90
Cronofy Pro$850
Supabase Pro$120
Infra + Upstash Redis$250
Observability$340

Scale

800,000 meetings/mo, 40,000 users

$48,000/mo

Sonnet 4 (heavy caching)$22,000
Haiku 4 parser$1,800
Cronofy Enterprise$9,500
Postgres + Redis infra$4,500
Compute + edge$6,500
Observability + evals$3,700

Latency budget

Total P50: 3,867ms
Total P95: 8,260ms
Parser extraction
500ms · 1100ms p95
Timezone normalization
5ms · 15ms p95
Free/busy fetch (2 calendars)
350ms · 900ms p95
Preference lookup (Redis)
12ms · 45ms p95
Sonnet orchestration + response
2200ms · 4000ms p95
Booking + invite
800ms · 2200ms p95
Median
P95

Tradeoffs

LLM reasoning vs deterministic booking logic

Tempting to let Sonnet 'just figure out' slot overlap — it mostly works but fails silently on DST weekends and 30-minute offset timezones. The robust pattern is LLM proposes candidate windows, deterministic code verifies and ranks, then LLM composes the response.

Synchronous vs async booking

For Slack/chat, users expect <3s. For email, async is fine and cheaper (batch operations, no streaming). Split the architecture at the ingest layer — same orchestrator, different latency budgets.

Unified calendar abstraction (Cronofy) vs direct APIs

Cronofy costs $0.05/user/mo but saves weeks of work on Microsoft Graph quirks and iCloud CalDAV. Direct APIs give you more control and lower unit cost at 10k+ users. Start with Cronofy, migrate later if the unit economics demand it.

Failure modes & guardrails

Books across DST boundary and meeting is off by 1 hour

Mitigation: Always compute slots in UTC using IANA zone IDs (not offset strings). Run a nightly DST audit job that flags any meeting in the next 30 days that crosses a DST boundary for either participant, and surface to user for confirmation.

Proposes a slot during the other person's lunch

Mitigation: Pull target attendee's visible free/busy where available, fall back to stated working hours. Prompt the orchestrator with explicit 'do not propose during 12:00–13:00 local time unless requestor insists' — then verify deterministically before sending.

AI-vs-AI infinite reschedule loop

Mitigation: Detect automation by headers (X-Autorespond, common scheduling bot signatures) and cap to 2 back-and-forths before escalating to human. Also: add a random 1–3min jitter before responding to prevent tight loops.

Creates duplicate events across calendars

Mitigation: Always use an idempotency key (thread ID + proposed slot hash) on booking API calls. Before creating, query both calendars for events with the same iCalUID. On conflict, update not create.

Leaks internal attendees/topics to external parties

Mitigation: Never auto-include private event details in proposed-time strings ('free after my 1:1 with Sarah'). Strip attendees, locations, and titles from context before sending to the LLM when the recipient is external. Use only free/busy boolean.

Frequently asked questions

Why not just use Cal.com or Calendly?

Cal.com/Calendly work when the recipient is willing to pick from a link. For inbound email where someone says 'Tuesday afternoon works', you need an agent to negotiate in natural language. The two patterns complement each other — link-based for prospects, agent for execs and existing contacts.

Which LLM is best for scheduling in 2026?

Claude Sonnet 4 — its tool-call reliability matters more than raw reasoning here. GPT-4o is close but fails more often on multi-step chained calendar lookups. Never use a single-shot LLM for timezone math regardless of model.

How do you handle 'sometime next week'?

Parser extracts it as a window (Mon 00:00 – Sun 23:59 in requestor's timezone). Orchestrator pulls free/busy across the window, filters by preferences, and picks the top 3 slots weighted by time-of-day preference. Never propose more than 3 — choice overload tanks reply rates.

Does it handle rescheduling?

Yes — same orchestrator, different prompt path. Detect the existing event by thread ID or subject reference, cancel + re-book atomically (or update if the API supports it). Confirm timezone of the new time explicitly in the reply, this is where errors compound.

How do you prevent the agent from over-committing my calendar?

Per-user daily and weekly caps on auto-bookings. Hold slots with 'tentative' status for 10 minutes after proposing, release if not confirmed. Maintain a 'protected' calendar (deep work blocks) that the agent cannot offer even if marked free.

What about multi-person scheduling?

For 3+ attendees, use a grid-intersection approach deterministically, then have Sonnet rank by preferences. Above 5 attendees, recommend a poll UI (Doodle-style) instead — LLM-negotiated group scheduling devolves quickly.

Is it safe to give an AI access to my calendar?

Use OAuth scopes as narrow as possible (calendar.events, not full profile). Store refresh tokens encrypted. Log every tool call for audit. Never let the agent delete events — only cancel with confirmation.

Related