Limit number of Responses in Microsoft Form

Within Microsoft Forms it is possible to close the form for new responses. In this article I will show you how to update this setting based on the number of responses via a Power Automate flow.

Inspiration

This question from Armin2:

Is it also possible that the link expires after the first use and can only be used once, so to speak?

Power Users Community thread: create a Link to a form which expires after the first use.

limitnumberofresponsesforms

Options for Responses

In the interface you have a couple of options for responses. You can set the End date, which can lock the form down after a certain date. This is also the option which I suggested to Armin2 in the Power Users Community thread.

But in this blog I also looked into the Accept responses option. The benefit of that option is that it also includes a Message to recipients field which you can use to present a message to the end user why it has been closed down, which is probably a bit more user friendly.

optionsforresponses

Forms API

Like demonstrated in the Get Microsoft Forms responses submitted today blog you can interact with your Form via the Forms API and a Send an HTTP request to SharePoint action in a Power Automate cloud flow.

In this example I am going to use the API to retrieve the responses of the form and check the total number of responses in a condition. You can do this by using a length function to check the number of items within the returned value property.

In this example want the form to be closed down after 5 responses.

I am also going to use a PATCH request to set the FormClosed boolean property to true and provide a text in the FormClosedMessage property.

Flow Setup

For this sample I am using personal Microsoft Form.

limitnumberofresponsesforms_flow

1. Add a When a new response is submitted action.

whenanewresponseissubmitted

a. Select your form from the dropdown

2. Add a Get response details action.

getresponsedetails

a. Select your form from the dropdown
b. Provide a Response Id, use the Response Id field from the Dynamic Content.

3. Add a Get user profile (V2) action.

getuserprofile

a. Provide a UPN, in this case the UPN of the user who created the Microsoft Form.

4. Add a Send an HTTP request to SharePoint action.

The URI uses the tenant id (which in my case is a parameter), the id of the user who created the form and the form id (which is retrieved from the dropdown in the first action).The tenant id can be found in Entra Id or via the following website, just enter your domain: https://www.whatismytenantid.com

sendanhttprequesttosharepoint

a. Use the https://forms.office.com as the SiteAddress.
b. Use the GET method
c. Use the URI from the code snippet below

d. Use the Headers from the code snippet below

5. Add a Condition action.

condition_length

a. Use the expression below for the condition

6. Add a second Send an HTTP request to SharePoint action.

The URI uses the tenant id (which in my case is a parameter), the id of the user who created the form and the form id (which is retrieved from the dropdown in the first action). The tenant id can be found in Entra Id or via the following website, just enter your domain: https://www.whatismytenantid.com

patch_formclosed

a. Use the https://forms.office.com as the SiteAddress.
b. Use the PATCH method
c. Use the URI from the code snippet below

d. Use the Headers from the code snippet below

e. Use the Body from the code snippet below

That should be it for the setup.

Happy testing!

You may also like...

28 Responses

  1. Toby Teng says:

    Hi Dennis, Thank you so much for this. May I know how can I get the tenant id in step four please?

  2. Dennis says:

    Hi Toby,

    You can for example find in Entra Id. But there is also a website for that:
    https://www.whatismytenantid.com/

  3. mohamed says:

    Hi Dennis.
    I get an error on the condition level
    ‘length(outputs(‘Send_an_HTTP_request_to_SharePoint’)?[‘body’][‘value’])’ cannot be evaluated because property ‘value’ doesn’t exist,

  4. Dennis says:

    Hi Mohamed,

    What outputs is the Send an HTTP request returning. Are you seeing by any chance a ‘d’ property?

    Did you use the same verbose Headers in the Send an HTTP request.
    {
    "Accept": "application/json;odata=verbose",
    "Content-Type": "application/json;odata=verbose"
    }

  5. Mohamed says:

    Thanks for your help! Your workaround did the trick perfectly once I adjusted the verbosity settings. I made a few tweaks to fit my needs better, like changing the condition to a greater-than comparison and adding an automatic email to the Responder with the form’s context.

    Just a heads up, though—the form still records responses and confirms to users, which might be misleading. So, I added the email notification for clarity.

    Thanks again for your support

  6. Mohamed says:

    I wonder if there is a way to change the expiration date on the form once the desired number of responses reaches.

  7. Dennis says:

    This setup should close the form and you should not be able to respond anymore, that is what is done in step 6 of the flow with the PATCH request. So, this does not work for you?

  8. Hannah says:

    Hiya, does this only work for a single user using the form? or will this work for multiple submitters?

  9. Dennis says:

    Hi Hannah,

    This applies to all submitters trying to submit a new response after a certain amount of total responses. In this example it closes after a total of 5 responses.

  10. Hannah says:

    Hi Dennis,
    I am getting the error below when testing at the first get https response: Unable to process template language expressions in action ‘Send_an_HTTP_request_to_SharePoint’ inputs at line ‘0’ and column ‘0’: ‘The workflow parameter ‘TenantId (exp_TenantId)’ is not found.’.

    Any suggestions?

  11. Dennis says:

    Hi Hannah,

    That is a environment variable from my personal development environment, which won’t exist in your setup. You need to replace that variable by your own tenant id.

    A tenant id can for example be found via: https://www.whatismytenantid.com/

  12. Irek says:

    Hi Dennis,
    could you provide an example of what the code snippet in step 5 and 6 should look like when replacing the TenantID with an actual one. I’m getting an error saying the expression is invalid.
    Many Thanks.

  13. Irek says:

    Hi Dennis,
    could you provide an example of what the code snippet in step 4 and 6 should look like when replacing the TenantID with an actual one. I’m getting an error saying the expression is invalid.
    Many Thanks.

  14. Dennis says:

    Hi Irek,

    That would be something like:

    Your specific tenant id can be found via the following website, just enter your domain: https://www.whatismytenantid.com/

  15. Irek says:

    Fantastic, this seems to work now, thank you for a quick reply, much appreciated,

  16. Dennis says:

    Hi Irek,

    Great to hear it works, happy to help out.

  17. Moe says:

    Hello Dennis

    I tried your way, the flow works perfectly until I reach the limit 5 when the condition is met, I get MethodNotAllowed

  18. Dennis says:

    Hi Moe,

    I assume you used the PATCH method, correct? Did you double check you used the right URI for your form. This sample is for a personal form, for a groups form that setup would be slightly different:
    /formapi/api/{tenantid}/groups/{groupid}/forms('{formid}')/responses

  19. Moe says:

    Hi Dennis
    That’s correct I used the same methods you did use, and yes I used the right URI. The form that I am testing on is also a personal form created under my name and not from a channel or group, but the account that I am using is my organization’s account. No idea if that’s what you are pointing to.
    that’s what I used for my URI:
    Note here, the tenant ID used down is a random tenant ID
    formapi/api/3a2f211d-5333-723a-a8ae-3a70add3f3db/users/@{outputs(‘Get_user_profile_(V2)’)?[‘body/id’]}/forms(‘@{trigger()[‘Inputs’][‘parameters’][‘form_id’]}’)/responses
    what shall I change in this case?
    I see that you used different URI in your reply:
    /formapi/api/{tenantid}/groups/{groupid}/forms(‘{formid}’)/responses
    what’s are the variables in this case? other than the tenantid
    Thanks!

  20. Dennis says:

    Hi Moe,

    The format I shared in my last reply was for a Groups form. In your case it is a personal form, so you can stick with the original format.

    I am retrieving my own user Id via a Get user profile (v2) action. You could use the same approach or even use a Get my profile action instead.

    The tenant id needs to be the id of your tenant. If you don’t know your tenant id you can find this in Entra Id or simply enter your tenant domain in this website:
    https://www.whatismytenantid.com/

  21. Ghislou says:

    Dear Dennis,

    Everything has been set up like what you showed here. Got the tenant ID and the flow is collecting properly data. However when i’m testing it on my computer, even after 5 replies i’m still able to use the form. Did i miss a parameters somewhere?

    Thank you

  22. Sebs2606 says:

    Hello, Thank you for this guide.
    However, I do have an error code for the closing of the form.
    “ActionBranchingConditionNotSatisfied. The execution of template action ‘Send_an_HTTP_request_to_SharePoint_-_FormsClosed’ skipped: the branching condition for this action is not satisfied.”

    Is there a way to sole this easily? everything goes fine until the last step.

    Form is setup as “accept responses” and “hide submit another response”. Nothing else added.

    I have no clue why i have this message but everything is same as your guide. (excpet tenant id who is the one of our domain).

    Can yuo help me sort this out? Thank you.

    Kind regards,

    Sebs

  23. Dennis says:

    Hi Sebs,

    It looks like it is skipping the update, which means it hasn’t got 5 responses in total/it reached the 5 limit yet. Did you submit 5 responses to the form?

    In the first 4 responses it would skip the PATCH action in the If Yes and would go the the If No branch. Only on the 5th response the expression result would be true and it would update the settings of the form.

  24. Dennis says:

    Hi Ghislou,

    Just to double check, are you using a personal form or a group hosted form?

    What did you see in the outputs of the PATCH action?

  25. Philipp says:

    This worked great for me until around the 18th of September of this year. Suddenly old and new flows are all failing in the third module where the GET response gets a error 400. Has anyone else experienced the same?

  26. John Mason says:

    Hi Dennis,
    This looks like it should do exactly what I need thanks I am however having a little issue getting it to work.

    When I go to save the flow I get the following error:
    Flow save failed with code ‘InvalidTemplate’ and message ‘The template validation failed: ‘The action(s) ‘Send_an_HTTP_request_to_SharePoint_-_Responses’ referenced by ‘inputs’ in action ‘Condition’ are not defined in the template.’.’.

    I feel like there is something obvious I have missed.

    Any help really appreceated.

  27. Dennis says:

    Hi Philipp,

    You are not the only one who is experiencing this issue. There is an ongoing issue since the 18th of September which prevents us from interacting with the MS Forms API via the Send an HTTP request to SharePoint action. For more details have a look at this Power Platform community thread:
    https://community.powerplatform.com/forums/thread/details/?threadid=9ca4e187-9e76-ef11-a671-000d3a9e52a3

    In the thread somebody suggested that the Entra ID HTTP action could be used instead as a workaround. I haven’t tried that myself though.

  28. Dennis says:

    Hi John,

    Make sure you use the name of the Send an HTTP request to SharePoint action is the same as in the expression in the Condition action.

    In my example the action name was ‘Send an HTTP request to SharePoint – Responses’. If your action name is ‘Send an HTTP request to SharePoint Renamed Action’ the expression in the condition action should be:
    length(outputs('Send_an_HTTP_request_to_SharePoint_Remaned_Action')?['body']['value'])

Leave a Reply

Your email address will not be published. Required fields are marked *

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