Power Pages and Power Automate connect two ways. A flow can trigger on the Dataverse row the form writes, or the page can call a flow directly and use what it returns. Most portal work needs the first and reaches for the second, which costs page code and web roles nobody budgeted for. Both routes need a table permission on the Dataverse table underneath. First builds forget that one until the form throws.
Table of Contents
The two ways Power Pages and Power Automate connect
Route one triggers a flow on the Dataverse row the form writes, so nothing on the page has to call anything. With route two you post to a flow endpoint from the page and wait on the reply. You need that when the customer cannot leave the page until they have the flow’s answer.
Route two brings a set of requirements route one never touches.
| Route one, Dataverse trigger | Route two, page calls the flow | |
|---|---|---|
| Trigger | When a row is added, modified or deleted, with Change type matching the interaction | When Power Pages calls a flow |
| Page code needed | None | JavaScript on the page, with a CSRF-safe post |
| Gets an answer back to the page | No | Yes |
| Flow added to the site and given web roles | No | Yes |
| Re-registered when moved between environments | No | Yes |
| Needs a record id passed to it | No, the trigger already has the row | Whenever it acts on an existing row. Getting it there after a form submit takes a redirect |
One caveat on that table. Microsoft documents the add-to-site step, the web roles and the environment registration only for the Power Pages trigger, and the Dataverse trigger documentation is silent on them. So we treat all three as route two requirements. Microsoft never says they do not apply to route one. It just never raises them there, and reading it that way is our call.
Which route does your process need?

Route one handles anything that leaves a Dataverse row behind, and that is the bulk of portal work. Route two exists so the page can show the visitor what the flow worked out. Two questions tell you which one you are looking at.
- Does the interaction create, change or delete a Dataverse row? If it does not, route two is your only option.
- Does the page have to display something only the flow can work out? If not, take route one.
The first question is the one people skip. A postcode lookup writes no row, so route one cannot see it. Nor can it see someone asking for their statement by email or pushing an existing job across to a CRM on demand. An edit to an existing request is different. The trigger fires on Modified and Deleted the same way it fires on Added.
The second is what most portal work turns on. Intake, approvals, notifications and status updates all sit behind the form, where route one handles them without any page code. Route two is for the narrower case where the page has to show a result only the flow can produce, as in Microsoft’s examples of a weather lookup and a file operation returning a value to the page. A reference number is not that case, since Dataverse will generate one for you with an autonumber column.
The trap is that route two feels like the integration because it is the one with a Power Pages trigger in the name. Reaching for it by default buys you page code and web roles you did not need. The same habit turns up right across process work, which our business process automation guide gets into.
Route one: trigger the flow from the Dataverse row
Point a flow at the table the form writes to and let the row change start it. Use the When a row is added, modified or deleted trigger with Change type matching the interaction and Scope set to Organization, then leave everything after the trigger inside the flow, including the approval, where the page cannot see it.
It costs you two settings on the trigger card and two on the approval action. None of the four sit where you would go looking for them. Scope has to be wide enough to see a row the flow owner does not own. That rules out User scope outright. It rules out the two business unit scopes as well, unless the row’s owner happens to sit in the flow owner’s business unit or a child of it. Set Scope to Organization and the trigger sees every row in the table no matter who owns it, which is why Filter rows is then compulsory. An unfiltered 500-row migration sends 500 approvals. Timeout goes on the approval action itself, with a Configure run after branch catching has timed out as well as has failed.
Modified carries one failure the other change types do not. Microsoft evaluates the trigger on every update, so write status back to the row that started the flow and you have started it again. It will keep going round until Select columns names only the columns the customer edits. That filter applies to updates only. The trigger page calls it the Update condition and the designer calls it Modified. A lookup column named in it never triggers the flow on its own changes, so list the scalar columns and nothing else.
The flow owner carries the permissions. That means a licence covering the premium Dataverse connector, plus user-level create, read, write and delete on the Callback Registration table. When a flow saves cleanly and then never fires, that table is the first place to look. The run history will not help, because there is no run.
A run waiting on an unanswered approval does not wait forever, though Microsoft’s own pages disagree on when it ends. The limits page puts it at the 30-day run duration limit and the approvals known-issues page says a flow waiting beyond 28 days fails. The known-issues page adds that the approval record survives in the Approvals action centre and somebody has to delete it by hand.
Route two: call the flow from the page
Create an instant cloud flow inside a solution with the When Power Pages calls a flow trigger. Add it to the site from the Set up workspace and assign web roles. Your page then posts to the generated URL, and the flow answers with the Return value(s) to Power Pages action.
Microsoft’s cloud flow documentation sets the platform requirements. Start with the site version. You need 9.5.4.xx or later with a starter site package of 9.3.2304.x or higher, and the flow has to be solution-aware before it can be attached. Microsoft requires a Power Automate licence and recommends a Process licence in production. That licence lets the flow use premium and custom connectors regardless of what the person triggering it holds, and you can only assign that licence to a flow already sitting in a solution, which is the second reason to build it there. Trigger inputs can only be Text, Boolean, File or Number. A flow with secure inputs cannot take a parameter.
Before anyone writes a line of JavaScript, two things about route two will shape what you build.
The call is synchronous and capped at two minutes. Microsoft’s inbound request limit is 120 seconds, and a flow with a response action answers inside it. Anything slower means the flow has to answer the page early and let the customer find the outcome another way. A human approval is the obvious case. Actions placed after the response keep running, so the work is not lost, but the page cannot wait for it.
A basic form gives you no success event to hook into. Microsoft documents entityFormClientValidate, which fires before the row is saved, not after. Getting the new record’s id to the page means setting On Success to Redirect, ticking Append Record ID To Query String and calling the flow from the destination page. Most first attempts stall on that redirect, usually after an afternoon spent looking at the flow instead.
Past those two, the page-side plumbing is its own job. You post a stringified eventData wrapper rather than a flat body, and the parameter names inside that wrapper have to be spelled the way the trigger spells them. On the way back you JSON.parse the response and read output names lower-cased with underscores. Every call has to carry a cross-site request forgery token. Microsoft’s own page shows the flat shape in its raw HTTP example and the wrapped shape in its JavaScript sample. Follow the JavaScript one, since that is what runs in a browser.
What a Dataverse-backed form needs: table permissions
No form reaches Dataverse until a table permission exists, and a web role alone does not grant one. You create a table permission and associate it with a web role. Skip it and the form throws before Power Automate is ever involved, which sends people off to debug a flow that never ran.
Microsoft’s table permissions documentation is explicit that access is restricted automatically when you use forms, lists, Liquid or the Web API. For a request form, the privilege that inserts a row is Create, with Write if the form stays editable afterwards. Append and Append To cover relating one record to another, such as attaching a note to a request. People reach for them when a save fails, which never helps because saving is Create.
The access type controls who can read the row back. The design studio offers Global, Contact, Account and Self. A preview Custom type needs the enhanced authorisation model, and a Parent type exists only in the Portal Management app.
- Authenticated forms should use Contact access, which requires a relationship between Contact and your request table. Set Associate Current Portal User under the form’s Additional Settings and name the Portal User Lookup Column, or every row is created with that lookup empty and the customer’s list comes back blank.
- Anonymous forms cannot use Contact, Account or Self. All three resolve against a signed-in contact. Global Create is the usual answer. Global Read is not, since it makes every submitted request readable by any visitor. Email the outcome instead, or take a reference number on the page and call a route two flow that returns just that row’s status. That keeps the data behind the flow, but it leaves you with an endpoint anyone can reach. Read the security points below before you build it that way.
A worked example: portal request to approval
This is route one from end to end. A customer submits a request, Dataverse takes the row and a flow does everything after that. Afterwards the portal only has to show the customer where things stand, which a list view does on its own.
We built the portal side of this for an air conditioning manufacturer in New South Wales. The portal showed customers the status of current jobs and the maintenance projects coming up. Behind it, a flow handled approval, wrote status back to Dataverse, sent notifications and pushed the result into the client’s CRM.
The project pipeline was the part we underestimated. A job status looks like a single field until you try to model it. We did not get it right in one pass. It took several conversations about how work actually moves through their business, and a flow revision after most of them.
Model the states you can name and budget for the ones that turn up later. Do not leave Status as free text and find out six months on that nobody can report on it.
Security considerations for Power Pages workflows
Page permissions decide who can load the page. Table permissions decide who can read and write records. Both hang off web roles, and so does access to a route two flow. That is three things reading off the same roles, and on most portals one of them is still on its default.
Points to settle before go-live:
- Site visibility is private by default, so an anonymous form does nothing until the site is made public. Check that before concluding your permissions are wrong.
- A route two flow on the Anonymous Users role is an unauthenticated endpoint. Anything holding a site session and token can reach it, not just your form. On a public site that means anyone. Whatever reaches it can create rows and send approval email to your staff. Form CAPTCHA does not help because the endpoint does not require the form. Validate inside the flow and keep route two off a public page unless you have a reason to put it there.
- Render returned values as text, not HTML. Microsoft’s sample writes flow output into
innerHTML. If that output echoes anything a visitor typed, you have a scripting hole on a public page. That is a reflected hole when the visitor sees their own input come back and a stored one when the flow returns text somebody else saved. - Check whose connection the flow runs on. It uses that account’s permissions, not the customer’s, so a flow authored on an administrator’s connection will do administrator things on behalf of an anonymous visitor.
On any client portal build, expect the permissions model to take longer than the pages sitting on top of it and to need revisiting after the first round of user testing.
Troubleshooting the Power Pages to Power Automate handoff
Ask which route you are on before anything else. On route one the failure happens out of sight of the page, and a trigger that never fired leaves no run to read. On route two it surfaces at the page, usually with a message naming the last thing to go wrong.
| Symptom | Likely cause | Fix |
|---|---|---|
| The form errors on submit before any flow runs | No table permission, or it is not associated with the submitter’s web role | Add a permission carrying the Create privilege and associate it with the web role |
| A customer’s list of their own requests is empty | The Contact lookup is not populated on insert | Switch on Associate Current Portal User for that form, then point Portal User Lookup Column at the Contact field |
| Route one trigger never fired | Change type does not match the interaction, a lookup column sits in Select columns or the Filter rows expression never evaluates true | Match Change type to the interaction, keep lookups out of Select columns and test the Filter rows expression against a real row |
| Route one flow owner cannot see the row | The trigger Scope is too narrow to reach the row’s owner, or the flow owner lacks the Callback Registration permissions | Set Scope to Organization, then check the flow owner’s Callback Registration access |
| Route two flow does not appear when adding it to the site | The flow is not solution-aware or sits in a different environment | Open Solutions, choose Add existing and bring the flow in where it sits. Microsoft notes some non-solution flows cannot be added |
| A visitor gets access denied when the page calls the flow | Web roles were not assigned to the flow, or the visitor does not hold one | Assign the roles when adding the flow to the site, then test signed in as a user who actually holds that role |
| Route two flow runs with empty inputs | The payload was posted flat, or a parameter name inside it does not match the trigger | Wrap the inputs in a stringified eventData field and match the names inside it to the trigger exactly |
| The page renders undefined where a value should be | The response was not parsed, or the output name was not transformed | JSON.parse it, then read the lower-cased underscore form of the name |
| Route two works in development, forbidden error in production | The flow was not registered in the target environment after the site components moved | Register it from the Cloud flows list in that environment’s Set up workspace |
| A request stalls at Pending approval and nobody is told | The approval has no timeout, or the run-after branch only catches failure | Set an explicit Timeout on the approval action and tick has timed out as well as has failed |
| An imported flow cannot reach Dataverse or Approvals | Connection references were not re-established on import | Set the connections on the imported solution. Often mistaken for the registration error above |
Frequently asked questions
How do you trigger a Power Automate flow from a Power Pages form?
Two ways. Point a flow at the Dataverse table the form writes to, using the When a row is added, modified or deleted trigger with Change type matching the interaction, which needs no page code at all. Or use the When Power Pages calls a flow trigger and post to it from JavaScript on the page, which is the one to choose when the visitor needs a result back on screen.
Which trigger should I use for a portal approval workflow?
The Dataverse one. An approval runs behind the form rather than in front of it, so nothing needs to come back to the page while the customer waits. Using the Power Pages trigger here adds page JavaScript, web roles on the flow, an environment registration step and the redirect dance needed to hand the new record’s id across, for no benefit the customer sees.
What happens if nobody responds to a portal approval?
The flow waits, and the platform eventually ends it rather than your process doing so. Microsoft’s limits page puts the ceiling at 30 days. Its approvals known-issues page gives a different number, 28 days, after which the run fails. Set a Timeout on the approval action well inside both and branch on has timed out as well as has failed.
Why does my flow run with empty inputs when the page calls it?
Usually because the payload was posted flat. Wrap the trigger inputs in a single stringified eventData field, as Microsoft’s JavaScript sample does, and make the parameter names inside it match the trigger exactly. A mismatched parameter name fails the same way for that one input, which is why a flow can run with some values present and others empty.
Do you need a Power Automate licence for Power Pages cloud flows?
Yes. Microsoft states a Power Automate licence is required for the cloud flow integration and recommends a Process licence in production. A Process licence assigned to a flow permits premium and custom connectors regardless of the licence held by whoever triggered it, and the licence can only be assigned to a flow that already lives in a solution.
How does a portal customer find out the outcome of their request?
On an authenticated portal, a Contact-scoped table permission lets them read their own rows. It needs a Contact relationship on the table and Associate Current Portal User switched on for the form. Neither works anonymously, and the Global Read permission that would substitute puts every request in front of every visitor. Email it to them instead, or wire a reference number box to a route two flow that returns that one row and nothing else.
Where to go next
Neither route models the process for you. Every process has its own states and its own exceptions, and working out which ones the business actually uses is the slow part. That is where the New South Wales build spent its time, and it is the work that outlasts whichever trigger you picked.
The Australian Industry Group surveyed leaders of 225 private sector businesses across nine industrial sectors in late 2025 and found that improving operational processes was the most commonly nominated cost management strategy, at 36%.
A canvas app is usually the better front end when the process is internal only or when it needs guided screens or fast data entry across many records. Our guide to choosing between Power Pages and Power Apps works through that decision, and how a Power Automate flow works covers triggers and actions on their own.
OfficePro Consulting builds portals like this one for Australian organisations, and on most of them the first fortnight goes on the process and none of it on the form. If a request lands in an inbox and somebody re-keys it by hand, book a free initial conversation. Our business automation services and Power Automate pages cover how we scope and price it.

