Table of contents
It always makes sense to carefully think about these scenarios. If it is possible to lower the number of recipients or spread the messages across multiple days, this will ALWAYS be the better choice. Also be aware that service limitations are there for a reason and that your Power Platform license also has a daily limit.
Use cases for high-volume messaging
- Inform users about upcoming changes within your organization
- Inform users about IT-system outages or service windows
- Send out “read receipts” for changes made to a process inside a quality management system
Comparison
A flow with default unoptimized messaging options takes about 16 minutes for 100 recipients, where as a flow with optimized messaging options only takes about 5 minutes. I tried also sending 500 messages, that took about 28 minutes and with 1000 messages it took about 45 minutes.
What happens when you reach limitations
- The respective API will throttle your requests, which in return will slow down your flow
- Recipients might be skipped without you knowing
- Your flow might fail entirely
Microsoft Teams
In Microsoft Teams high-volume messages can also be achieved by sending a message into a group or channel chat. If you are sending general information, you should use a channel. Because that is technically speaking quite easy, I will focus on single user messaging for Microsoft Teams.
Current limitations
Before we start
This method will send the Teams message in the context of the user who starts the flow. This will be the flow owner for automated or recurring flows. You can also define the run-only settings to always run in the owners context. Because of that I always recommend using a service account for this. This is also a simple flow. I am sure that there can be more improvements, but this worked fine for me.
How to
High-Level-Steps:
- Initialize variables
- Get your recipients addresses ready (I will skip details)
- Loop through all recipients
- Create a chat
- Send the message
Detailed steps:
- Initialize variables
- Name: intStatusCode, Type: Integer, Value: leave empty
- Optionally - Name: arrRecipients, Type: Array, Value: leave empty
- Set your recipients list and store it in arrRecipients
- The approach might vary for you here. Your recipients might come from an Excel sheet, a SharePoint List or other means. In my example I used a fairly simple array. I used this simple array. Add a E-Mail address here that is not yours.
- Add an “Apply to each” (loop) - action
- Use the arrRecipients variable as the input. You can also directly use the body/value dynamic input from Excel list rows action or get items action from SharePoint.
- Call the loop action “Apply to each - arrRecipients”
- In the loop add a “Do until” action. This do until will be responsible for creating a chat for the message to be send into.
- Call it “Do until - Create Chat”
- Enter these parameters
- Add a condition
- Call it “Condition - delay if chat creation gets throttled”
- Enter these parameters. Make sure the conditions are combined with “OR”. Both codes, 429 and 412, signal a throttled request where we need to wait two seconds to send that request again.
- To the TRUE path of that condition, add a delay action.
- Call it “Delay - two seconds create chat”
- Configure it for 2 seconds
- Do not add anything to the FALSE part
- Add a “Create a chat” action after the condition
- Leave the name as is
- Under “Members to add” you will have to add the recipients email address that you want to reach out to. In my case the property that stores is this, entered as an expression. Depending on your case this will vary and can be a dynamic input.
- Under settings in that action enter the value “PT5S” into the Action timeout parameter. This will help with some throttling using the create a chat action.
- Last action for this do until is the “Set variable” action.
- Call it “Set variable - intStatusCode create a chat”
- Use an expression to add this code. This code will save the statusCode of the create a chat action into the intStatusCode variable.
- Under settings configure the run after parameter. This will make sure we catch both a successfully created chat as well as a throttled action, just in case. Check the following options.
- In the loop add a second “Do until” action. This do until will be responsible for sending the message into the chat we created before.
- Call it “Do until - Send message”
- Add a condition
- Call it “Condition - delay if send message gets throttled”
- Enter these parameters
- To the TRUE path of that condition, add a delay action.
- Call it “Delay - two seconds send message”
- Configure it for 2 seconds
- Do not add anything to the FALSE part
- After the condition add a “Send a Microsoft Graph HTTP request” action from the Microsoft Teams connector group.
- Call it “Send a Microsoft Graph HTTP request - Send message”
- Configure the parameters as shown in the screenshot, using the code below it. This will send a plain message to the recipient. You can also send adaptive cards, which are formatted and therefore, much prettier 🙂
- Lastly, add another Set variable action
- Call it “Set variable - intStatusCode Send Message”
- Add this code as a value using an expression
- Under settings configure the run after parameter as follows:
Use: We will store the status code of the actions in there to determine if we need to delay and try again or if the action was successful.
Use: You can store all message recipients in this variable. If you want to directly use the list rows outputs from Excel or other list type outputs. Feel free.
[
{
"Mail": "thisisnotmyemail@domain.com"
}
]
item()?['Mail']
Coalesce(outputs('Create_a_chat')?['statusCode'],429)


//IF you did not change the create a chat actions name, as instructed, you can paste the following code into the URI input box
URI: https://graph.microsoft.com/v1.0/me/chats/@{outputs('Create_a_chat')?['body/id']}/messages
Method: POST
Body: {
"body": {
"content": "Hello world. This is your plain text."
}
}
Content-type: application/json
//Again if you have renamed the http action as instructed, simply paste the code below into the expression builder
outputs('Send_a_Microsoft_Graph_HTTP_request_-_Send_message')?['statusCode']

Congrats! You are done. Add other actions after if needed or try it out. Remember, I would recommend using a service account as the flow owner will be the sender of the message and with this method you cannot send a message to the same user that owns the flow.
Exchange Online (Outlook)
Please be aware that some limitations will depend on your Exchange administrators configuration. Notice also a special service within Exchange Online called: High-Volume E-Mail
Current limitations
Before we start
I would generally recommend packing multiple recipients into one E-Mail if content is not personalized. To keep privacy set those recipients as BCC and add yourself or any email address as the primary recipient. If you have an array of multiple hundred, you would need to “chunk” them into a size that your company allows. That chunk size might be 50, 100 or up to 1000. Also be aware of the recipient rate limit per day as well as the message rate limit per minute.
Also, I always recommend using a service account for this.
More here at a later time!
Thanks for reading! 💕