Group scheduling API engineering

    Group Scheduling API Design: Idempotency, Retries, and Cross-Company Fallbacks

    By Tevye Krynski15 min read

    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. 1

      Create one durable meeting request

      Accept POST /meeting-requests with 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. Return 202 Accepted with 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. 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. 3

      Normalize Google and Microsoft availability

      Put provider calls behind adapters. Google Calendar’s free/busy API and Microsoft Graph’s getSchedule differ 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. 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 expose waiting_on_participant rather 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. 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. 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. 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.

    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?

    Return a durable meeting request, not a fake final booking. A long-running coordination job should usually return 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?

    Use a booking idempotency key tied to the meeting request, revision, and approved proposal. Persist the provider correlation and event ID before acknowledging success. If the write result is uncertain, query or reconcile against the provider before repeating the insert.

    Can a group scheduling API include people who do not connect calendars?

    Yes. Treat conversational availability as a first-class adapter with consent, channel, message ID, parsed intervals, time zone, and freshness. It should feed the same slot engine as connected Google or Microsoft free/busy rather than create a separate manual workflow.

    Is an MCP scheduling server the same as a group scheduling API?

    No. MCP is a protocol through which models can discover and invoke tools. A group scheduling API is the underlying domain contract and state model. An MCP server can expose commands such as creating a meeting request or approving a proposal, but it still needs idempotency, consent, recovery, and observable completion underneath.

    Where can developers check WonderCal’s current API access?

    WonderCal is targeting its developer-facing MCP/API release for September 1, 2026. Check WonderCal for AI agents for the current access path. Validate live routes, schemas, supported channels, and error behavior before treating any design in this article as an available product feature.

    Primary sources

    Related WonderCal reading

    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