Skip to content

Microsoft 365 integration (Outlook + Teams)

Datahub can fan platform signals — task completion, workflow approvals, alert rule fires — into your team through Outlook email and Teams Workflows webhooks. Each Datahub deployment is connected to one customer-owned Azure App Registration in your tenant; Datahub never holds tokens for any other tenant.

When to use it

Use the Microsoft 365 integration when you want platform signals to land in:

  • A shared Teams channel — for example, a #data-quality channel that should receive a message every time a Logic Engine alert fires or a workflow gets rejected.
  • A specific mailbox — a stewardship inbox, a vendor-facing alias, or an alerts distribution list.

You can configure both at once. Each "destination" is called a channel in Datahub and is configured per integration.

How it works

Datahub event  →  Microsoft 365 dispatcher  →  Outlook or Teams
   (task,           (capability gate +              (Graph API
    workflow,         channel match)                 or webhook URL)
    alert)
  • Datahub authenticates to your tenant with the client credentials flow — no user consent, no per-user OAuth, no shared multi-tenant app.
  • For Outlook, Datahub calls POST /users/{from}/sendMail on Microsoft Graph using the App Registration's Mail.Send (Application) permission.
  • For Teams, Datahub posts an Adaptive Card to a Workflows-app (Power Automate) trigger URL. No Graph permission is needed — just the trigger URL pasted into a Datahub channel row. The standard Teams Workflows template handles delivery automatically; no manual flow configuration is required.

Every dispatch attempt — delivered, failed, or blocked — is recorded in the integration's Activity tab so admins can audit what was sent and why.

Setup

1. Create the Azure App Registration

You must do this in your own Microsoft Entra tenant. Datahub never registers an app on your behalf.

  1. Open the Microsoft Entra admin centreApplications → App registrations → New registration.
  2. Name it something recognisable (for example Datahub notifications).
  3. Supported account types: choose Accounts in this organizational directory only (single tenant) — Datahub only ever talks to your tenant.
  4. Redirect URI: leave blank (Datahub uses client credentials, not user OAuth).
  5. Save.

On the new app's Overview page, copy:

  • Directory (tenant) ID
  • Application (client) ID

2. Grant Microsoft Graph permissions

Still on the new app:

  1. API permissions → Add a permission → Microsoft Graph → Application permissions.
  2. Add the permissions you need:
Capability you want Permission Notes
Outlook email delivery Mail.Send Required for any Outlook channel. By default this lets the app send as any mailbox; you can scope this with an application access policy (recommended — see below).
Teams Workflows webhooks none Teams uses Workflows-app trigger URLs, not Graph. Skip this if you only want Teams.
  1. Click Grant admin consent for {tenant} and confirm. The status column should switch to Granted.

Mail.Send (Application) lets the app send as any mailbox in the tenant. To restrict it, create an application access policy in Exchange Online:

# In Exchange Online PowerShell (Connect-ExchangeOnline)
New-ApplicationAccessPolicy `
  -AppId <client-id> `
  -PolicyScopeGroupId datahub-senders@yourcompany.com `
  -AccessRight RestrictAccess `
  -Description "Datahub may only send mail as members of datahub-senders"

Add the mailboxes Datahub should be able to send from to the datahub-senders mail-enabled security group.

3. Create a client secret

  1. Certificates & secrets → New client secret → Add.
  2. Choose an expiration that fits your rotation policy (12 or 24 months is typical).
  3. Copy the value immediately — Azure shows it only once.

4. Configure the Datahub integration

  1. In Datahub: Admin → Integrations → Microsoft 365. Open the integration.
  2. On the Credentials & capabilities tab paste:
  3. Tenant ID (from step 1)
  4. Application (client) ID (from step 1)
  5. Client secret (from step 3)
  6. Below, toggle the capabilities you have permissions for:
  7. Outlook email — turn on if you granted Mail.Send (Application).
  8. Teams Workflows webhooks — turn on if you want to dispatch to Teams channels.
  9. Click Save, then Test connection in the side panel. A successful test confirms the credentials work and Datahub can mint Graph tokens.

You can flip a capability off at any time to pause dispatch without deleting any channel rows — useful if you need to rotate credentials or temporarily quiet a noisy notification source.

5. Add channels

Switch to the Channels tab and click Add channel.

For a Teams channel:

  1. In Teams, go to the target channel. Click the ··· (More options) icon next to the channel name.
  2. Select Workflows from the context menu.
  3. Search for and select the "Send webhook alerts to a channel" template.
  4. In the wizard, select the target team and channel, then click Save.
  5. After the workflow is saved, click Copy next to the generated trigger URL (it looks like https://{env}.{region}.environment.api.powerplatform.com:443/powerautomate/automations/direct/workflows/…).
  6. In Datahub: pick Teams Workflows webhook, paste the trigger URL, give the channel a recognisable name, pick which events it should subscribe to.

Note: The trigger URL is the credential — treat it like a password. Anyone holding it can POST payloads that fire your workflow. Regenerate it in Power Automate if you suspect leakage and update the URL in Datahub.

For an Outlook destination:

  1. Pick Outlook.
  2. From mailbox = the user principal name (UPN, e.g. alerts@contoso.com) or object ID of the mailbox Datahub should send as. The App Registration's policy must permit sending as this mailbox.
  3. Recipients = one or more email addresses (press Enter or comma to add).
  4. Pick which events the channel should subscribe to.

You can subscribe to the wildcard * (everything) or to a specific subset — typical choices:

Event What fires it
Task completed A user marks a Datahub task as done.
Task overdue A task crossed its due date without being completed.
Workflow step advanced An approval workflow moved to its next step (intermediate sign-off).
Workflow completed An approval workflow reached its terminal "approved" state.
Workflow rejected An approval workflow was rejected at any step.

Logic Engine alert fires are not dispatched as wildcard events — admins wire them per-rule via a Microsoft 365 action on each alert (see below). This avoids double-delivery when a wildcard channel and a per-rule action would both want to notify.

6. (Optional) Wire Logic Engine alerts

To send a specific alert rule to an M365 channel:

  1. Open the alert rule in Logic Engine.
  2. Under THEN, add an action of type Microsoft 365.
  3. Pick the integration, then the channel within it. Save.

The alert action runs only when this rule fires — separate from the integration's wildcard channels, so noise stays controllable.

Day-2: testing and audit

  • The Channels tab has a Send test message button on every channel row. It dispatches a test payload or test email straight from your browser through the same code path live notifications use, so a successful test means real signals will land too.
  • The Activity tab is the audit trail — last 100 dispatch attempts with delivered / failed / blocked status, HTTP response code, and any error message. Failures stay in the log so you can investigate Microsoft Graph rate limits, permission gaps, or invalid webhooks without Datahub silently swallowing them.

Limitations

Teams via Workflows app webhooks, not full Graph

Datahub uses Workflows-app (Power Automate) trigger URLs for Teams channel messages, not the Microsoft Graph ChannelMessage.Send endpoint. This keeps onboarding lightweight — no admin consent for Teamwork.Migrate.All or RSC — but it means:

  • Each Teams channel destination is a single trigger URL pasted into Datahub. Anyone holding that URL can POST to the workflow until you regenerate it in Power Automate.
  • Datahub sends a fully-formed Adaptive Card (title + body, full-width). The card is rendered as-is by the Workflows template — no extra flow configuration is needed.
  • Replies, threading, mentions and reactions are not surfaced back to Datahub.
  • If you need Datahub to read Teams messages or post as a specific user, that's outside the scope of this integration — open a feature request.

Payload contract: Datahub POSTs a v1.2 Adaptive Card JSON to the trigger URL. The "Send webhook alerts to a channel" Workflows template renders it directly — no custom flow expressions needed.

One App Registration per Datahub deployment

Each Datahub deployment maps to one Azure App Registration. If you operate two Datahub environments (e.g. UAT + PROD) you create two App Registrations and grant each its own Mail.Send policy.

Outlook needs a real mailbox to send as

Mail.Send (Application) requires the From mailbox to be a real, licensed mailbox in your tenant — not a contact, distribution group, or external address. Shared mailboxes work; the App Registration just needs send-as permission on them (controlled via the application access policy from step 2).

Webhook URLs are bearer secrets

A Teams Workflows-app trigger URL grants posting rights that can fire your workflow until you regenerate it in Power Automate. Treat the URL like a password:

  • Don't paste it into chat or tickets.
  • Regenerate it in Power Automate if you suspect leakage; paste the new URL into the Datahub channel modal.
  • Datahub stores webhook URLs inside the integration's configuration JSON; admins with Integrations: Manage can read them, by design, so they can rotate.

No outbound to private network webhooks

Datahub blocks Teams webhook URLs whose host resolves to a private, loopback, or link-local address. The dispatch is recorded with status blocked in the Activity tab. This applies to any URL you paste — including reverse proxies pointed at internal hosts. Use official Power Automate trigger URLs (*.environment.api.powerplatform.com or *.logic.azure.com).

Troubleshooting

Symptom Likely cause Fix
Test connection fails with AADSTS7000215 Wrong client secret Generate a new secret in Azure → paste in Datahub → save
Test connection fails with AADSTS50034 Wrong tenant ID Copy the Directory (tenant) ID from the App Registration overview (not from your user account)
Outlook test sends, but production messages fail with Access Denied App access policy excludes the From mailbox Add the mailbox to the policy's PolicyScopeGroupId group, or remove the policy if you intentionally want unrestricted sending
Teams test fails with 404 or 400 Bad Request Workflow trigger URL is stale (flow was deleted or regenerated) or copied incorrectly Re-copy the trigger URL from Power Automate → your flow → trigger details, and update the channel in Datahub
Teams Activity tab shows delivered for the test but no message appears in Teams The Workflows template was created using a custom action instead of the standard "Send webhook alerts to a channel" template, or the flow is turned off In Power Automate, confirm the flow is on and uses the "Send webhook alerts to a channel" template (trigger: "When a Teams webhook request is received" + action: "Post card in a chat or channel"). Datahub sends a fully-formed Adaptive Card — the template renders it without any custom configuration.
Activity tab shows blocked rows Webhook hostname resolves to a private IP Use an official Power Automate trigger URL (*.environment.api.powerplatform.com or *.logic.azure.com) — never a reverse proxy
Notifications stopped arriving but Test passes A capability flag (Outlook / Teams) was switched off Re-enable on the Credentials & capabilities tab
Logic Engine alert fires but no M365 message The alert has no Microsoft 365 action, or the action's channel is disabled Open the rule → THEN → confirm a microsoft_365 action exists with a valid integration + channel

What Datahub stores

Item Storage Notes
tenant_id Integration config JSON (not a secret) Visible to admins via the Integrations API
client_id, client_secret Key Vault Backend stores Key Vault references in the database; secret values never leave the backend
Channels Integration config JSON Includes Teams webhook URLs and Outlook recipients/from-mailbox
Dispatch log integrations.m365_dispatch_log table One row per attempt — delivered/failed/blocked, HTTP status, error message
Microsoft Graph access tokens In-memory cache only Acquired via client_credentials, never persisted to disk

Datahub never stores user-level OAuth tokens, refresh tokens, or any user identity from your Entra tenant — the integration is exclusively app-only.