In this post, we'll build an agentic Logic App that decides whether
to approve, escalate, or deny a refund. The Agent applies policy,
pauses for human approval when needed, and emails the customer
with the final decision.
Why this pattern?
Most refund flows are a mix of clear rules (auto-approve low amounts
for valid reasons) and edge cases (needs a human). Logic Apps now
support an Agent action (Azure OpenAI) that can reason, call tools,
and control the flow --- perfect for policy + people.
What we're building (at a glance)
HTTP POST (refund request JSON)
└─ Agent "RefundAgent" (Azure OpenAI gpt-4.1-mini)
├─ Tool: Send_Mail_For_Action (Outlook/Webhook) -> pause & wait for approver
├─ Tool: Send_Final_Status_Email (Outlook) -> notify customer
└─ Tool: EndWorkflow (Terminate) -> clean run completion
└─ Response 200 (optional output)
🧩 Decision Policy
Auto-approve if:
- Amount ≤ 200
- Reason contains damaged, defective, or never arrived
Escalate if:
- Amount > 200
- Reason is unclear or outside policy
Deny if:
- Reason violates policy (e.g., buyer’s remorse outside window)
The incoming request (HTTP trigger)
The Logic App expects a JSON payload like:
{
"requestId": "REQ-2025-0918-001",
"customerEmail": "[email protected]",
"orderId": "ORD-992311",
"reason": "Item arrived damaged. Screen was cracked.",
"amount": 149.99
}
Here's a sample payloads ready for testing.
How the Agent thinks
- System message (policy + format): tells the agent to produce a
deterministic JSON decision and guide the flow. - User message: injects the raw trigger body (
@{triggerBody()})
so the Agent sees requestId, email, reason, amount.
The Agent then chooses tools: - Call Send_Email_For_Action only when
a human decision is required. - Otherwise, jump to
Send_Final_Status_Email with a clear, customer-friendly message. -
End with EndWorkflow once the goal is reached.
Human-in-the-Loop (how the pause works)
Your Send_Email_For_Action tool uses: - Outlook "Mail with Options": sends an actionable email (e.g., Approve / Deny). - The workflow waits until the
approver clicks an option;tool resumes with the approver's choice.
The JSON (your workflow)
Trigger (HTTP POST)
- Type: Request (kind: Http)
- Schema: requestId, customerEmail, orderId, reason, amount
Agent action: RefundAgent
- Model: Azure OpenAI gpt-4.1-mini
- System: policy + human-loop instructions
- User: includes the trigger body
- Channels: Allow both input and output channels
🔄 Human-in-the-Loop Requires Real-Time Channels
To make the human approval loop (HITL) work correctly, you need to enable the following option in the Channels tab of your Agent action:
✅ Allow both input and output channels
- This keeps the workflow active while the Agent is waiting on a human decision.
- The approver’s response (Approve / Deny) is posted back to the callback URL, and because both channels are open, the Agent can resume in real time without restarting the workflow.
- Without this option enabled, the workflow would end after the first response, and you couldn’t support HITL interactions.
Tool 1: Send_Email_For_Action
- Purpose: Pause for human approval when the Agent isn't confident
- Pieces:
- Send_email_for_Approval_Or_Denial: Outlook Mail with Options
subscription with:
- To: approver (your demo address)
- Subject:
@{agentParameters('Subject')} #Your input is required#
- Body:
@agentParameters('Body')
- Options:
@agentParameters('User Options')(e.g., "Approve,
Deny")
- Send_email_for_Approval_Or_Denial: Outlook Mail with Options
Tool 2: Send_Final_Status_Email
- Purpose: Notify the customer of the final decision
- Inputs:
- Subject:
@agentParameters('Subject')
- Body :
<p class="editor-paragraph">@{agentParameters('Body')}</p>
- To : the customer (your JSON uses a fixed list; parameterize to
customerEmailfor production)
- Subject:
Tool 3: EndWorkflow
- Purpose: cleanly terminate with Succeeded once done
📊 Run History
One of the most useful ways to validate and debug your Logic App is by looking at the Run History. Each execution shows:
Workflow steps on the left: trigger, RefundAgent, and tools (e.g., Send Email for Action, Send Final Status Email).
Agent log on the right: detailed reasoning steps, the request payload, and the deterministic JSON decision generated by the Agent.
Status indicators ✅ or ❌ that help you quickly spot whether a step succeeded or failed.
In the RefundAgent example:
- For a high-value refund ($275.50), the Agent matched a valid reason (“defective”) but since the amount exceeded $200, it escalated to a human approver. The run shows the “Send Email for Approval or Denial” step being called.
- For a lower-value refund ($145.00), the Agent saw that the reason (“item damaged”) was valid and the amount was below the threshold, so it auto-approved the refund and sent the final status email directly to the customer.
📸 Screenshot: Run History — left side shows the Logic App workflow steps, right side shows the Agent log with reasoning and decision.
This gives full transparency into how the decision was made and which path the workflow followed — critical for auditability in HITL (Human-in-the-Loop) scenarios.
Copy-paste snippets (helpful bits)
Sample system message (condensed)
You are an operations agent that decides whether to approve a refund based on policy, or requests a human decision when uncertain. Produce a deterministic JSON decision and notify the customer.
Auto-approve if amount <= 200 and reason includes one of {damaged, defective, never arrived}.
Escalate if amount > 200 or reason unclear/outside policy.
Deny if reason violates policy and no human approval required.
If escalating, prepare an approver email: subject, body (HTML), and user options "Approve, Deny".
If finalizing, prepare a customer email: subject, body (HTML).
Sample customer approval email body (Agent output)
Wrap-up
You now have a deterministic, auditable refund flow that mixes
policy automation with human judgement --- all inside Logic
Apps. The same pattern works for credit notes, discount
approvals, RMA decisions, and more. Start with this JSON,
parameterize the recipients, replace the mock webhook, and you're
production-ready.








SOCIAL SHARE CARD GENERATOR