← All work

Copilot Studio · Power Automate · Dataverse

Time Off Intake Automation

Requests arrive by email and Teams message, and nobody can say who approved what.


The problem

In an organisation of 80–150 people without a dedicated HR system, time off requests arrive by email, Teams message, and hallway conversation. Requests get lost, because an inbox is not a queue. Nobody can answer "how many days have I got left" without manually reconstructing it. And there is no record of who approved what, leaving nothing to refer to during a dispute.

Buying an HR platform is the usual instinct and usually the wrong answer at this size: a per-seat subscription and a migration project to fix one workflow.

Why conversational intake fits

Three properties make an agent genuinely better than a form here. The request is unstructured at the point it occurs. Someone thinks "I need Thursday and Friday off" while doing something else. The data needed is small and well-typed: four fields, all parseable. And the follow-through is asynchronous, which is exactly where email-based processes fail.

Where an agent would be the wrong answer: anything requiring the requester to see and compare data before deciding, such as a leave balance view, a team calendar, or a departmental conflict check. Those are Power Apps problems.

Architecture

Time Off Intake Automation architectureAn employee messages a Copilot Studio agent, which collects four typed values and calls a Power Automate flow. The flow writes a row to Dataverse and returns a reference number to the employee within the hundred second timeout. Below that boundary, the flow starts an approval that may run for hours, then updates the Dataverse row with the outcome.EmployeeTeams or web chatCopilot Studio agentTopic: submit time off requestWork email — email entityStart date — date and time entityDays needed — number entityReason — free text4 variablesPower Automate agent flowAdd row to DataverseStatus set to pendingReturn values to agentRequest ID and confirmationEverything above completes inside the 100 second timeoutStart and wait for approvalRuns for hours or daysUpdate row on outcomeApproved or declined, with commentsDataverseTime off requests tableApproverTeams or email cardReference numberreturned in secondsSolution scoped for portability. Approver resolved from the Entra ID manager attribute.
Approval runs after the return step, outside the 100 second timeout

The agent collects four values using typed entities, so "next Thursday" resolves to a date and "three" to a number. It calls a Power Automate agent flow, which writes to Dataverse and returns a reference number.

The constraint that drives the design

Agent flows time out at 100 seconds. A human approval takes hours.

Put the approval in the middle of the flow and the agent hangs while the approver is at lunch. The resolution is ordering: write the row, return control to the agent, then start the approval. Everything above the return step is synchronous. Everything below continues after the requester has already been thanked.

Why Dataverse

A message posted into a channel is not a record: it can't be queried, has no status, and is gone in a week. A typed row with a lifecycle means the same data later supports a Power App for HR and a Power BI view of usage patterns, without rebuilding the intake.

Delivery considerations

Approver resolution comes from the requester's Entra ID manager attribute, so routing survives reorganisations without editing a flow.

Permissions require the agent to authenticate with Microsoft so Dataverse row-level security applies. An employee sees their own requests; a manager sees their team's.

Policy validation at intake flags the 14 or 30 day notice requirement before submission rather than after rejection. This removes a whole category of back-and-forth.

Failure behaviour matters more than it looks. If Dataverse is unavailable the agent says so plainly. Users forgive an error message; they don't forgive a request that vanished.