AI scheduling API reliability architecture

    AI Scheduling API Transactional Outbox: Never Lose a Participant Update

    By Tevye Krynski18 min read

    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. 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. 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. 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. 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 Microsoft getSchedule reads 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. 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. 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. 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 optional transactionId intended 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. 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. 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?

    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?

    It is a local transaction that commits a scheduling state change and the durable record of its required side effect together. A separate dispatcher later performs participant outreach, availability work, calendar writes, read-back, or client notification and records the outcome.

    Why is idempotency not enough for a scheduling API?

    Idempotency makes repeated execution of one logical action safe. It does not save an action when the process commits participant state and crashes before publishing work. The outbox preserves the action; idempotent dispatch and reconciliation make its later replay safe.

    Should the calendar API call run inside the database transaction?

    No. A remote Google or Microsoft call cannot join the application’s normal local database transaction safely. Commit the immutable calendar-write intent to the outbox, perform it after commit, record its provider identity and outcome, reconcile uncertain responses, then read back the canonical event.

    How should dead-letter scheduling actions be handled?

    Preserve the action, meeting and participant revisions, attempt history, redacted failure code, last safe checkpoint, and named owner. Automatic replay must retain the same authority and action identity. Identity, consent, permission, scope, or participant conflicts usually need a human-approved repair revision.

    Can the outbox guarantee exactly-once invitations?

    No. A dispatcher can complete a provider side effect and crash before recording success. Design for at-least-once dispatch with stable action identities, provider correlation, deduplication where supported, bounded retries, and read-before-retry reconciliation. Report only the completion facts the provider can verify.

    Where can developers review WonderCal’s AI scheduling API direction?

    Visit WonderCal for AI agents. The MCP/API direction is targeted for September 1, 2026; validate the current meeting state, outbox, participant fallback, consent, retry, recovery, provider read-back, observability, and completion behavior before production use.

    Primary sources

    Related WonderCal reading

    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