> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flow.engineer/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI Agents SDK

> Receive messages and send an OpenAI Agents SDK run back as chat bubbles.

Run your OpenAI Agents SDK agent for each incoming message and pass its stream to Flow's `reply()`. The messaging integration is the same on each connected channel.

```ts TypeScript theme={null}
// npm install @flow-engineer/messaging @openai/agents
import { Agent, run } from "@openai/agents";
import { FlowMessaging, contentText } from "@flow-engineer/messaging";

const flow = new FlowMessaging();
const agent = new Agent({
  name: "Bakery assistant",
  instructions: "You help customers of Asha's Bakery with orders and delivery. Keep answers short.",
  model: "gpt-4.1-mini",
});

for await (const event of flow.events.stream({ types: ["message.received"] })) {
  const result = await run(agent, contentText(event.data.message.content), { stream: true });
  await event.conversation.reply(result); // reads result.toTextStream()
}
```

```python Python (HTTP) theme={null}
# pip install openai-agents fastapi requests
# Plain HTTP, no Flow SDK; the Python SDK (pip install flow-messaging) wraps the same calls. This calls the HTTP API.
import os, requests
from fastapi import FastAPI, Request, BackgroundTasks
from agents import Agent, Runner

API = "https://api.flow.engineer"
HEADERS = {"Authorization": f"Bearer {os.environ['FLOW_MESSAGING_KEY']}"}
agent = Agent(name="Bakery assistant", instructions="You help customers of Asha's Bakery. Keep answers short.")
app = FastAPI()

async def answer(event: dict):
    text = event["data"]["message"]["content"].get("text", "")
    result = await Runner.run(agent, text)
    requests.post(
        f"{API}/v0/conversations/{event['conversation']['id']}/basic",
        headers={**HEADERS, "Idempotency-Key": event["id"]},
        json={"text": result.final_output},  # sent exactly as written: no markdown is rendered
        timeout=30,
    )

@app.post("/flow")
async def flow_webhook(request: Request, tasks: BackgroundTasks):
    event = await request.json()  # verify Flow-Signature first: see Events and webhooks
    if event["type"] == "message.received":
        tasks.add_task(answer, event)
    return {}
```

## How it fits

* In TypeScript, `run(agent, input, { stream: true })` returns a streamed result; `reply()` reads its text stream and sends bubbles while the agent runs.
* In Python, answer the webhook with `{}` at once and send the agent's `final_output` afterwards. Text longer than the channel's limit (4096 characters on Telegram) is refused, so split long answers at paragraph breaks ([the bubble rule](https://docs.flow.engineer/unified-messaging-api/concepts/streaming-replies.md#the-bubble-rule-for-any-language)) and send each part with its own `Idempotency-Key`.
* Give the agent the conversation's history from `GET /v0/conversations/{conversation_id}/messages`, or keep your own session keyed by `conversation.id`.
* Verify webhook signatures as shown in [Events and webhooks](https://docs.flow.engineer/unified-messaging-api/concepts/events-and-webhooks.md#verify-the-signature).
* To see each turn's model and tool calls and get every reply graded, send this agent's traces to Flow Observe: [Traces from agent frameworks](https://docs.flow.engineer/unified-messaging-api/observe/frameworks.md).

## Full example

[examples/openai-agents](https://github.com/flow-engineer/sdk/tree/main/examples/openai-agents) on GitHub.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.