← All integrations
Power Automate
Automation integration
Coming soon
Included on
Pro, Team & Enterprise

Power Automate

Move meeting output into the Microsoft stack you already run. A native connector is on the way, and an HTTP-trigger flow works on the same partner API today.

How it works today

Power Automate can call TeamsMaestro before the native connector ships. Start a flow with the When an HTTP request is received trigger, then register the URL it generates as a webhook destination in your TeamsMaestro settings.

Once events are arriving, the branches teams build most often are a summary posted to a Teams channel, action items created as Planner tasks, and call notes appended to a SharePoint list.

Summary to Teams

New meeting summary → post it to a Teams channel

Action items to Planner

New action items → create a Planner task per item

Call notes to SharePoint

New call notes → add a row to a SharePoint list

API reference

This is the partner integration surface, the same API the certified connector is being built on, and the one an HTTP-trigger flow talks to today. The base URL is https://teams-app.maestrolabs.com and every path below sits under /integrations/partners/.

Authentication

Integrations authenticate with OAuth 2.0, authorization code with PKCE. PKCE is required, and a request without a code challenge is rejected. TeamsMaestro issues each integration its own access token, granted by the account holder and revocable by them, so the account holder's Microsoft credentials are never exposed to the integration.

Authorization: Bearer <access token>

Scopes are not used, so omit the scope parameter. Any explicit scope value is rejected with invalid_scope. A token grants whatever its account holder is permitted to do, and each endpoint enforces that through the account's plan and organization settings.

Access tokens last one hour and refresh tokens ninety days, with rotation enabled, so store the refresh token returned by every refresh response. A grace period of 120 seconds lets concurrent refreshes both succeed. Client credentials are issued on request; there is no self-service registration, and client secrets are shown once, at registration.

A partner token reaches /integrations/partners/ and nothing else. Any other path returns 403. Treat that as out of scope rather than as an expired token: refreshing does not change the outcome, and because refresh tokens rotate, a refresh-and-retry loop burns through them.

Webhook triggers, one operation per event

Power Automate expects a single trigger operation per event, so the subscribe call is also exposed with the event type fixed by the path. Both return the create response plus a Location header.

POST /integrations/partners/subscriptions/meeting-transcribed/
POST /integrations/partners/subscriptions/meeting-summarized/

The body is the same as the general subscribe call below, minus event_types, which the path overrides.

POST /integrations/partners/subscriptions/

A subscription is a target URL plus the event types delivered to it. Requires an active plan with webhooks.

The body takes target_url (required, at most 2048 characters, must resolve to a public address), event_types (required, at least one of meeting.transcribed and meeting.summarized), filter_match (optional, all or any, default all) and filters (optional array, default empty).

{
  "target_url": "https://hooks.example.com/teamsmaestro",
  "event_types": ["meeting.summarized"],
  "filter_match": "all",
  "filters": [
    { "field": "meeting.participants", "operator": "contains", "value": ["@external"] }
  ]
}

It returns 201 Created.

{
  "id": "0022c696-b12d-40e8-9c65-ba6f50d9bc38",
  "name": "Alex Rivera's Power Automate: 1",
  "source": "power-automate",
  "target_url": "https://hooks.example.com/teamsmaestro",
  "event_types": ["meeting.summarized"],
  "status": "active",
  "filter_match": "all",
  "filters": [
    { "field": "meeting.participants", "operator": "contains", "value": ["@external"] }
  ],
  "payload_version": 20260806,
  "created_at": "2026-08-04T19:12:44.104382Z"
}

id identifies the subscription for deletion. name is generated and not settable. source is the partner platform that created it. status is one of active, inactive, disabled and expired, and only active delivers. payload_version is the payload contract and is immutable. No signing secret is returned; see the note at the end.

Repeating the call with the same target_url rewrites the existing subscription, event types and filters included, reactivates it, and still returns 201. A target URL not used before, or an existing subscription that is disabled or expired, creates a new one instead.

400 covers an invalid target URL, empty event types, or a rejected filter. 403 covers a plan or organization restriction.

DELETE /integrations/partners/subscriptions/{id}/

Returns 204 No Content. This is the unsubscribe call a flow makes when it is turned off or deleted. It needs only a valid partner token, so an account with a lapsed plan can still unsubscribe.

GET /integrations/partners/subscriptions/

Lists the subscriptions this account created through the calling partner. Subscriptions created in the TeamsMaestro applications, or through a different partner, are not returned. The response is a bare array and is not paginated.

GET /integrations/partners/subscriptions/{id}/ returns one subscription in the same shape as the create response, and 404 if it belongs to another account or another partner.

GET /integrations/partners/me/

The identity of the account the access token belongs to. Use it as a connection test and as the source of a connection label. This is the only partner endpoint with no plan requirement, so it still answers for an account whose subscription has lapsed.

{
  "email": "owner@example.com",
  "name": "Alex Rivera",
  "organization": "Example Ltd",
  "partner": "Power Automate",
  "can_create_webhooks": true
}

email is stable and suitable as a key. name falls back to the email address when no name is set. organization is null for an individual account. can_create_webhooks reflects the plan and organization settings at the time of the call, and both can change afterwards, so treat the status code of the subscribe request as the authoritative answer rather than gating on this value alone.

401 means the token is expired, revoked, or not a Bearer credential. 403 means its OAuth client is not a registered partner.

GET /integrations/partners/event-types/

The catalogue of meeting events a subscription can listen to. No plan requirement, so it can be read before entitlement is established. The response is a bare array and is not paginated.

[
  { "id": "meeting.transcribed", "label": "Meeting Transcribed" },
  { "id": "meeting.summarized",  "label": "Meeting Summarized" }
]

Read this endpoint rather than hard-coding the list, since new event types appear here first. The two events fire independently and in that order, and each is evaluated separately, so a meeting with too little speech to summarize fires meeting.transcribed only.

GET /integrations/partners/events/

Past meetings rendered in the same shape as a webhook delivery, so a connector can be built and tested before a live meeting has happened. Neither this endpoint nor the sample one below delivers events. Requires an active plan with webhooks.

The query takes event_type (required, meeting.transcribed or meeting.summarized) and limit (optional, 1 to 25, default 3). The response is a bare array of delivery envelopes, newest first.

Three things differ from a live delivery: id is generated per call and is not an idempotency key, webhook_id refers to a placeholder subscription, and filters are not applied. An account with no meetings of that type gets an empty array, in which case fall back to the sample endpoint.

GET /integrations/partners/events/sample/

Synthetic payloads, for an account with no meetings. The optional event_type parameter restricts the response to one type, and omitting it returns all. Three samples come back per event type, differing in host, meeting platform, whether the transcript carries per-utterance segments, and which template produced the summary. Implement against all three.

POST /integrations/partners/subscriptions/{id}/send-sample/

Delivers a sample payload to the subscription's own target URL, signed with its own secret, once per event type on the subscription. Nothing is persisted, retried, or filtered. The body is empty.

{
  "results": [
    {
      "event": "meeting.summarized",
      "delivery_id": "evt_54f1c640-6c05-4147-9568-14b91bf67689",
      "payload": { "...": "the exact body that was POSTed" },
      "result": "succeeded",
      "response_status_code": 200,
      "response_body": "ok",
      "error_message": ""
    }
  ]
}

delivery_id is the X-Webhook-ID the delivery carried. result is succeeded, failed or cancelled. response_status_code and response_body come from the receiving endpoint and are null when no response arrived, in which case error_message is populated. A failure at the receiving endpoint is reported as a result inside a 200 response.

Signature verification

Partner subscriptions do not return a signing secret, and no partner endpoint exposes one. Deliveries are signed, but the key cannot be obtained through this surface. Where signature verification is required, the webhook has to be created in the TeamsMaestro web application instead. Otherwise treat the target URL as the credential: generate it per subscription, make it unguessable, and do not reuse it.

What's coming

The native connector replaces the manual trigger with OAuth2 sign-in and a proper trigger picker, so a flow starts from a named TeamsMaestro event rather than a URL you copied. Join the early access list and we will email you when it ships.

Frequently asked questions

Is this different from a native Power Automate connector?

Yes. Today's setup uses a generic HTTP-trigger flow. The native connector, coming soon, authenticates with OAuth2 and offers a proper trigger picker, so there is no URL or JSON to handle.

Do I need a paid TeamsMaestro plan?

Yes. This integration is included on the Pro, Team, and Enterprise plans. It is not available on the Free plan.