A common requirement is the need to collect responses from users outside of your organization. Anyone who’s spent a good deal of time within Power Platform knows this can quickly turn into a very complex task! I don’t want to license external users and I don’t want to build a Power Page to collect some simple form responses! Surely there’s got a be a simpler way? Well, with the help of the pre-filled URL feature in Microsoft Forms, and a little Power Automate, there is!
Scenario: Event Response Submissions
In this example, I’m gathering Power Platform Conference Event interest responses from users in my Dataverse Contacts table. Since many of these Contacts are external users, I need a way to send them a publicly accessible Microsoft Form. That part is easy. The tricky part is linking their responses back to their contact record and recording their event response in Dataverse.
Here’s a workflow illustration along with the technologies used:

Create the Microsoft Form and Prefilled URL
Creating the Microsoft Form itself is very straight-forward and beyond the scope of this post, but there are some key settings to configure for it. I had already created a form called “Microsoft Power Platform Event Interest Form” within my environment. Under the form settings, set Who can fill out this form to Anyone can respond.

The form consists of free text and single response options:

The key question number 4 however, “Enter Contact Id” is what we’re going to pre-fill with the contact’s unique guid.
Select the “Get pre-filled URL” link from the top-right menu. Navigate down to question 4 and just enter a bunch of a’s (we are going to dynamically change this later).


Click “Get Prefilled Link” and Copy the Link. Paste the link into a text editor like notepad. We will need this later!

The final item we need to account for on the form is how to hide the question for the contactid. After all, we can’t have the user changing this value! Select the question before your contact id question you’ll and see a 3 dot menu. Select add branching. Set the “go to” as “End of the form” which will effectively hide the contactid question.


Create Custom Response Events Table
While the contacts table is a straight out of box table, we need to create a custom table to capture the event responses. Create the corresponding column fields to capture the responses. For the Contact question, this is a lookup column back to the contacts table.

Send the Pre-filled Form to Contacts
The method in which I am using to actually send the pre-filled link to the contact involves a canvas app and the Outlook 365 connector. Of course, there’s many other ways this could be triggered but for the demo purposes, I felt this was easiest to show using a canvas app.
For the App onStart code, I am storing my pre-filled URL in a variable (minus the parameter value) called “varBasePreFormURL”.

Within my Contacts Gallery, I add an additional column for the “Form URL”. This will concatenate the Form Base URL with the contactid for the parameter pre-filled value.

Within the Contact Gallery, I have a button to send the Form link.

I used the following powerfx on the button’s onselect property to send an email using the Outlook Connector. The body will contain the prefilled URL link for the contact.
With(
{
EmailParams: {
To: ThisItem.Email,
Subject: "PowerApps Event Survey",
Body: $"Hello <strong>{ThisItem.'Full Name'}</strong>,<br><br>Please access the form link <a href='{ThisItem.FormURL}'>here</a>."
}
},
Office365Outlook.SendEmailV2(
EmailParams.To,
EmailParams.Subject,
EmailParams.Body
)
)

The contact will then fill out and submit the form.
Build the Power Automate
The Power Automate flow itself is pretty straightforward. It uses the When a new response is submitted automatic trigger to listen for incoming form responses and then retrieves the response details. From there, the contact ID captured in the form is used to look up the corresponding Contact record.

You might notice that I’m using the List rows (Dataverse) action instead of Get a row by ID. That’s intentional. There’s always a chance that the passed-in Contact ID no longer exists (for example, if the contact was deleted) or is malformed. If that happens, Get a row by ID would fail and fail the entire flow run while checking to see if found in a condition eliminates that possibility.

I retrieve the first record returned by the Contact ID (there is only one since the GUID is unique) and update the Event Response table.

Here’s the end-result captured in my Response Events table.

I’ve captured several responses from this user and taken it a step further to show the responses within my Canvas App on a different screen.

Hopefully, what I’ve showcased here helps you expand on these ideas for your own external user data collection challenges!
