Handling Approvals
Build a human-in-the-loop approval flow for high-risk operations
2 min read
Handling Approvals
Some workflow tool executions are marked as high-risk and require human approval before they can proceed. This guide shows you how to build a complete approval flow.
How It Works
- You trigger a workflow via the Run Workflow endpoint
- You connect to the SSE stream to receive events
- When a high-risk tool is about to execute, the workflow pauses and emits an
approval_requestevent - Your application presents the request to a human reviewer
- The reviewer approves or rejects via the Approvals API
- The workflow continues or handles the rejection accordingly
Full Example
1. Start the Workflow
const runResponse = await fetch(
"https://api.mindra.co/v1/workflows/your-workflow-slug/run",
{
method: "POST",
headers: {
"x-api-key": process.env.MINDRA_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
task: "Your task description here",
}),
}
);
const { execution_id, stream_url } = await runResponse.json();
2. Listen for Events
const response = await fetch(
`https://api.mindra.co${stream_url}`,
{
headers: { "x-api-key": process.env.MINDRA_API_KEY },
}
);
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value);
const lines = text.split("\n");
for (const line of lines) {
if (line.startsWith("data: ")) {
const data = JSON.parse(line.slice(6));
if (data.approval_id) {
await handleApproval(execution_id, data);
}
}
}
}
3. Handle the Approval
async function handleApproval(
executionId: string,
approval: { approval_id: string; tool_name: string; tool_input: any }
) {
console.log(`Approval needed for: ${approval.tool_name}`);
console.log(`Input: ${JSON.stringify(approval.tool_input, null, 2)}`);
// In a real app, you'd show this in a UI for a human to review.
// Here we auto-approve for demonstration:
const response = await fetch(
`https://api.mindra.co/v1/workflows/execute/${executionId}/approve/${approval.approval_id}`,
{
method: "POST",
headers: {
"x-api-key": process.env.MINDRA_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ reason: "Approved by admin" }),
}
);
console.log("Approval submitted:", response.status);
}
Best Practices
- Show context — Display the tool name, input, and any relevant context to the reviewer
- Set timeouts — Configure approval timeouts in your workflow to avoid indefinitely paused executions
- Log decisions — Record who approved or rejected each request and why
- Notify reviewers — Use notifications (email, Slack, etc.) to alert reviewers of pending approvals