> ## Documentation Index
> Fetch the complete documentation index at: https://www.integrate.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ETL: Outlook Source

> Read Microsoft Outlook calendar events or mail messages into Integrate.io ETL pipelines using a delegated Microsoft sign-in with full or incremental loads.

Use the Outlook source component to read Microsoft Outlook **calendar events** or **mail messages** through Microsoft Graph into your Integrate.io ETL pipeline.

## When to use it

* Load meetings from a calendar into a warehouse for reporting on time spent, meeting volume, or attendance.
* Load mail from a folder to track inbound requests, notifications, or correspondence with customers.
* Copy events from one calendar to another together with the [Outlook Calendar destination](/docs/etl/using-components-outlook-calendar-destination).

## Connection

The Outlook connection uses delegated OAuth. Click **Authenticate** and sign in with the Microsoft 365 account whose calendar and mail you want to read. The source reads data as that user, so it can read only what that user can see in Outlook.

The mailbox is part of the connection. By default the source reads the signed-in user's own mailbox. To read a shared mailbox, enter its address on the connection. Reading mail from a shared mailbox needs Full Access to it.

Integrate.io stores the connection's access and refresh tokens. A token that expires during a job is refreshed automatically. If Microsoft rejects the refresh, sign in to the connection again.

The connection is tied to the account that signs in. If that person leaves or loses access, the connection stops working. For production pipelines, sign in with a service account.

### Create an Outlook connection

<Steps>
  <Step>
    Go to the **Connections** tab and click **+ New connection**.
  </Step>

  <Step>
    Search for and select **Outlook**.
  </Step>

  <Step>
    Click **Authenticate** and sign in with the Microsoft 365 account. Review and accept the requested permissions.
  </Step>

  <Step>
    Optionally, enter a **Mailbox** to use a shared mailbox instead of the signed-in user's own. Enter the mailbox's email address (user principal name) or its Microsoft Entra user object ID. Leave it blank for the signed-in user's mailbox.
  </Step>

  <Step>
    Enter a connection name, click **Test Connection**, then click **Create Connection**.
  </Step>
</Steps>

**Test Connection** reads the mailbox's default calendar and its Inbox. If either check fails, the error names the one that failed. A shared mailbox that is shared for mail but not for the calendar, or the reverse, fails here instead of in a job.

The connection asks Microsoft for these delegated permissions. Users can consent to them without a Microsoft 365 admin:

| Permission | Used for |
| :- | :- |
| `Calendars.ReadWrite`, `Calendars.ReadWrite.Shared` | Reading events, and writing them with the Outlook Calendar destination, in the user's own or a shared mailbox. |
| `Mail.Read`, `Mail.Read.Shared` | Reading mail in the user's own or a shared mailbox. |
| `offline_access` | Refreshing the token without signing in again. |
| `openid`, `email`, `profile` | Showing which account signed in. |

Every Outlook connection asks for calendar write permission, even if you only use it with the source.

## Source properties

### Read

Select what to read:

* **Calendar events.** Recurring meetings are returned as individual occurrences, one row per occurrence.
* **Mail messages.**

### Calendar (events only)

Select the calendar by name from the calendars of the connection's mailbox. The default calendar is marked **(default calendar)**. If the selected calendar is removed from the mailbox, or the signed-in user loses access to it, the editor won't save until you pick another calendar.

### Folder (mail only)

The mail folder to read:

* **Inbox** (default)
* **Sent Items**
* **Archive**
* **All folders (including Deleted Items and Junk Email)**

### Load Type

* **Full Load.** Reads every message in the folder, or the events from 30 days before the run date to 90 days after it.
* **Incremental Load.** Reads only the records after or before a reference date. The options are described below.

### Incremental Load settings

**Date field (mail only).** The message date the load compares:

* **Received** (default). When the message arrived.
* **Sent.** When it was sent. Drafts have no sent date, so they are not read.
* **Last modified.** Any change, such as being read, moved, or flagged. Use this to pick up messages that changed since the last run.

**Load records.**

* For mail: **newer than ( > )** or **older than ( \< )** the reference date.
* For events: **occurring after ( > )** or **occurring before ( \< )** the reference date.

**Reference date.**

* **Last successful run.** The time the last successful run of this package started. Until a run has succeeded there is no such time, so the first run reads what a Full Load reads.
* **Fixed Date.** A date you pick.
* **Variable.** A package variable. If the variable is blank at run time, a mail load reads every message, as a Full Load does.
* **Relative date.** A number of days ago or from now, counted in whole UTC days from the run date. Up to 3650 days.

### How events are read

Events are read by when they occur, not by when they were last changed. Microsoft Graph needs both ends of a date range to expand recurring meetings, so every events load reads a bounded range:

| Load | Events read |
| :- | :- |
| Full Load | From 30 days before the run date to 90 days after it. |
| Occurring after a date | The 90 days after the date. |
| Occurring before a date | The 30 days before the date. |

### How mail is read

Messages are read in order of the date field, up to the moment the run started. A message that is moved, deleted, or changed while the job runs does not cause other messages to be skipped. Message and event bodies are returned as plain text.

<Note>
  Each run returns the records as they are at that moment. To keep a table in sync, use `id` as the key in your destination and update rows that already exist. A message or event deleted in Outlook stops appearing in later runs, and the source doesn't report the deletion.
</Note>

## Schema

Select the fields to read. Date-times are returned in ISO 8601 format in UTC, for example `2026-10-01T09:00:00.000Z`. Lists of addresses and categories are comma-separated. A value Outlook does not return is null.

Events and messages both return immutable IDs. An event's `id` doesn't change when the event is moved to another folder or calendar, so you can use it to update the same event later with the Outlook Calendar destination.

### Events

| Field | Description |
| :- | :- |
| `id` | Outlook event ID. |
| `ical_uid` | iCalendar UID shared by all copies of the event. |
| `series_master_id` | ID of the recurring series an occurrence belongs to. |
| `event_type` | `singleInstance`, `occurrence`, `exception`, or `seriesMaster`. |
| `subject` | Event title. |
| `body` | Event body. |
| `body_preview` | Short plain-text preview of the body. |
| `start_time`, `end_time` | Start and end, in UTC. For an all-day event these are its first and last day at 00:00 UTC. |
| `is_all_day` | `true` for all-day events. |
| `start_time_zone`, `end_time_zone` | Time zones the event was created in. |
| `location` | Location display name. |
| `organizer_name`, `organizer_email` | Organizer. |
| `attendee_emails` | Attendee addresses, comma-separated. |
| `attendees` | Attendees as a JSON array. |
| `categories` | Categories, comma-separated. |
| `show_as` | Free/busy status, such as `busy` or `tentative`. |
| `sensitivity` | `normal`, `personal`, `private`, or `confidential`. |
| `importance` | `low`, `normal`, or `high`. |
| `is_cancelled` | `true` if the event is cancelled. |
| `is_organizer` | `true` if the signed-in user is the organizer. |
| `is_online_meeting` | `true` for online meetings. |
| `online_meeting_join_url` | Join link for an online meeting. |
| `response_status` | The signed-in user's response to the invitation. |
| `web_link` | Link that opens the event in Outlook on the web. |
| `created_at`, `last_modified_at` | When the event was created and last changed. |

### Messages

| Field | Description |
| :- | :- |
| `id` | Outlook message ID. |
| `conversation_id` | ID of the conversation (thread). |
| `internet_message_id` | The message's `Message-ID` header. |
| `subject` | Subject line. |
| `body` | Message body. |
| `body_preview` | Short plain-text preview of the body. |
| `from_name`, `from_email` | Sender shown in the From line. |
| `sender_email` | Account that actually sent the message. |
| `to_emails`, `cc_emails`, `bcc_emails` | Recipients, comma-separated. |
| `reply_to_emails` | Reply-to addresses, comma-separated. |
| `received_at`, `sent_at` | When the message was received and sent. |
| `has_attachments` | `true` if the message has attachments. |
| `importance` | `low`, `normal`, or `high`. |
| `is_read`, `is_draft` | Read and draft flags. |
| `categories` | Categories, comma-separated. |
| `parent_folder_id` | ID of the folder that holds the message. |
| `web_link` | Link that opens the message in Outlook on the web. |
| `created_at`, `last_modified_at` | When the message was created and last changed. |

## Example: incremental mail load

To load new inbox messages on each scheduled run, set:

* **Read:** Mail messages
* **Folder:** Inbox
* **Load Type:** Incremental Load
* **Date field:** Received
* **Load records:** newer than ( > )
* **Reference date:** Last successful run

The first run reads every inbox message. Each later run reads only messages received since the previous successful run started. In the destination, use `id` as the key.

## Example: upcoming meetings

To load the meetings of the next 90 days on each run, set:

* **Read:** Calendar events
* **Calendar:** the calendar to report on
* **Load Type:** Incremental Load
* **Load records:** occurring after ( > )
* **Reference date:** Relative date, 0 days from now

Each run reads the events that occur in the 90 days from 00:00 UTC on the run date. Use `id` as the key in your destination, so a meeting that moves or changes updates its existing row.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.