Primary navigation

Legacy APIs

Guardrails and human review

Add automatic validation and human-in-the-loop approvals to SDK workflows.

Use guardrails for automatic checks and human review for approval decisions. Together, they define when a run should continue, pause, or stop.

  • Guardrails validate input, output, or tool behavior automatically.
  • Human review pauses the run so a person or policy can approve or reject a sensitive action.

Choose the right control

Use caseStart with
Block disallowed user requests before the main model runsInput guardrails
Validate or redact the final output before it leaves the systemOutput guardrails
Check arguments or results around a function tool callTool guardrails
Pause before side effects like cancellations, edits, shell commands, or sensitive MCP actionsHuman-in-the-loop approvals

Add a blocking guardrail

Use input guardrails when you want a fast validation step to run before the expensive or side-effecting part of the workflow starts.

Block a request with an input guardrail
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import {
  Agent,
  InputGuardrailTripwireTriggered,
  run,
} from "@openai/agents";
import { z } from "zod";

const guardrailAgent = new Agent({
  name: "Homework check",
  instructions: "Detect whether the user is asking for math homework help.",
  outputType: z.object({
    isMathHomework: z.boolean(),
    reasoning: z.string(),
  }),
});

const agent = new Agent({
  name: "Customer support",
  instructions: "Help customers with support questions.",
  inputGuardrails: [
    {
      name: "Math homework guardrail",
      runInParallel: false,
      async execute({ input, context }) {
        const result = await run(guardrailAgent, input, { context });
        return {
          outputInfo: result.finalOutput,
          tripwireTriggered: result.finalOutput?.isMathHomework === true,
        };
      },
    },
  ],
});

try {
  await run(agent, "Can you solve 2x + 3 = 11 for me?");
} catch (error) {
  if (error instanceof InputGuardrailTripwireTriggered) {
    console.log("Guardrail blocked the request.");
  }
}

Use blocking execution when the cost or risk of starting the main agent is too high. Use parallel guardrails when lower latency matters more than avoiding speculative work.

Pause for human review

Approvals are the human-in-the-loop path for tool calls. The model can still decide that an action is needed, but the run pauses until you approve or reject it.

Pause for approval before a sensitive action
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { Agent, run, tool } from "@openai/agents";
import { z } from "zod";

const cancelOrder = tool({
  name: "cancel_order",
  description: "Cancel a customer order.",
  parameters: z.object({ orderId: z.number() }),
  needsApproval: true,
  async execute({ orderId }) {
    return `Cancelled order ${orderId}`;
  },
});

const agent = new Agent({
  name: "Support agent",
  instructions: "Handle support requests and ask for approval when needed.",
  tools: [cancelOrder],
});

let result = await run(agent, "Cancel order 123.");

if (result.interruptions?.length) {
  const state = result.state;
  for (const interruption of result.interruptions) {
    state.approve(interruption);
  }
  result = await run(agent, state);
}

console.log(result.finalOutput);

This same interruption pattern applies even when the approving tool lives deeper in the workflow, such as after a handoff or inside a nested agent.asTool() call.

Approval lifecycle

When a tool call needs review, the SDK follows the same pattern every time:

  1. The run records an approval interruption instead of executing the tool.
  2. The result returns interruptions plus a resumable state.
  3. Your application approves or rejects the pending items.
  4. You resume the same run from state instead of starting a new user turn.

If the review might take time, serialize state, store it, and resume later. That’s still the same run.

Workflow boundaries matter

Agent-level guardrails don’t run everywhere:

  • Input guardrails run only for the first agent in the chain.
  • Output guardrails run only for the agent that produces the final output.
  • Tool guardrails run on the function tools they’re attached to.

If you need checks around every custom tool call in a manager-style workflow, don’t rely only on agent-level input or output guardrails. Put validation next to the tool that creates the side effect.

Streaming and delayed review use the same state model

Streaming doesn’t create a separate approval system. If a streamed run pauses, wait for it to settle, inspect interruptions, resolve the approvals, and resume from the same state. If the review happens later, store the serialized state and continue the same run when the decision arrives.

Next steps

Once the control boundaries are clear, continue with the guide that covers the runtime or tool surface around them.