Group scheduling API engineering
Group Scheduling API Design: Idempotency, Retries, and Cross-Company Fallbacks
A group scheduling API is a long-running coordination system wearing an HTTP interface. The first request may arrive now. The last required participant may answer tomorrow. Between those moments, calendars change, access expires, webhooks repeat, workers restart, and an organizer edits the brief. The API contract has to make every one of those events safe.
A production group scheduling API contract
Expose a meeting resource and a small command set. Do not expose one magical ‘schedule’ endpoint that blocks until the world cooperates. The client should be able to create intent, inspect progress, approve a proposal, request a revision, and receive verified state changes.
- 1
Create one durable meeting request
AcceptPOST /meeting-requestswith a client idempotency key. The body should name the organizer, required and optional participants, duration, date window, meeting time zone, working-hour or preference rules, booking deadline, approval mode, and permitted outreach channels. Return202 Acceptedwith a stable resource URL when coordination continues asynchronously.- The same key and same payload return the same meeting request.
- The same key with a different payload returns a conflict, not a second request.
- The response exposes current state, revision, created time, and next expected action.
- 2
Separate commands from observed events
Commands express intent: approve this slot, change the window, add an optional participant, cancel the request. Events record facts: availability received, provider access expired, candidate generated, booking committed, invitation verified. Give every event a unique ID, meeting request ID, revision, sequence number, and occurred-at timestamp. Consumers should deduplicate by event ID and reconcile gaps by reading the meeting resource.- Never ask a webhook consumer to infer state from prose.
- Keep event delivery at-least-once and document ordering boundaries.
- Expose a full current-state read so a lost webhook is recoverable.
- 3
Normalize Google and Microsoft availability
Put provider calls behind adapters. Google Calendar’s free/busy API and Microsoft Graph’sgetSchedulediffer in request shape, permissions, limits, errors, and time-zone handling. Convert both into canonical busy intervals with participant ID, source provider, source account, retrieval time, and confidence. Do not pass raw provider payloads into an agent model as your system of record.- Use RFC 3339 timestamps at API boundaries and IANA zones for policy.
- Distinguish an empty busy list from an incomplete provider response.
- Store permission denial, throttling, and expired credentials as separate reason codes.
- 4
Make no-calendar fallback a first-class adapter
An external participant may never connect a calendar. Model conversational availability as another provider with consent, channel, message ID, requested window, normalized response, freshness, and opt-out state. The API should exposewaiting_on_participantrather than hide a message chase behind a generic processing status.- Limit reminders and make the policy visible to the organizer.
- Ask narrow follow-ups for ambiguous dates, zones, or ranges.
- Do not contact anyone unless the organizer has authority and the channel is allowed.
- 5
Version proposals and availability evidence
A slot proposal is derived data. Include a proposal ID, meeting revision, required-participant overlap, optional-participant score, preference score, and the availability snapshot version behind it. If any required calendar or response changes, mark the proposal stale. Approval of a stale proposal should trigger a re-check, never an unconditional write.- Explain which constraint rejected every near-miss slot.
- Keep required attendance as a hard rule unless the organizer changes the brief.
- Expire proposals at a documented freshness boundary.
- 6
Create an idempotent booking transaction
The commit path needs its own key, separate from request creation. Derive it from meeting request ID, revision, and approved proposal. Re-read fresh free/busy, acquire a short commit lock, write the organizer event, persist the provider event ID, send attendee updates, and verify the resulting record. If the provider times out, query by stored correlation data before retrying the insert.- One approved proposal creates at most one canonical meeting event.
- A retry returns the prior booking result when the commit already succeeded.
- A partial failure moves to reconciliation with an explicit operator action.
- 7
Close the loop with reconciliation and observability
Emit traces, metrics, and structured logs around meeting state rather than individual HTTP calls alone. Track time in state, required participants still missing, provider error class, retries, stale proposals, duplicate commit attempts, and invitation verification. Reconciliation workers should compare stored booking state with the provider record after uncertain writes and webhook gaps.- Every failure response includes a stable code, retry class, and safe next action.
- Every meeting can be reconstructed from its command and event history.
- Sensitive calendar details stay out of logs and model prompts.
The resource model that keeps clients sane
A useful meeting resource exposes id, revision, state, intent, participants, availability_summary, active_proposal, booking, blocking_reasons, and next_actions. The client should never need to scrape a message thread to discover why a meeting has not booked.
Use nested participant state carefully. One person can have Google connected for work, no access to a Microsoft side calendar, an approved email channel, a stale conversational response, and a pending consent change. Flattening that into available: true destroys the evidence the slot engine and operator need.
Build the failure matrix before the happy path demo
Write recovery policy for provider throttling, token expiration, permission denial, invalid attendee address, unknown time zone, ambiguous reply, required-participant silence, no overlap, stale approval, event-write timeout, duplicate webhook, invitation rejection, and organizer cancellation. Each condition needs one of four classes: retry automatically, request participant input, request organizer approval, or stop with a terminal reason.
Retries need budgets. A provider throttle can use bounded exponential backoff with jitter. A participant reminder follows a human cadence and consent policy. A calendar write with an uncertain result needs reconciliation before retry. Calling all three ‘retryable’ is how duplicate invites and message spam escape into production.
- Network failure before the provider accepts the request: retry may be safe.
- Timeout after an event may have been created: reconcile first.
- Required participant declines: organizer decision, not automatic substitution.
- Proposal becomes stale after approval: re-check and ask again if the slot is gone.
Consent and privacy belong in the API surface
The API should expose why it can read availability or contact a participant. Store the authorization source, permitted channel, granted scope, and revocation state. Return free/busy intervals to the slot engine without private titles, descriptions, locations, or attendee lists. Apply retention policy separately to calendar evidence, participant messages, and audit history.
MCP adds another control boundary. The MCP specification’s tool guidance says applications should make exposed tools visible and provide human control for tool invocations. For scheduling, the high-risk tools are participant outreach, approval bypass, event creation, rescheduling, and cancellation. A model should not gain those powers because it discovered a server.
When to build adapters and when to buy execution
Build directly on Google and Microsoft when calendar behavior is core intellectual property, your team can own OAuth support and provider changes, and you need a provider-specific experience. A direct build gives control. It also gives you every edge case above, plus participant messaging and operator recovery.
Use a scheduling execution layer when your product’s value lives above calendar coordination and the requirement is a completed cross-company booking. The vendor has to prove more than endpoint coverage. Demand optional-sync fallback, required and optional participant semantics, safe replay, observable meeting state, consent controls, error recovery, and a verified final invitation. WonderCal is being built toward that boundary.
Choose the API boundary, not just the API vendor
Provider APIs, booking APIs, and execution APIs solve different layers. The correct choice follows the outcome your agent promises.
| Decision vector | Direct calendar APIs | Booking-link or poll API | WonderCal execution direction |
|---|---|---|---|
| Execution completion | Calendar reads and writes are available; orchestration, outreach, slot policy, and completion proof remain yours. | Creates a participant-facing choice surface; the client still waits for clicks and closes the meeting state. | Target boundary owns coordination from typed instruction through verified invitations or a bounded exception. |
| Cross-company reach | You integrate each provider, tenant case, permission path, and guest behavior. | External people can open a link, but their actual calendar state may not be connected to the decision. | Designed around mixed Google and Microsoft participants across company boundaries. |
| No-calendar fallback | Requires a messaging system, reply parser, reminder policy, and consent record. | The link or poll becomes the fallback and transfers work to participants. | Target design treats conversational availability as a peer to connected free/busy. |
| Recovery and observability | Maximum control and maximum engineering responsibility for replay, traces, and reconciliation. | Good visibility into link events; limited meeting-level visibility before every person responds. | The live release should be evaluated on states, reason codes, idempotency, webhooks, and operator actions. |
| Consent | You own provider scopes, participant channels, approvals, data retention, and revocation. | Participant choice is explicit, but organizer authority and end-to-end audit may live elsewhere. | Target architecture preserves private free/busy and explicit connected, outreach, approval, and decline states. |
| Time to ship | Fast for one provider and one happy path; long for cross-company completion and support tooling. | Fast when a link or poll satisfies the product promise. | Worth adopting only when its released contract removes the coordination and recovery work your team would otherwise own. |
Execution completion
Direct calendar APIs
Calendar reads and writes are available; orchestration, outreach, slot policy, and completion proof remain yours.
Booking-link or poll API
Creates a participant-facing choice surface; the client still waits for clicks and closes the meeting state.
WonderCal execution direction
Target boundary owns coordination from typed instruction through verified invitations or a bounded exception.
Cross-company reach
Direct calendar APIs
You integrate each provider, tenant case, permission path, and guest behavior.
Booking-link or poll API
External people can open a link, but their actual calendar state may not be connected to the decision.
WonderCal execution direction
Designed around mixed Google and Microsoft participants across company boundaries.
No-calendar fallback
Direct calendar APIs
Requires a messaging system, reply parser, reminder policy, and consent record.
Booking-link or poll API
The link or poll becomes the fallback and transfers work to participants.
WonderCal execution direction
Target design treats conversational availability as a peer to connected free/busy.
Recovery and observability
Direct calendar APIs
Maximum control and maximum engineering responsibility for replay, traces, and reconciliation.
Booking-link or poll API
Good visibility into link events; limited meeting-level visibility before every person responds.
WonderCal execution direction
The live release should be evaluated on states, reason codes, idempotency, webhooks, and operator actions.
Consent
Direct calendar APIs
You own provider scopes, participant channels, approvals, data retention, and revocation.
Booking-link or poll API
Participant choice is explicit, but organizer authority and end-to-end audit may live elsewhere.
WonderCal execution direction
Target architecture preserves private free/busy and explicit connected, outreach, approval, and decline states.
Time to ship
Direct calendar APIs
Fast for one provider and one happy path; long for cross-company completion and support tooling.
Booking-link or poll API
Fast when a link or poll satisfies the product promise.
WonderCal execution direction
Worth adopting only when its released contract removes the coordination and recovery work your team would otherwise own.
Frequently asked questions
What should a group scheduling API return first?
202 Accepted with a stable resource URL, current state, revision, and next expected action. The client can read that resource and receive state-change webhooks.How do you prevent duplicate calendar events after a timeout?
Can a group scheduling API include people who do not connect calendars?
Is an MCP scheduling server the same as a group scheduling API?
Where can developers check WonderCal’s current API access?
Primary sources
- Google Calendar API: Freebusy query — official Google availability request, limits, scopes, time bounds, and response
- Google Calendar API: Push notifications — official resource-change notification channel model
- Microsoft Graph: calendar getSchedule — official Microsoft free/busy endpoint and permissions
- Microsoft Graph: Webhook change notifications — official webhook delivery, response, retry, and lifecycle considerations
- Model Context Protocol: Tools — official MCP tool discovery, invocation, and human-control guidance
- RFC 9110: Idempotent Methods — HTTP retry and idempotency semantics
Ship the booking, not another calendar adapter
Use this contract to review WonderCal’s developer release: durable meeting state, mixed-provider availability, optional-sync fallback, safe replay, consent, recovery, and a verified final invitation.
Review the AI-agent path