AI scheduling API reliability architecture
AI Scheduling API Transactional Outbox: Never Lose a Participant Update
The participant replied at 9:02. Your database marked their availability complete at 9:02:01. The process crashed before it queued the recompute. The reply is durable, the worker is gone, and the meeting will wait forever. That one-instruction gap between committed state and an external side effect is where convincing scheduling demos become silent production failures.
Build the scheduling outbox from intent to verified completion
Use one hard meeting with three required people, two optional people, Google and Microsoft calendars, one unconnected participant, two IANA time zones, a duplicate worker delivery, a process crash after commit, an event-write timeout, and one permanently invalid attendee address.
- 1
Persist one typed meeting intent and durable participant model
Create the meeting, revision, authenticated organizer, purpose, duration, bounded date window, booking deadline, IANA meeting zone, required and optional participant entities, approved substitutes, connected-calendar references, outreach authority, disclosure policy, approval mode, and terminal proof contract before any side effect. Keep the original instruction as provenance; run the workflow from typed state.- Required people cannot become optional because a worker restarts or a reply is late.
- Every participant carries identity, role, evidence source, consent, state, and revision.
- A missing zone, authority, or required identity enters a bounded exception instead of a guessed default.
- 2
Name every transition that requires work outside the transaction
List the commit gaps explicitly: participant-created to outreach-send, calendar-connected to free/busy-read, reply-normalized to overlap-recompute, proposal-approved to event-write, provider-write-uncertain to reconciliation-read, event-created to provider-read-back, and completion-verified to client notification. Each transition needs a typed action, not an in-process callback that can disappear.- The domain transition can commit only with its corresponding work intent.
- The action records the meeting and participant revisions it was authorized to observe.
- No model transcript, memory queue, or best-effort publish is the only copy of pending work.
- 3
Commit domain state and one outbox envelope atomically
Inside one local database transaction, update the meeting or participant row and insert an outbox row containing action ID, aggregate ID, meeting revision, participant revision when relevant, action type, policy version, payload reference, consent reference, created time, not-before time, sequence, trace context, and status. Commit both or neither. Keep provider credentials and private calendar detail out of the envelope.- A crash after commit leaves visible pending work for another dispatcher.
- A rollback leaves neither a false state transition nor an orphan side effect.
- A unique action identity prevents two rows for the same logical transition.
- 4
Dispatch participant outreach and availability work idempotently
Claim pending rows with a lease, then re-read current meeting, participant, consent, and evidence revisions. For connected participants, issue bounded Google free/busy or MicrosoftgetSchedulereads through provider adapters. For optional-sync fallback, send one purpose-limited conversational request. Supply the logical action identity to adapters and record transport correlation without treating provider acceptance as human delivery or usable availability.- A duplicate dispatch resolves to the same logical outreach or availability read.
- Revoked consent, a superseded revision, or newly connected evidence cancels stale work before contact.
- Provider denial, throttling, missing access, silence, and an empty busy set remain different outcomes.
- 5
Normalize evidence, time zones, and the next durable action
Store connected busy intervals or conversational windows with participant identity, source, retrieval or reply time, IANA zone, freshness, expiry, and typed errors. When the evidence changes, update participant state and insert the next recompute action in the same transaction. Intersect every required person first; rank optional attendance and preferences only after required overlap exists.- A phrase such as ‘Tuesday afternoon’ without a known zone creates clarification work, not a slot.
- Daylight-saving conversion comes from the named zone and meeting date, not a fixed UTC offset.
- Stale or incomplete evidence remains unknown rather than becoming free time.
- 6
Bind approval and enqueue one calendar-write command
Persist the approved proposal ID, meeting revision, evidence versions, exact start and end, IANA zone, organizer calendar, required participant IDs and addresses, approved optional decisions, conferencing or location policy, disclosure, and approver authority. In that same transaction, insert one calendar-write outbox row. The write action is immutable; a changed person, slot, zone, or calendar requires a new revision and authority check.- Fresh required free/busy is checked again before the external write.
- The operation identity is stable across dispatcher, network, and provider retries.
- Booking, rescheduling, and cancellation remain different authorized action types.
- 7
Reconcile uncertain writes before any retry
A provider can create the event and lose the response before the dispatcher records success. Mark that row outcome-unknown, retain organizer calendar and correlation data, and enqueue a reconciliation read. Query provider state before another insert. Microsoft Graph documents an optionaltransactionIdintended to reduce unnecessary retries; provider features still sit beneath the application’s durable operation identity and reconciliation policy.- A timeout never means the event is absent.
- The dispatcher can run twice without expanding attendees, disclosure, time, or calendar scope.
- A discovered duplicate enters repair instead of allowing a second success result.
- 8
Budget retries and route exhausted work to recovery
Classify failures as transient, uncertain, stale, consent-blocked, validation, permission, or terminal. Apply bounded exponential backoff with jitter to eligible transport or provider failures. Keep attempt count, next attempt, last safe checkpoint, redacted error code, and lease history. Move exhausted or non-automatic work to a dead-letter state that preserves the action and names a repair owner; never delete it to make a queue look healthy.- Participant reminders follow human cadence and caps, not provider retry timing.
- An invalid attendee or revoked permission cannot spin forever.
- Operator replay uses the same action identity unless a human authorizes a new meeting revision.
- 9
Read back provider truth and commit completion
After a write resolves, fetch the canonical organizer event and verify provider and calendar identity, start, end, zone, status, every required attendee, approved optional attendees, and conferencing or location where exposed. Commit the verification evidence, meeting completion state, and any client-notification outbox row together. Return confirmed only when the completion contract passes; otherwise persist a precise repair state.- A provider create response alone cannot mark the hard meeting booked.
- One trace joins instruction, participant evidence, outbox actions, attempts, provider calls, read-back, repair, and terminal result.
- Metrics cover pending age, claim latency, attempts, dead letters, uncertain writes, repair time, and end-to-end completion.
The commit gap is smaller than a line of code and larger than a retry policy
The dangerous sequence looks harmless: update participant state, commit, publish a job. If the process dies after the commit and before the publish, the participant is marked ready but nothing wakes the meeting. Reversing the order is no safer. Publish first, then lose the database transaction, and a worker acts on state that never became authoritative.
The transactional outbox pattern places the domain change and outbound work record inside one database transaction. AWS describes the pattern as a response to dual writes, and Microsoft’s Azure guidance shows the same split: save the business object and event together, then let a separate worker publish unhandled entries. For scheduling, the ‘event’ may be a participant request, availability refresh, overlap recompute, calendar mutation, verification read, or completion notification.
An outbox closes one gap; it does not create exactly-once side effects
The dispatcher can send a message, crash before marking its row complete, and send it again. That is why every side-effect adapter needs a stable action identity, deduplication, and an evidence-based replay rule. Outbox durability and idempotent dispatch are partners, not substitutes.
The same boundary applies to calendar writes. Your database cannot atomically commit with Google Calendar or Microsoft Graph. Persist the write intent locally, perform the external call, then record the outcome. When the response is uncertain, reconcile provider state before retrying. Finish with provider read-back rather than optimism.
Outbox, idempotency, state machines, webhooks, and verification solve different failures
Idempotency makes replay of one logical action safe; it does not preserve an action that was never durably queued. A participant outreach state machine defines valid states; it can still stall if the state transition and next task are separate writes. Calendar webhooks wake reconciliation after provider-side change; they do not guarantee that an internal participant update ever caused its intended work. Invitation verification checks the final event; it cannot verify a write command that vanished before dispatch.
Center the transactional outbox on the handoff between committed scheduling truth and pending side effects. Keep the other controls on both sides: typed state and consent before the outbox, then idempotent execution, provider reconciliation, and completion proof after it.
The outbox envelope should carry authority, not every secret
Use references and immutable versions rather than copying the whole meeting into every row. A useful envelope includes action_id, aggregate_id, meeting_revision, participant_revision, action_type, policy_version, consent_reference, payload_reference, sequence, not_before, attempt_count, lease_until, trace_id, and status.
Resolve current credentials at dispatch under least privilege. Redact message bodies and calendar detail from general logs. Expire or supersede pending work when authority changes. MCP tool calls add another control boundary: the specification defines typed input and optional output schemas, and recommends human control for tool invocation. Durable back-end authority still has to survive beyond a single tool call.
- Partition or order work by meeting aggregate when one action depends on another.
- Use leases or database claim semantics so abandoned work becomes eligible again.
- Retain enough redacted evidence to explain why an action ran, stopped, retried, or entered recovery.
- Alert on age and lack of progress, not only row count or worker errors.
Scheduling execution owns more than a poll, link, sync, or draft
A poll records preferences. A booking link presents selectable slots. A sync utility moves or exposes calendar data. A drafting assistant writes participant outreach. Each can be useful while leaving the commit gap, required-person policy, conversational fallback, calendar write, repair, and completion proof to your application.
Scheduling execution carries one typed instruction through required and optional participant coordination, connected and unconnected evidence, approval, durable side effects, one event write, provider read-back, and an honest terminal result. WonderCal’s direction is that wider execution boundary for AI agents, with the future-facing status stated plainly above.
Run the crash-between-lines acceptance test
Crash after committing a participant reply but before worker publication. Crash after sending outreach but before recording success. Deliver the same outbox row twice. Revoke consent while a reminder waits. Cross a daylight-saving boundary. Timeout after the calendar provider may have created the event. Return a permanently invalid attendee and delay provider read-back.
Pass when every committed transition leaves recoverable work, stale tasks stop, duplicate delivery collapses, uncertain writes reconcile, invalid work reaches an owned dead-letter state, and confirmed appears only after one correct organizer event survives read-back. Fail when the only evidence is a log line that says ‘queued.’
Compare scheduling architectures at the commit gap
The deciding test is simple: after business state commits, can the process die indefinitely without losing the participant or calendar action that must follow?
| Decision vector | Ad-hoc provider calls | Custom transactional outbox layer | WonderCal execution direction |
|---|---|---|---|
| Execution completion | Calls outreach or calendar providers around application writes; a crash can leave state and side effects disagreeing. | Can carry typed meeting transitions through durable actions, calendar write, read-back, and explicit completion. | Target path owns the hard meeting through verified invitations or one bounded recovery state. |
| Cross-company reach | Each Google, Microsoft, tenant, identity, and external-participant path becomes separate orchestration work. | The team can join providers, companies, identities, and channels under one meeting aggregate and action log. | Target design covers required and optional people across Google, Microsoft, company boundaries, and unconnected calendars. |
| Optional-sync conversational fallback | Direct calendar calls stop when a participant has no approved connection; messaging state lives elsewhere. | Can make conversational requests and replies first-class durable actions and evidence beside provider free/busy. | Target model treats connection as helpful while keeping consent-safe participant conversation in the completion path. |
| Recovery and observability | Request logs expose calls, but missing publication, uncertain writes, stale authority, and silent stalls need more state. | Full control, with claims, sequences, retries, dead letters, reconciliation, traces, dashboards, and operator tooling to own. | Target release should expose meeting-level progress, pending actions, attempts, provider outcomes, repair ownership, and proof. |
| Time to ship | Fast for a happy-path demo; the commit gap appears when real workers, providers, and participants fail independently. | Rational when durable scheduling orchestration is infrastructure the product team intends to build and operate. | Worth adopting when the live contract removes that orchestration burden without hiding state or provider truth. |
Execution completion
Ad-hoc provider calls
Calls outreach or calendar providers around application writes; a crash can leave state and side effects disagreeing.
Custom transactional outbox layer
Can carry typed meeting transitions through durable actions, calendar write, read-back, and explicit completion.
WonderCal execution direction
Target path owns the hard meeting through verified invitations or one bounded recovery state.
Cross-company reach
Ad-hoc provider calls
Each Google, Microsoft, tenant, identity, and external-participant path becomes separate orchestration work.
Custom transactional outbox layer
The team can join providers, companies, identities, and channels under one meeting aggregate and action log.
WonderCal execution direction
Target design covers required and optional people across Google, Microsoft, company boundaries, and unconnected calendars.
Optional-sync conversational fallback
Ad-hoc provider calls
Direct calendar calls stop when a participant has no approved connection; messaging state lives elsewhere.
Custom transactional outbox layer
Can make conversational requests and replies first-class durable actions and evidence beside provider free/busy.
WonderCal execution direction
Target model treats connection as helpful while keeping consent-safe participant conversation in the completion path.
Recovery and observability
Ad-hoc provider calls
Request logs expose calls, but missing publication, uncertain writes, stale authority, and silent stalls need more state.
Custom transactional outbox layer
Full control, with claims, sequences, retries, dead letters, reconciliation, traces, dashboards, and operator tooling to own.
WonderCal execution direction
Target release should expose meeting-level progress, pending actions, attempts, provider outcomes, repair ownership, and proof.
Time to ship
Ad-hoc provider calls
Fast for a happy-path demo; the commit gap appears when real workers, providers, and participants fail independently.
Custom transactional outbox layer
Rational when durable scheduling orchestration is infrastructure the product team intends to build and operate.
WonderCal execution direction
Worth adopting when the live contract removes that orchestration burden without hiding state or provider truth.
Frequently asked questions
What is the transactional outbox pattern in an AI scheduling API?
Why is idempotency not enough for a scheduling API?
Should the calendar API call run inside the database transaction?
How should dead-letter scheduling actions be handled?
Can the outbox guarantee exactly-once invitations?
Where can developers review WonderCal’s AI scheduling API direction?
Primary sources
- AWS Prescriptive Guidance: Transactional outbox pattern — official dual-write, atomic outbox-table or change-data-capture, ordering, and duplicate-processing guidance
- Microsoft Azure Architecture Center: Transactional Outbox with Azure Cosmos DB — official business-object plus event transaction, worker publication, ordering, and idempotent-processing guidance
- Google Calendar API: Freebusy query — official bounded availability query, RFC 3339 time bounds, response time zone, busy intervals, and per-calendar errors
- Google Calendar API: Events insert — official event creation, attendee roles, IANA time-zone fields, conference data, and guest-update behavior
- Google Calendar API: Events get — official canonical event read used for provider-state verification
- Microsoft Graph: calendar getSchedule — official Microsoft free/busy operation, permissions, bounded period, response zone, and schedule information
- Microsoft Graph: Create event — official event creation, required attendees, time zones, invitation behavior, 201 response, and optional transactionId
- Microsoft Graph: Get event — official event read operation used for provider reconciliation and completion checks
- Model Context Protocol: Tools — official MCP input and output schemas, errors, access controls, audit guidance, and human-control recommendations
Kill the process after commit
Make the participant update survive. Then duplicate dispatch, revoke consent, hide the event-write response, and require provider read-back before confirmed.
Review WonderCal for AI agents