Webhook tool

Outlook Calendar AI voice agents that book into Microsoft 365

The agent reads free and busy times from a Microsoft 365 calendar and books the event through a small service of yours that holds the Graph token.

Appointment agent

Offers free times and books Outlook events.

Instructions

Ask what the appointment is for. Offer two free times from the availability tool and book the one the caller picks. Read the date and time back before ending the call. If no time works or the caller asks for a person, transfer to the office.

Handoff
Office

Connected tools

  • Get free timesWebhook
  • Create eventWebhook
  • Transfer to officeTransfer

What a Outlook Calendar AI voice agent can do

Open one to watch a call. The grey lines are the tools the agent calls mid-sentence.

Your service calls Graph's getSchedule for the mailbox and a time window, and the agent offers the caller two open times.

Tool definitions

Webhook tools go to POST /v1/agents/tools. Transfers are a system tool on the agent. Replace the placeholder values in capitals with your own.

Webhook

Get free times

Asks your service for free windows on the Outlook calendar.

Show the JSON definition
get_free_times
{
  "type": "webhook",
  "name": "get_free_times",
  "description": "Lists free windows on the calendar for a date. Use it before offering times.",
  "pre_tool_speech": "auto",
  "execution_mode": "immediate",
  "response_timeout_secs": 20,
  "api_schema": {
    "url": "https://api.your-company.com/outlook/free-times",
    "method": "GET",
    "query_params_schema": {
      "properties": {
        "date": {
          "type": "string",
          "description": "Date to check, YYYY-MM-DD."
        },
        "duration_minutes": {
          "type": "string",
          "description": "Length of the appointment in minutes."
        },
        "mailbox": {
          "type": "string",
          "constant_value": "YOUR_MAILBOX_ADDRESS"
        }
      },
      "required": [
        "date",
        "duration_minutes"
      ]
    },
    "authentication": {
      "mode": "bearer",
      "token": {
        "type": "secret",
        "secret_value": "YOUR_SERVICE_TOKEN"
      }
    }
  }
}

Webhook

Create event

Asks your service to create the event on the Outlook calendar.

Show the JSON definition
create_event
{
  "type": "webhook",
  "name": "create_event",
  "description": "Creates the appointment on the calendar at the time the caller chose.",
  "pre_tool_speech": "auto",
  "execution_mode": "immediate",
  "response_timeout_secs": 20,
  "api_schema": {
    "url": "https://api.your-company.com/outlook/events",
    "method": "POST",
    "request_body_schema": {
      "type": "object",
      "properties": {
        "start": {
          "type": "string",
          "description": "Start time, ISO 8601 with offset."
        },
        "duration_minutes": {
          "type": "string",
          "description": "Length in minutes."
        },
        "attendee_name": {
          "type": "string",
          "description": "Caller's name."
        },
        "phone": {
          "type": "string",
          "dynamic_variable": "system__caller_id"
        },
        "reason": {
          "type": "string",
          "description": "Reason for the appointment, in a sentence."
        },
        "mailbox": {
          "type": "string",
          "constant_value": "YOUR_MAILBOX_ADDRESS"
        }
      },
      "required": [
        "start",
        "duration_minutes",
        "attendee_name",
        "reason"
      ]
    },
    "authentication": {
      "mode": "bearer",
      "token": {
        "type": "secret",
        "secret_value": "YOUR_SERVICE_TOKEN"
      }
    }
  }
}

Transfer

Transfer to office

Cold transfer to your office.

Show the JSON definition
transfer_to_office
{
  "config": {
    "system_tools": {
      "transfer_to_number": {
        "description": null,
        "pre_tool_speech": "auto",
        "transfers": [
          {
            "destination": {
              "type": "phone",
              "phone_number": "+14155550131"
            },
            "condition": "The caller asks for a person, or no free time works."
          }
        ]
      }
    }
  }
}

Set it up

No native connector. Webhook tools call a service of yours, which calls Microsoft Graph with an app registration your Microsoft 365 admin approved. Vendor details read in November 2026.

  1. Register an app in Microsoft Entra ID

    Add the Calendars.ReadWrite application permission, which covers both getSchedule and creating events, and have an admin grant consent.

  2. Limit it to the calendars it books

    Use RBAC for Applications in Exchange Online to scope the permission to those mailboxes, and remove the unscoped grant in Entra ID so the scope holds.

  3. Run the two endpoints

    Your service gets a token with the client credentials flow, calls POST /users/{id}/calendar/getSchedule and POST /users/{id}/events, and gets a new token before the old one expires.

  4. Add the tools and test

    Configure both webhooks with a bearer secret for your service, replace YOUR_MAILBOX_ADDRESS with the mailbox, and book a test event across a daylight saving change.

Before you build

Why not call Graph directly

A client credentials token from Microsoft lasts about an hour (expires_in is 3599), and a webhook tool cannot request a new one. A service of yours can.

Per-mailbox limits

Outlook allows 10,000 Graph requests per app per mailbox in 10 minutes, and four concurrent requests. One shared mailbox behind many phone lines is where you would hit it.

Enterprise-grade security

  • HIPAA compliant badge

    HIPAA compliant

  • SOC 2 Type 2 badge

    SOC 2 Type 2

  • GDPR badge

    GDPR

Outlook Calendar AI voice agent FAQs

Can an AI voice agent book appointments in Outlook?

Yes, on Microsoft 365 work or school mailboxes. A Cartesia agent calls a service of yours, which reads free and busy times with Microsoft Graph's getSchedule and creates the event with POST /users/{id}/events. The event lands with the caller's name, number and reason in the body. There is no native Outlook connector.

Does it work with personal Outlook.com calendars?

No. Microsoft's getSchedule does not support personal Microsoft accounts, so this setup only works for Microsoft 365 work or school mailboxes. A personal calendar would need a different way to read free and busy times.

What Microsoft Graph permission does the agent's service need?

Calendars.ReadWrite as an application permission, with admin consent in Microsoft Entra ID. It covers both getSchedule and creating events. Scope it to the mailboxes the agent books with RBAC for Applications in Exchange Online, then remove the unscoped grant in Entra ID so the scope holds.

Will Microsoft Graph throttling limit a busy phone line?

Rarely. Outlook allows 10,000 Graph requests per app per mailbox in 10 minutes, and four concurrent requests per mailbox. You would hit it with one shared mailbox behind many busy phone lines, so spread bookings across mailboxes if that's your setup.

What does an Outlook calendar voice agent cost to run?

Agents run at $0.03/min, plus LLM usage and telephony. Your Microsoft 365 licenses are billed by Microsoft, and you host the service that holds the Graph token. Transfers work only on Twilio and SIP trunk numbers, not on Cartesia numbers, so put the number on Twilio or a SIP trunk if the agent hands callers to staff.

Get started today

Talk to an expert.

Connect with a member of our team and learn how Cartesia can help you build world-class voice experiences.

Contact Sales

Start building.

Access our models via API and bring a voice agent into production in minutes.

Try Cartesia