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

# Set Up the Microsoft Teams Webhook Connector

> Post Genesis-authored alerts, scheduled reports, and approval-handoff cards into a Microsoft Teams channel via Power Automate Workflows. Step-by-step setup, an actions reference, governance guidance, and a troubleshooting catalog.

The Microsoft Teams Webhook connector lets Genesis bots post operational notifications, alerts, scheduled reports, and approval-handoff cards to a Microsoft Teams channel via a Power Automate Workflow URL. This is the **outbound, bot-attributed** path — messages appear in Teams as posted by the Workflow identity, not by any individual human user.

This connector is the right fit for:

* Pipeline failure alerts (dbt / Snowflake task failures)
* Data quality alerts pushed through Genesis enrichment
* Scheduled daily / weekly report delivery
* SLA breach notifications
* Surface-a-finding-for-review cards for human attention

<Note>
  If you need inbound interaction (Genesis reading messages users post in Teams), this connector does not cover it — that requires a separate inbound surface. See [Activate Eve in Teams (Bot Framework)](/docs/Workspaces/Microsoft-Teams/Activate-Bot-Framework-Eve-in-Teams) for the bot path that handles `@`-mentions and direct messages. Adaptive Card `Action.Execute` callbacks on that path are pending end-to-end verification and must not be treated as supported. See [Microsoft Teams (Graph connection)](/docs/Setup/Microsoft-Teams) for the delegated-OAuth path that sends as a specific human user.
</Note>

## Relationship to the other Microsoft Teams paths

Genesis ships three distinct paths for Teams integration. They are **complementary** and can coexist in the same deployment.

| Connector | Auth model | Sender attribution | Best for |
| - | - | - | - |
| [Microsoft Teams (Graph connection)](/docs/Setup/Microsoft-Teams) | Delegated OAuth as a real Microsoft 365 user | The connected human | Sending as a person, listing teams/channels, looking up users — operations that depend on a specific human identity |
| [Bot Framework](/docs/Workspaces/Microsoft-Teams/Activate-Bot-Framework-Eve-in-Teams) | Per-bot Azure Bot credentials, Microsoft-signed JWT on inbound | The Genesis bot principal | Inbound `@`-mentions and direct messages; Adaptive Card callbacks are pending end-to-end verification |
| **Microsoft Teams Webhook (this page)** | Shared webhook URL stored as a Genesis Secret | Workflow bot identity | Automated operational notifications, scheduled reports, alert cards |

For most customer alerting use cases, the webhook connector is the right tool — human attribution is incorrect for automated notifications, and outbound alerting does not need a full two-way bot.

## Prerequisites

* A Microsoft 365 tenant with Microsoft Teams
* A Teams channel where notifications should land (for example, `#Genesis Alerts`)
* Permission in that channel to create a Workflow (most users can; some tenants restrict via Power Platform DLP policies)
* A Genesis user with admin access to the Secrets management surface

<Tip>
  No Power Automate Premium licensing is required for the outbound notification path.
</Tip>

## Setup

<Steps>
  <Step title="Create the Workflow in Microsoft Teams">
    In the target Teams channel:

    1. Click the **··· (More options)** menu next to the channel name → **Workflows**
    2. Search for and select the template **"Send webhook alerts to channel"** (or **"Post to a channel when a webhook request is received"** in some Teams versions — both work)
    3. Name the workflow descriptively, e.g. **"Genesis Alerts webhook"**
    4. Confirm the **team** and **channel** the workflow will post into
    5. Click **Add workflow** → **Done**

    The workflow is now active. Microsoft will generate a webhook URL for it.

    <Warning>
      The workflow name you choose here is **internal Power Automate metadata** for whoever manages the customer's flows. It is **not** a branding lever — Microsoft 365 always attributes every Workflow-posted message to the "Workflows" bot identity in the Teams message header, regardless of the per-flow name. Genesis-side branding (logo, colored header, footer) is rendered inside the Adaptive Card body itself by the typed builders documented below.
    </Warning>
  </Step>

  <Step title="Copy the webhook URL">
    From the Workflows panel (Teams left rail → **Workflows** → select the workflow you just created):

    1. Click **Copy webhook link**
    2. The URL looks like `https://default<TENANT_ID>.<REGION>.environment.api.powerplatform.com/powerautomate/automations/direct/workflows/<WORKFLOW_ID>/triggers/manual/paths/invoke?...sig=<SIGNATURE>`

    <Warning>
      **Treat this URL as a secret.** Anyone who has the URL can post to the channel — there is no additional authentication. Do not paste it into source control, email, or any unencrypted store.
    </Warning>
  </Step>

  <Step title="Store the URL as a Genesis Secret">
    The webhook URL is consumed as a **Secret reference**, not a Connection. There is no "Microsoft Teams Webhook" entry in the Connections page.

    <Tabs>
      <Tab title="Genesis dashboard">
        1. Open the Genesis dashboard → **Secrets** (or **API Keys**, depending on dashboard version)
        2. Click **New Secret**
        3. **Name**: must start with `secret_`. Pick a descriptive suffix that names the destination, e.g. `secret_contoso_genesis_alerts` or `secret_data_pipeline_alerts_channel`
        4. **Value**: paste the full webhook URL from step 2
        5. Save
      </Tab>

      <Tab title="HTTP endpoint">
        ```bash theme={null}
        curl -X POST https://<your-genesis-host>/api/secrets \
          -H "Authorization: Bearer <your-token>" \
          -H "Content-Type: application/json" \
          -d '{
            "name": "secret_contoso_genesis_alerts",
            "value": "https://default<...>powerplatform.com/...sig=<...>"
          }'
        ```
      </Tab>

      <Tab title="Programmatic (in-cluster)">
        ```python theme={null}
        from genesis_bots.core.secrets import create_secret

        create_secret(
            "secret_contoso_genesis_alerts",
            "https://default<...>powerplatform.com/...sig=<...>",
            user="<admin-user-id>",
        )
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Teach the bot which secret to use">
    The agent invokes the webhook tool by passing the secret reference name as the `webhook_url` argument. The agent learns the mapping from `(routing intent) → (secret reference name)` via one of:

    * **Bot persona / instructions** *(recommended)*: bake the mapping into the bot's system prompt. Example: *"When posting an alert about a pipeline failure, post to `secret_contoso_genesis_alerts`."*
    * **Per-call argument**: the agent decides which secret to use at runtime based on context. Less reliable; persona-baked routing is preferred for stable operational workflows.

    If your customer uses multiple channels (for example `secret_critical_alerts` + `secret_data_pipeline_alerts` + `secret_scheduled_reports`), each gets its own secret and the bot persona routes by intent.
  </Step>

  <Step title="Test the connection">
    From a bot conversation:

    ```text theme={null}
    Use teams_webhook_tools to TEST_WEBHOOK against secret_contoso_genesis_alerts
    ```

    A successful response confirms the URL resolves, the hostname is allow-listed, and the Workflow accepts the POST. The test will not post a visible message to the channel.

    To verify visual delivery, ask the bot to send a real notification:

    ```text theme={null}
    Send a test alert to secret_contoso_genesis_alerts with title "Genesis webhook setup verified" and severity Info, and fields setup=complete, verified_by=<your-name>
    ```

    The notification card should appear in the channel within a few seconds.
  </Step>
</Steps>

## Actions reference

The agent-facing actions are exposed on `teams_webhook_tools`. The typed actions (`SEND_ALERT`, `SEND_SCHEDULED_REPORT`, `SEND_APPROVAL_HANDOFF`) are preferred over `SEND_ADAPTIVE_CARD` for their respective use cases — the agent passes typed parameters and the builder produces a well-formed, semantically-validated card.

| Action | What it sends | Typical use |
| - | - | - |
| `TEST_WEBHOOK` | Sanity ping; no visible artifact | Verify URL + connectivity at setup time |
| `SEND_MESSAGE` | Plain text wrapped in a minimal Adaptive Card | Lightweight notifications without structured fields |
| `SEND_NOTIFICATION` | Title + key/value fields | General-purpose structured notification |
| `SEND_ADAPTIVE_CARD` | Raw Adaptive Card JSON | Custom card shapes the typed builders don't cover |
| `SEND_ALERT` | Typed alert card with severity color-coding (Critical/Warning/Info/Good) + optional details URL | Pipeline failures, SLA breaches, Monte-Carlo-style alerts |
| `SEND_SCHEDULED_REPORT` | Typed report card with titled sections + generation timestamp | Daily / weekly summary delivery |
| `SEND_APPROVAL_HANDOFF` | Display-only handoff card with title, summary, and a "reply in Genesis" instruction | Cards posted for human review and asynchronous decision |

<Note>
  **Genesis branding scope:** typed cards (`SEND_ALERT`, `SEND_SCHEDULED_REPORT`, `SEND_APPROVAL_HANDOFF`) are wrapped with a Genesis-branded shell: a logo image at the top, a colored header bar keyed off severity or action type, and a "Sent by Genesis" footer. Branding is intentionally scoped to typed cards only — `SEND_MESSAGE`, `SEND_NOTIFICATION`, and raw `SEND_ADAPTIVE_CARD` payloads remain pass-through, since callers there author the card shape directly.
</Note>

<Note>
  **`SEND_APPROVAL_HANDOFF` is display-only.** The `*.api.powerplatform.com` webhook delivery path cannot receive `Action.Submit` round-trips, so no Approve / Reject buttons are emitted. The card instructs the reader to reply in Genesis to record the decision. Round-trip card-button callbacks require Bot Framework and are tracked as a separate deferred capability.
</Note>

For the full parameter list of each action, see [`Additional Tool Groups → Microsoft Teams Webhook Tools`](/docs/Genbot-Toolkit/Additional-Tool-Groups).

## Wiring it up to actually fire automatically

Once the connector is set up and a bot persona knows which secret to use, you still need something to **trigger** the bot to fire the webhook — an alert that has to be typed by a human every time isn't very useful. See [Automate Teams Alerts via the Scheduler](/docs/Workspaces/Microsoft-Teams/Teams-Webhook-Monitoring) for the recommended scheduler-based pattern, a worked starter for a dbt-failure alerter, design considerations (cadence, deduplication, failure modes), and an honest catalog of what does not work today (Snowflake `TASK` → Genesis HTTP, generic inbound webhooks, composite tool emission, reactive observability — each with its workaround).

## Webhook URL governance

The webhook URL is bearer-token-equivalent: any party who holds it can post to the channel. Treat accordingly.

### Naming convention

Use descriptive, target-disambiguated suffixes after the mandatory `secret_` prefix:

* ✅ `secret_contoso_genesis_alerts`
* ✅ `secret_data_pipeline_alerts_channel`
* ✅ `secret_critical_ops_handoff`
* ❌ `secret_teams_webhook` (which Teams channel? which customer?)
* ❌ `secret_url_1` (no context)

### Rotation

Microsoft does not impose a fixed expiry on Workflow webhook URLs. Rotation is operator-driven and recommended:

* **Annually** as part of routine secret hygiene
* **Immediately** if the URL is exposed (committed to source control, pasted in an email, etc.)
* **At ownership transfer** when the human who created the Workflow leaves the team

To rotate:

1. In Teams → Workflows panel → the relevant workflow → click the **··· (More options)** menu
2. Select **Edit** → there's typically a regenerate URL option (or delete + recreate the workflow)
3. Update the Genesis Secret's value to the new URL via the dashboard or `PUT /api/secrets/{secret_name}`
4. The next agent invocation picks up the new URL transparently — no Genesis restart required

### Ownership and blast radius

The Workflow in Teams is owned by the Microsoft 365 user who created it. If that user leaves the customer's organization, the Workflow may be disabled. Recommended practice:

* **Service account**: create the Workflow under a shared service-account user that survives individual employee turnover
* **Document ownership**: in your customer's runbook, record which Microsoft 365 user owns each Workflow and the contact responsible for rotation

The blast radius of a leaked webhook URL is limited to the single channel the Workflow posts to. There is no path from a webhook URL to other Microsoft 365 surfaces or other channels.

## Delivery assurance and observability

The webhook tool ships with bounded retries and per-attempt logging.

### Retries

Webhook sends retry up to 3 attempts with exponential backoff + jitter, bounded by a 21-second wall-clock budget. Retries fire on 5xx responses and network errors.

<Warning>
  **4xx responses (including 401, 404) are treated as terminal — no retry.** These typically indicate a configuration error (wrong secret, deleted Workflow, etc.) where retrying would not help.
</Warning>

### Per-attempt log records

Every send attempt writes a row to `tool_observability_facts` with:

* `tool_name = 'teams_webhook_action'`
* `tool_action` — for example `SEND_ALERT`, `SEND_NOTIFICATION`
* `result_json` — the full webhook response envelope (delivery status, HTTP code, attempt count, error excerpt if any)
* Timestamps for each attempt

### Querying recent deliveries

Agents can call `teams_webhook_recent_deliveries` to surface the last N deliveries with optional filtering by `delivery_status` (`completed` / `failed`). Useful for operator diagnostics ("did the alert about the dbt failure land at 09:14 actually go through?").

### Failure visibility

Failed sends emit observability rows but do not raise to the agent's conversation by default. For operator-visible alerting on persistent failures, route `tool_observability_facts` into your existing operational dashboard or use the OTEL metrics surface.

## Troubleshooting

<AccordionGroup>
  <Accordion title="“Invalid webhook host” error">
    The hostname did not match the allow-list. Supported hostname patterns:

    * `*.api.powerplatform.com` — current Microsoft 365 Workflows (preferred; this is what `Send webhook alerts to channel` produces)
    * `*.logic.azure.com` — legacy Azure Logic Apps (still functional)
    * `*.webhook.office.com` — deprecated O365 Connectors (still allowed for backward compatibility; emits a deprecation warning in the response)

    If your URL doesn't match any of these, you may be looking at a Workflow trigger URL from a different connector. Re-create the Workflow using the "Send webhook alerts to channel" template.
  </Accordion>

  <Accordion title="HTTP 401 / 403 from the Workflow">
    The signature in the URL has been rotated or the workflow has been deleted/disabled. Verify the Workflow is active in Teams and regenerate the URL if needed.
  </Accordion>

  <Accordion title="HTTP 4xx with body about Adaptive Card validation">
    The Adaptive Card JSON failed Microsoft's parser. Use the typed actions (`SEND_ALERT`, `SEND_SCHEDULED_REPORT`, `SEND_APPROVAL_HANDOFF`) rather than `SEND_ADAPTIVE_CARD` to let Genesis's semantic validator catch most issues before they reach Microsoft.
  </Accordion>

  <Accordion title="Webhook URL accidentally committed to source control">
    1. Rotate the URL immediately (see [Rotation](#rotation))
    2. Update the Genesis Secret value
    3. The exposed URL is now invalid; no further action needed
  </Accordion>

  <Accordion title="Sender attribution shows a human user's name">
    If the Workflow's "Send as" setting is configured for impersonation (some templates do this), the message will appear posted by the user who created the Workflow rather than by the Workflow bot. To fix: edit the Workflow → change the "Post as" setting to "Flow bot" or equivalent.
  </Accordion>
</AccordionGroup>

## Related

* [Automate Teams Alerts via the Scheduler](/docs/Workspaces/Microsoft-Teams/Teams-Webhook-Monitoring) — the trigger layer; recommended scheduler-based pattern + worked starter
* [Activate Eve in Teams (Bot Framework)](/docs/Workspaces/Microsoft-Teams/Activate-Bot-Framework-Eve-in-Teams) — the bot-attributed inbound message path; Adaptive Card callbacks are pending end-to-end verification
* [Microsoft Teams (Graph connection)](/docs/Setup/Microsoft-Teams) — the delegated-OAuth path that sends as a specific human user
* [Additional Tool Groups → Microsoft Teams Webhook Tools](/docs/Genbot-Toolkit/Additional-Tool-Groups) — full parameter list for each action
