Forum Discussion
API to access MS forms
This is my set up (set up from scratch to test it), hopefully it can help narrow down the problem:
- Set up a basic App registration (single tenant, no redirect URI).
- Copy the application (client) ID
- Set up a secret. Copy the secret.
- NO API PERMISSIONS REQUIRED (as of writing this). This is strange, but for some reason, it works (for now)
- log into forms through your browser, then open a new tab and go to the following: https://forms.office.com/formapi/api/userInfo
- Grab the (user) id from that response, and use it in the following: https://forms.office.com/formapi/api/{Tenant_id}/users/{User_id}/forms
- Grab a (form) id from that response and now try the following: https://forms.office.com/formapi/api/{Tenant_id}/users/{User_id}/forms
Testing in postman, authenticate using the following and copy the token:
POST to "https://login.microsoftonline.com/{TenantID}/oauth2/v2.0/token"
Body:
- grant_type = client_credentials
- client_id = {app_id copied}
- client_secret = {app_secret copied}
- scope = https://forms.office.com/.default
- (@mpheasent used this with success as well: api://forms.office.com/c9a559d2-7aab-4f13-a6ed-e7e9c52aec87/.default)
9. Replicate the responses call with postman (note the URL encoding of (''):
GET "https://forms.office.com/formapi/api/{Tenant_id}/users/{user_id}/forms%28%27{Form_id}%27%29/responses"
Headers:
- Authorization = Bearer {token}
Haven't figured out a single call to to get all forms for all users yet either. Hope this helps someone nonetheless.
Thanks for your tips. Getting form data is pretty straightforward if OwnerId field is actually ObjectId of the user. But unfortunately "https://forms.office.com/formapi/api/<tenant_Id>/users/<form_owner_id>/forms" doesn't work if the form_owner_Id is a group ObjectId. I've tried to replace users segment with groups but to no avail
Some forms in my organization are under group ownership and I'm at loss how to get data about them without using delegated access
- OleksiihoSep 02, 2022Copper Contributor
Maybe somebody will find it useful so I'll leave it here.
Unfortunately forms API doesn't work well for S2S solutions, simply because there's no way to get Group forms, and the problem is that sooner or later every user form get transferred to group ownership.
So if you wanna to build something on server side with full support of any forms your best bet is using automation solutions, either it's Azure Logic Apps, or Power Automate, because they have native connectors to forms, and actions which can perform any http request as long as integration account does have O365 license.
Also, there's always a choice to use MSAL and perform authentication using login / password of integration account (with assigned license of course), so you'll be able obtain appropriate user token silently, but I strongly suggest not to look into this avenue
- OleksiihoAug 22, 2022Copper Contributor
When you logged in to the Forms portal, the browser makes different requests depending on form ownership type. Per my understanding "ownerId" field can contain 2 types of owners: individual users (who own / created the form initially), or Office 365 group (when user delegates form access / permissions / ownership to whole bunch of users i.e. group).
So, in browser, if the formOwnerUserId is user's oid, it uses the following URL:
"https://forms.office.com/formapi/api/<tenantId>/users/<formOwnerUserId>/forms"
It's fine and works the same in delegated scenario and S2S
But, if the formOwnerGroupId is office 365 group's oid, it uses another url segment (/groups/ instead of /users/):
"https://forms.office.com/formapi/api/<tenantId>/groups/<formOwnerGroupId>/forms"
And that's where the problem lies with S2S.. Apparently it doesn't recognize /groups/ segment and still requires /users/ one, but when used /users/ with formOwnerGroupId it just throws error because apparently it can't treat groupId as userId, meaning that S2S can't grab any data on form which is under group ownership
You can get data using delegated access though, but still..
- mpheasantAug 22, 2022Copper Contributor
I havent seen one like that so cant say.
You should be able to find the API URL by going to that form in the browser and using "Inspect" like I mention in my comment under note 2/: