FlowRunner
Pricing
Theme
Start Free

OpenAI Agents SDK and FlowRunner

FlowRunner handles the approval loop the OpenAI Agents SDK leaves to you: it reaches the approver in Slack or email, waits days for the answer, and records it.

2026-11-02 Updated November 3, 2026 9 min

Add FlowRunner when

  • A tool call needs approval from someone who isn't using your app, in Slack, by email, on WhatsApp, by phone, or in a Form
  • An approval can take hours or days, longer than your process should hold a request open
  • The agent should start when something happens in a business app, or on a schedule
  • People outside engineering need a record of each run and who approved what
  • You're coming from Agent Builder and want a canvas the team can read

The Agents SDK on its own is enough when

  • The person approving is the user already in your app's chat, and your UI shows the approve button
  • Your agent runs inside a request and finishes in seconds
  • You already run Temporal, DBOS, Restate, or Dapr for durable waits, and you have a review screen
  • The OpenAI Traces dashboard is all the run history you need

TL;DR

  • FlowRunner takes the half of the Agents SDK approval loop that the SDK leaves to your app: reaching the approver by email, Slack, WhatsApp, phone, or a Form, waiting hours or days, and recording the answer. It also starts your agent from 2,100+ integrations or a schedule.
  • The Agents SDK is where you write agents, tools, handoffs, and guardrails, in your own Python or TypeScript app. Keep it.
  • Its approvals are documented: needs_approval, result.interruptions, and a RunState you can store and resume. OpenAI’s guide is clear about what else the app has to build, and that list is where FlowRunner fits.
  • Coming from Agent Builder? Its export is Agents SDK code. You can host that code yourself with FlowRunner around it, or turn it into a flow.

What the Agents SDK is for

The OpenAI Agents SDK is an open source library for building agent apps in your own code. OpenAI describes it as a way to “build agentic AI apps in a lightweight, easy-to-use package with very few abstractions,” and its guide puts the deployment model plainly: “The SDK runs inside your application.” It comes in Python and TypeScript, both MIT licensed.

The primitives are small. Agents are models with instructions and tools. An agent can hand off to another agent or be used as a tool by one. Guardrails check inputs and outputs. Around them, the SDK ships sessions for conversation memory, tracing that’s on by default, MCP client support (hosted MCP tools, Streamable HTTP, stdio), and realtime voice agents. The README calls it provider-agnostic, with support for OpenAI’s Responses and Chat Completions APIs and 100+ other models.

The approval support is solid. Mark a tool with needs_approval=True (or a function that decides per call), and the run stops before the tool executes. result.interruptions lists what’s waiting. Call state.approve(...) or state.reject(...) and run again to resume. For long waits, serialize the paused run with to_json() or to_string() and restore it later with RunState.from_json or RunState.from_string, even in a different process. For runs that span restarts, the SDK integrates with Temporal, DBOS, Restate, and Dapr.

What FlowRunner adds around it

OpenAI’s human-in-the-loop guide spells out the rest of the work. It says RunState.from_json() and RunState.from_string() “do not authenticate the snapshot.” It tells you to “authenticate the reviewer using the application’s session or authentication middleware,” to “use an atomic owner-checked transition before starting resumed execution,” and it warns that “approval permits a tool call to execute; it does not guarantee exactly-once execution,” so you should “assign a stable idempotency key to each logical action.”

Read that list from the approver’s side and there’s one more job underneath it: getting the request in front of a person at all. If the approver is the user in your chat window, your UI already does that. If it’s a finance lead in Slack, a manager who reads email, or a customer, you’re building a notification system, a decision screen, and something that waits for days.

FlowRunner is a workflow platform with that part built in:

  • The approver gets the request where they work. A flow sends it by email, Slack, WhatsApp, phone, or a Form with approve and reject choices, and pauses until the answer comes back. Then it posts the decision to your resume endpoint.
  • Long waits don’t hold your process. A run can wait up to 30 days on Free, Starter, and Growth, and up to a year on Professional and above. Your app stores the RunState and goes back to work. The whole run, wait included, is one execution.
  • A record of who decided. Each run is on the flow’s Instances tab with every step’s input and output, so the request, the answer, and who gave it are there for anyone in the workspace.
  • Triggers from 2,100+ integrations, and schedules. The SDK has no inbound triggers. A flow can start your agent service when an email arrives, a ticket opens, a deal changes stage, or a schedule fires.
  • Retries on the calls in between. The HTTP Request block that calls your service retries on 429 and 5XX with exponential backoff, and Handle Error gives a failed step a recovery path.
  • Unlimited users on every plan, so approvers and auditors don’t cost seats.

Your app keeps the parts that belong to it: the stored state, the check on the callback, the atomic resume, and the idempotency keys. FlowRunner doesn’t change any of that. It does the reaching and the waiting.

How they work together

The code for each pattern is on Use the OpenAI Agents SDK with FlowRunner.

Approval hand-off. When result.interruptions isn’t empty, your app saves the serialized state under a request id, then starts a FlowRunner flow with the non-blocking Call Flow API and the pending tool calls. The call returns at once. The flow reaches the approver, waits, and POSTs the decision with the request id to your resume endpoint. The endpoint checks the shared secret, claims the request once, restores the RunState, applies approve or reject, and runs again.

A flow as a function tool. Wrap the blocking Call Flow API in a tool. The flow does work across FlowRunner’s integrations (look up the order, check the CRM, create the ticket) and returns its answer in the same request, within up to 300 seconds. The agent gets the result, and FlowRunner keeps a record of the call.

A business event starts the agent. A flow starts on a new email, form submission, or support ticket, or on a schedule, and calls your agent service with an HTTP Request block that retries. The agent doesn’t need its own polling or cron.

Your MCP server, used by FlowRunner agents too. If your service exposes tools over a public MCP server, register it in FlowRunner and attach its tools to a FlowRunner AI Agent. The same tools your SDK agent uses become available to flows the rest of the team builds.

From Agent Builder to code, with FlowRunner around it. OpenAI shuts down Agent Builder on November 30, 2026, and its guidance is to continue with the Agents SDK or ChatGPT Workspace Agents. Agent Builder’s export is Agents SDK code, so the SDK is the natural home for it. Hosting it yourself means the approvals and triggers are yours to wire, and the patterns above cover them. If you’d rather keep a canvas, FlowRunner Prompt to Flow converts that same export into a flow: see the Agent Builder comparison and how to move from Agent Builder to FlowRunner.

When you don’t need FlowRunner

The SDK covers a lot by itself. Skip FlowRunner when:

  • The approver is the user in front of your app. The chat already shows the request, and your UI’s button calls approve or reject.
  • Runs finish inside one request. Nothing waits, so there’s nothing to hold.
  • You already run a durable workflow engine and a review screen. Temporal or DBOS plus your own admin UI covers the waits and the decisions.
  • The Traces dashboard is all the history you need, and nobody outside engineering asks what happened.
  • It’s a prototype. A notebook trying out instructions and handoffs doesn’t need triggers or approvals.

Add FlowRunner when the agent becomes part of how the business runs: someone outside the app approves, the wait is long, the work starts in a business system, or other people need the record.

Feature comparison

DimensionAgents SDK on its ownAgents SDK with FlowRunner
Agents, tools, handoffs, guardrailsIn your codeThe same code, unchanged
Approval pauseneeds_approval, interruptions, approve / rejectThe same pause
Reaching the approverYour app: notification, screen, remindersA flow, by email, Slack, WhatsApp, phone, or a Form
Waiting for the answerSerialize RunState and store it; durable engines for long runsYour app stores the state; the flow waits up to 30 days (Free to Growth) or a year (Professional and up)
Callback checks, atomic resume, idempotencyYour appStill your app; the flow sends a shared secret and the request id
What starts a runYour codeAny of 2,100+ integrations, a webhook, or a schedule
RetriesModel and runner retriesPlus Retry Policy and Handle Error on every call between systems
Run historyOpenAI Traces (not under Zero Data Retention), or your own processorEvery run’s steps, inputs, and outputs, open to the whole workspace
UsersYour app’s usersUnlimited FlowRunner users on every plan
PriceFree library; you pay for model usageFlowRunner Free covers 100 executions a month; one execution per run

Frequently asked questions

Does FlowRunner replace the OpenAI Agents SDK?

No. Your agents, tools, handoffs, and guardrails stay in your code, in Python or TypeScript. FlowRunner runs the parts around them: reaching the approver, waiting for the answer, starting the agent from business apps, and keeping a record of each run. FlowRunner doesn't run Python; your code calls FlowRunner over HTTP, or FlowRunner calls your service.

The SDK already has approvals. What does FlowRunner add?

The SDK pauses the run and gives you approve and reject calls. Getting the request to a person, giving them something to click, and waiting for them is up to your app, and OpenAI's guide says so. A FlowRunner flow does that part: it sends the request by email, Slack, WhatsApp, phone, or a Form, waits, records who answered, and posts the decision to your resume endpoint. Your app still checks that callback and resumes the run.

How long can an approval wait?

A FlowRunner run can wait up to 30 days on the Free, Starter, and Growth plans, and up to a year on Professional and above. Your app keeps the serialized RunState until the answer arrives.

I'm moving off Agent Builder. Should I use the Agents SDK or FlowRunner?

Either, or both. Agent Builder exports Agents SDK code, so you can keep that code and host it yourself, or have FlowRunner Prompt to Flow turn it into a flow on a canvas. See the Agent Builder comparison and how to move from Agent Builder.

What does it cost?

FlowRunner counts one execution per complete run, however many steps it has and however long it waits. The Free plan covers 100 executions a month with no card. Starter is $5 for 300 or $15 for 3,000, and Growth starts at $45 for 12,000. Every plan has every integration, AI agents with your own keys, human-in-the-loop, and unlimited users. New accounts get 14 days of Professional.

Does it work with the TypeScript SDK?

Yes. The pattern is the same: needsApproval on the tool, result.interruptions, result.state.toString() to store the paused run, and RunState.fromString(agent, serialized) to restore it. The FlowRunner side is plain HTTP, so the language doesn't matter.

Editorial policy

Ready to try it?

Start on the Free plan. No card required, and every new account gets 14 days of Professional.