> ## 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.

# Vercel AI SDK

> Connect a Vercel AI SDK agent to Flow Messaging.

Use Flow to receive messages and deliver a Vercel AI SDK agent's answer as chat bubbles. The webhook example below keeps channel delivery separate from your model and tools.

```ts TypeScript theme={null}
// app/api/flow/route.ts (Next.js)
// npm install @flow-engineer/messaging ai @ai-sdk/openai
import { after } from "next/server";
import { FlowMessaging, contentText } from "@flow-engineer/messaging";
import { streamText, type ModelMessage } from "ai";
import { openai } from "@ai-sdk/openai";

const flow = new FlowMessaging();

export const POST = flow.webhooks.handler({
  onEvent: async (event) => {
    if (event.type !== "message.received") return;

    after(async () => {
      // The last 20 messages of this conversation, oldest first (the new one included).
      const page = await event.conversation.messages({ limit: 20 });
      const messages: ModelMessage[] = page.data
        .reverse()
        .map((m) => ({ role: m.direction === "in" ? "user" : "assistant", content: contentText(m.content) }) as ModelMessage)
        .filter((m) => m.content);

      const result = streamText({
        model: openai("gpt-4.1-mini"),
        system: "You are the assistant for Asha's Bakery. Answer in short messages.",
        messages,
      });
      await event.conversation.reply(result, { idempotencyKey: event.id });
    });
  },
});
```

Set `FLOW_MESSAGING_KEY`, `FLOW_MESSAGING_WEBHOOK_SECRET` and `OPENAI_API_KEY`, then register `https://<your-app>/api/flow` as a webhook endpoint for `message.received`. During development, with no public URL, read events from the live stream (`GET /v0/stream`) instead; `npx @flow-engineer/messaging listen --forward-to http://localhost:3000/api/flow` wraps it for this route. See [Local development](https://docs.flow.engineer/unified-messaging-api/guides/local-development.md).

## How it fits

* `reply(result)` reads `result.textStream`, keeps the typing indicator on, and sends a bubble at each paragraph break while the model writes. See [Streaming replies](https://docs.flow.engineer/unified-messaging-api/concepts/streaming-replies.md).
* Tools work as usual (`tools`, `stopWhen`); only the model's text is sent to the person, never tool calls or their results (text the model writes between tool steps is sent too). To show progress during long tool calls, wrap the work in `event.conversation.responding(...)`.
* The webhook answers at once and `after()` runs the reply, so slow models never cause a timed-out delivery.
* One handler serves Telegram and iMessage alike; `event.conversation.channel` tells you which one if you want to adapt the tone.
* 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/vercel-ai-sdk](https://github.com/flow-engineer/sdk/tree/main/examples/vercel-ai-sdk) on GitHub.

## Related

* [Build a Telegram agent](https://docs.flow.engineer/unified-messaging-api/guides/telegram-agent.md)
* [Build an iMessage agent](https://docs.flow.engineer/unified-messaging-api/guides/imessage-agent.md)
* [Events and webhooks](https://docs.flow.engineer/unified-messaging-api/concepts/events-and-webhooks.md)


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