In my series about the Graph API, I’m going to look at subscribe to ‘things’ to trigger a flow when events happen using MS Graph subscriptions in Power Automate.

MS Graph Subscriptions

Using the MS Graph subscription model it is possible to subscribe to any changes in on of the following:

  • Call Records
  • Channels
  • Chat
  • Chat Message
  • Contact
  • Conversation Members
  • Drive Item
  • Events
  • Groups
  • Group Conversation
  • Lists
  • Messages
  • Presence
  • Printers
  • Print Task Definition
  • Security Alert
  • Teams
  • To Do Tasks
  • Users

When you subscribe you can with different change types:

  • created
  • updated
  • deleted

Using these change types you can for example only trigger flows when an event is updated, deleted or created or a combination of these operation.

Subscribe using Power Automate

We are going to create two flows. A subscription flow that we run on a daily basis and a flow that we want to run to handle the process that we want to trigger.

This should result in a flow that looks like this:

Subscribe to Microsoft Graph API with MS Graph Subscriptions
MS Graph subscriptions using Power Automate 1

In the above example I’m subscribing to CallRecords that are created or updated.

For each subscription you have to specify an expiration date. As our flow resubscribes every day, I’m goig to set the subscription expiry time to 1 day after my subscription flow runs. I’m using the following expression for this:

addDays(UtcNow(), 1)

Callback URL

The List Callback URL action will give me the URL of the flow that I want to trigger when a new call comes in.

This matches the URL that is given by the When a HTTP request is received action of my flow that is being triggered every time a Call record is created or updated.

MS Graph subscriptions using Power Automate
MS Graph subscriptions using Power Automate 2

Subscription URIs

So for each different thing that we might want to subscribe to a specific UTI will need to be supplied. For Call records this is /communications/callRecords, but there are various options depending on what you want to subscribe to.

Handle the changes

Now we need to create a second flow. This flow will be triggered every time a change is made. So in our example every time a call is made our flow will trigger. Notice that this flow will also trigger when we subscribe.

MS Graph subscriptions using Power Automate
MS Graph subscriptions using Power Automate 3

The trigger will need to have a schema specified that looks like this:

{
"type": "object",
"properties": {
"validationToken": {
"type": "string"
}
}
}

And the validation token can now be used to see if we have ouor flow triggered because of the initial subscription or if this is a call record update trigger triggering our flow.

Then we need to respond back to the parent flow with a success code (200) to acknowledge that we have received the subscription. We also need to acknowledge any other triggers of our flow. After this acknowledgement you can now use the data that is supplied by the trigger of our flow. So in our example you will see that you get actual call records.


Discover more from SharePains

Subscribe to get the latest posts sent to your email.

Related Posts

11 thoughts on “MS Graph subscriptions using Power Automate

  1. Hi! This seems to be the easiest way to get the events, but I’m receiving this error when I run the first flow:
    “Subscription validation request failed. Response must exactly match validationToken query parameter.”
    What could be happening?

    1. You will need to collect the validation token on the subscription run of the handling flow. Then respond with that token for the subscription to be complete

  2. Id don’t get the whole subscription process. You run it initially for the first time and the POST request is triggering the child workflow. Then you have condition: if validationToken is null, then you return the response with 200 code and validationToken in the body (which is null). So the parent workflow will fail because there is no validationToken.
    If validationToken is not null, then workflow returns 200 response with empty body. What’s the point of it? When does validationToken have value and when do you actually return it?

  3. OK, I figured it out. You actually have to return verificationToken value in response. It seems that the screenshot you pasted is wrong.

  4. Hi there thanks for this! I’m hoping you can help because I am banging my head against the wall on this one. I am getting the child flow trigger when I request to Graph subscription, but the validationToken dynamic value is always blank. I have the schema as above, but it just isn’t finding it. This is the raw output from the “When a HTTP request is received” trigger:

    {
    “headers”: {
    “Accept”: “text/plain”,
    “Host”: “REMOVED”,
    “Max-Forwards”: “10”,
    “client-request-id”: “REMOVED”,
    “X-ARR-LOG-ID”: “REMOVED”,
    “CLIENT-IP”: “REMOVED”,
    “DISGUISED-HOST”: “REMOVED”,
    “X-SITE-DEPLOYMENT-ID”: “REMOVED”,
    “WAS-DEFAULT-HOSTNAME”: “REMOVED”,
    “X-Forwarded-Proto”: “https”,
    “X-AppService-Proto”: “https”,
    “X-ARR-SSL”: “REMOVED”,
    “X-Forwarded-TlsVersion”: “1.2”,
    “X-Forwarded-For”: “REMOVED”,
    “X-Original-URL”: “REMOVED”,
    “X-WAWS-Unencoded-URL”: “REMOVED”,
    “Content-Length”: “0”,
    “Content-Type”: “text/plain; charset=utf-8”
    },
    “queries”: {
    “validationToken”: “Validation: Testing client application reachability for subscription Request-Id: 3f6ad46e-1560-432f-8d18-69734c1ff680”
    }
    }

      1. Thank you, Pieter so much for responding! The problem seems to be that the value passed in empty. I wish I could send a screenshot. I am wondering if it is glitch or something… for instance, with the schema in your tutorial, it generates 4 dynamic values: Body, Header, Path Parameters, and validationToken. If I put a compose action directly after the trigger to view the values of these, they all return empty except for Header, which contains everything in the JSON I posted above, EXCEPT the validationToken info. I am at a loss.

      2. FYI, how I got this to give me a functional token was adding a compose action directly after the trigger with the following function:

        triggeroutputs()?[‘queries’]?[‘validationToken’]

  5. Hi @Pieter Veenstra,
    I have build both flows in power automate. i am not adding any condition for checking validation token in child flow. In parent flow, for notificationURL, i have directly placed a power automate flow URL instead of “List Flow”.
    when i tried to test the entire flow, parent flows thorws a error saying “Subscription validation request failed. Notification endpoint must respond with 200 OK to validation request.”
    But when i try to same URL in postman, it gives back 200.
    i could not see any request coming to child flow. can you help me here

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.