Calendar & scheduling

AI Agents and Microsoft Outlook

No Microsoft Graph connector exists in the product today. Two workarounds get Outlook-based teams to the same outcome now.

PlannedMicrosoft Outlook / 365 · bitpull AI agents

Where this stands today

This page exists because "Outlook integration" is a reasonable thing to search for and a bad thing to be misled about. bitpull has a native connector for Calendly, an assisted setup for Google Calendar, and nothing for Microsoft Graph. No Outlook OAuth flow, no calendar read, no event creation.

Two routes work today. The first: publish the Outlook or Microsoft 365 calendar into a provider that is connected - Calendly integrates with Microsoft 365 and Outlook.com calendars directly, so the agent books through Calendly and the event lands in Outlook. The second: take the appointment as a callback request and let the outbound webhook drive whatever creates the event, including Microsoft Graph from your own code.

The second route is more work and more control. If you already run anything against Graph, the webhook consumer is a short function, and you keep the mapping to rooms, categories and shared mailboxes that a generic connector would never get right anyway.

What the agent can do

Route A - Calendly in front of Microsoft 365

Calendly reads Microsoft 365 and Outlook.com availability. The agent books through the connector it does support, and the event appears in Outlook.

Route B - webhook into Microsoft Graph

The conversation ends, your endpoint receives it, and your own Graph call creates the event with the categories, room and attendees your organisation actually uses.

Shared mailboxes and rooms

Anything involving a resource mailbox or a room list is Route B territory. A generic calendar connector would not model it correctly.

Teams meeting links

Creating an event with an online meeting is a Graph flag on the event, which means Route B. Nothing in the product does it for you.

How it is wired

  1. Conversation ends
  2. bitpull webhookPOST to your URL
  3. Your functionclient credentials token
  4. Microsoft GraphPOST /events
Route B. Route A needs no code at all - it is the Calendly connector with a Microsoft calendar behind it.

Code

Route B - webhook consumer creating a Graph event
const TENANT = process.env.MS_TENANT_ID
const ORGANISER = process.env.MS_ORGANISER_UPN   // person@your-company.com

async function graphToken() {
  const res = await fetch(`https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      client_id: process.env.MS_CLIENT_ID,
      client_secret: process.env.MS_CLIENT_SECRET,
      scope: 'https://graph.microsoft.com/.default',
      grant_type: 'client_credentials'
    })
  })
  return (await res.json()).access_token
}

export default async function handler(req, res) {
  res.status(200).end()

  const body = req.body ?? {}
  const summary = body.summary ?? body.session?.summary ?? {}
  if (!summary.followUp?.required) return

  // The agent captured a wish, not a confirmed slot. Book a provisional hold
  // and let a human confirm - the caller was never told a slot was guaranteed.
  const start = new Date(Date.now() + 24 * 3600_000)
  const end = new Date(start.getTime() + 30 * 60_000)

  await fetch(`https://graph.microsoft.com/v1.0/users/${ORGANISER}/events`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${await graphToken()}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      subject: `[To confirm] ${summary.title ?? 'AI agent callback'}`,
      body: { contentType: 'text', content: (summary.keyPoints ?? []).join('\n') },
      start: { dateTime: start.toISOString(), timeZone: 'UTC' },
      end:   { dateTime: end.toISOString(),   timeZone: 'UTC' },
      showAs: 'tentative',
      isOnlineMeeting: true
    })
  })
}
Application permissions (Calendars.ReadWrite) and admin consent. A delegated token will not work in an unattended webhook.

Limits worth knowing before you start

  • No Microsoft Graph connector in bitpull. Nothing on this page is a product feature; Route B is code you own.
  • Application permissions need tenant admin consent. In most organisations that is a conversation, not a checkbox.
  • The agent does not confirm a Graph slot in real time, so a booking created this way is provisional by nature. Say so in the prompt.
  • Time zones are the usual trap: an agent handling calls across borders must resolve the caller's zone before anything is written to a calendar.

Questions

Is Outlook support planned?

It is a reasonable roadmap item and this page will change when something ships. Today there is no connector, and nothing on this site will imply otherwise.

Which route should we take?

If you can put Calendly in front of Microsoft 365, take Route A - it needs no code and no admin consent. If rooms, resources or Teams links matter, only Route B models them properly.

Ready to run this?

Agents are created and operated on bitpull.ai - this site documents how to connect one. If the outbound webhook is not visible in your dashboard yet, that is the account capability flag, and support can enable it.