Turn Facility Emails into Service Requests with Power Automate and an AI Prompt (Part A)
Every facilities team has a shared inbox like facilities@ or service@. Tenants and building staff write to it in plain language: "the tap on 2 is leaking again", "it smells like something's burning by the dock", "AC is dead in our waiting room". Someone then reads every email, works out which building it's about, decides how urgent it is and types it into a tracker.
That copying step is slow, easy to get wrong, and it's the first thing to slip on a busy day. In this guide we'll replace it with a Power Automate flow and a single AI prompt that reads each email, pulls out the fields you need and writes a ticket to a SharePoint list, usually within a minute of the email arriving.
This is Part A of a three-part series:
Part A (this post): Power Automate and an AI prompt that returns structured JSON.
Part B: the same job as an autonomous Copilot Studio agent that can ask for missing details and spot duplicates.
Part C: Microsoft 365 Copilot answering questions over the request list.
Here's where we're going. Four real-world style emails in, four tickets out, with priority, category and location filled in by the AI:

What you'll need
Microsoft 365 with Exchange Online, SharePoint and Power Automate.
A shared mailbox for requests. We used one called Facilities Desk.
Access to prompts (Power Apps > AI hub > Prompts, or Copilot Studio). Prompts run on Copilot Credits, so your environment needs prepaid capacity or a pay-as-you-go billing plan. More on cost at the end.
The Sites and Buildings lists from our Site Inspection app, or any list of your properties.
Step 1: Create the shared mailbox
In the Microsoft 365 admin center, go to Teams & groups > Shared mailboxes > Add a shared mailbox. Give it a display name and an address, then add yourself (and the facilities team) as members. Shared mailboxes don't need a licence.
Step 2: Build the Service Requests list
In SharePoint, create a list called Service Requests. Rename the Title column to Summary and add these columns:
TicketNo: single line of text, filled in by the flow.
SiteID, SiteName, Building, Floor and Location: where the problem is.
Category: a choice of Plumbing, HVAC, Electrical, Cleaning, Security, Elevator, Doors & Access or Other.
Priority: a choice of Emergency, Urgent or Routine.
PriorityReason: one sentence from the AI explaining the priority.
RequesterName, RequesterEmail and ReceivedOn: who sent it and when.
Status: a choice of New, Needs review, Assigned, In progress or Resolved.
Confidence: a number from 0 to 1.
MissingInfo, EmailSubject, EmailBody and MessageId: for review and traceability.
Add some simple column formatting to Priority and Status so the urgent items stand out. A coloured pill per value is enough.
Step 3: Write the prompt
This is where the AI does the work. In Power Apps, open AI hub > Prompts > Build your own prompt and name it Extract facility service request.
The prompt has four inputs. Type / in the instructions to add each one as a Text input:
Sender: the email's From address.
Subject: the email subject.
Body: the email body.
Sites: a short directory of your sites and buildings, built by the flow from SharePoint.
Then write the rules in plain English. The rules that made the biggest difference in our testing were:
Match the site from a known list, and use siteId 0 if you can't tell. Never guess.
Spell out what Emergency, Urgent and Routine mean, so priority is consistent.
Ask for a missingInfo field listing what a technician would still need.
Ask for a confidence score, so low-confidence tickets can be flagged for a person.
Never invent details that are not in the email.
Set Output to JSON and give it an example of the shape you want. That way the flow gets named fields instead of free text:
{"summary":"","siteId":0,"siteName":"","building":"","floor":"","location":"","category":"","priority":"","priorityReason":"","requesterName":"","missingInfo":"","confidence":0}Fill in sample data for each input and select Test. With a leaking-tap email, the prompt matched the right site, building and floor, picked Plumbing and Urgent, and explained why:

Step 4: Create the flow
Create an automated cloud flow called Facilities Inbox to Service Requests with the trigger Office 365 Outlook > When a new email arrives in a shared mailbox (V2). Set the mailbox address and the Inbox folder.
The whole flow is short:

Step 5: Give the AI a site directory
The prompt can only match a site it knows about. Add SharePoint > Get items for your Sites list (filter on Active eq 1) and another for Buildings. Then add two Select actions in text mode to turn each row into one line:
concat(item()?['ID'],' | ',item()?['Title'],' | ',item()?['Address'],', ',item()?['City'])
concat(item()?['SiteID'],' | ',item()?['Title'])A Compose action called Site directory joins them into one block of text:
concat(join(body('Site_lines'),decodeUriComponent('%0A')),decodeUriComponent('%0A'),decodeUriComponent('%0A'),'Buildings (site ID | building):',decodeUriComponent('%0A'),join(body('Building_lines'),decodeUriComponent('%0A')))decodeUriComponent('%0A') is simply a line break. Because the directory comes from SharePoint on every run, a new site becomes recognisable as soon as it's added to the list. No prompt changes needed.
Step 6: Run the prompt
Add AI Builder > Run a prompt, choose Extract facility service request and map the inputs: From to Sender, Subject to Subject, Body to Body, and the Site directory output to Sites.

The JSON comes back under structuredOutput, so every field is available by name. For example, the priority is:
body('Extract_request_details')?['responsev2']?['predictionOutput']?['structuredOutput']?['priority']Step 7: Log the ticket
Add SharePoint > Create item on the Service Requests list and map each field from structuredOutput. Two small touches make the list much more useful. (In the expressions below, structuredOutput is shorthand for the full path shown in Step 6.)
First, set Status to Needs review when the AI isn't sure, when it couldn't find the site, or when details are missing:
if(or(less(float(structuredOutput?['confidence']),0.7),equals(int(structuredOutput?['siteId']),0),not(empty(structuredOutput?['missingInfo']))),'Needs review','New')Second, add SharePoint > Update item straight after it to give the request a friendly ticket number based on its ID:
concat('FR-',string(add(1000,outputs('Log_service_request')?['body/ID'])))Step 8: Reply to the requester
Add Office 365 Outlook > Send an email from a shared mailbox (V2) so the reply comes from the facilities address, not from a person. Put the ticket number in the subject and summarise what was logged. If missingInfo isn't empty, add a highlighted line asking for those details:
if(empty(structuredOutput?['missingInfo']),'',concat('<p>To send the right technician, please reply with the missing details: <b>',structuredOutput?['missingInfo'],'</b>.</p>'))The requester gets a ticket number in seconds, and the facilities team gets the details they need without a back-and-forth:

Step 9: Escalate emergencies
Finish with a Condition that checks whether priority equals Emergency. In the True branch, send a high-importance email (or a Teams message) to the facilities manager with the summary, location and the AI's reason.
Step 10: Test it
We sent four emails to the shared mailbox, written the way people really write:
"The tap in the men's washroom on level 2 of Tower A at Harbourfront is running non-stop..." became FR-1001: Plumbing, Urgent, Harbourfront Office Tower, Tower A, floor 2.
"There is a strong burning smell coming from the electrical room beside the loading dock at the Northgate warehouse..." became FR-1002: Electrical, Emergency, flagged for review because no floor was given, and escalated to the manager.
"Someone knocked over the coffee urn in the level 2 kitchenette in Tower A..." became FR-1003: Cleaning, Routine.
"The air conditioning in our waiting room isn't working, it's about 28 degrees..." became FR-1004: HVAC, Routine, Needs review. The email didn't name a site, so the AI left it blank instead of guessing, and the reply asked for the site, building and floor.
That last one is the behaviour you want. An AI that admits it doesn't know is far more useful than one that confidently files the ticket under the wrong building.
The inbox, before and after
Before: someone opens an email titled "AC not working", reads it twice, scrolls the site list, guesses it's probably Lakeview, types it into a spreadsheet, forgets to reply, and gets a follow-up email an hour later asking whether anyone saw it.
After: the ticket exists before that person has finished their coffee, the requester already knows their ticket number, and the only emails that need a human are the ones marked Needs review.
What it costs
Each email runs the prompt once. In our tests that was about 0.3 Copilot Credits per email, shown right in the prompt builder after each test. If your tenant has no prepaid Copilot Credits, set up a pay-as-you-go billing plan in the Power Platform admin center (Licensing > Billing plans), link it to an Azure subscription, and limit it to the Copilot Studio meter and the one environment you need. Add a budget alert in Azure Cost Management so there are no surprises.
Ideas to take it further
Read attachments: pass photos of the problem to an Image or document input, so the AI can describe what it sees.
Clean up the body first: run the HTML body through Html to text before the prompt to save tokens on long email threads.
Route by category: look up the right technician or vendor for each category and site, and assign the ticket automatically.
Handle replies: when a requester answers the missing-details question, match the ticket number in the subject and update the existing ticket instead of creating a new one. That's exactly what we'll hand to a Copilot Studio agent in Part B.
Link to inspections: show open service requests next to each site's inspections in the Site Inspection app.
Why this matters
Facility requests already arrive with everything you need. It's just buried in sentences. A prompt that turns those sentences into fields is the simplest, most practical way to put AI to work: bring the data from your inbox and your property lists into one place, put AI in front of it, and let your team spend their time fixing things instead of retyping them.
Need help?
Smart Solutions builds Power Automate, Power Apps and Copilot solutions for Canadian property and facilities teams, from shared-mailbox automations like this one to full service desks. Contact us to talk about what you'd like to automate. Next up in Part B: the same workflow as a Copilot Studio agent.




Comments