---
title: "Vercel AI"
description: "Adds instrumentation for Vercel AI SDK."
url: https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai/
---

# Vercel AI | Sentry for Next.js

*Import name: `Sentry.vercelAIIntegration`*

The `vercelAIIntegration` adds instrumentation for the [`ai`](https://www.npmjs.com/package/ai) SDK by Vercel to capture spans using the [AI SDK's built-in telemetry](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry).

Don't use the AI SDK's `registerTelemetry` API (AI SDK v7 and above) together with this integration. `vercelAIIntegration` already instruments the AI SDK, so registering telemetry separately produces duplicate spans.

## [Runtime Differences](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#runtime-differences)

Next.js runs your server code in two runtimes, and Sentry ships a different implementation for each. The Node implementation patches the `ai` module through OpenTelemetry. The Edge runtime can't load OpenTelemetry instrumentation, so it uses a reduced implementation that reads the spans the AI SDK emits on its own.

That difference decides where you configure the integration and which options do anything:

|                                   | Node runtime            | Edge runtime                        |
| --------------------------------- | ----------------------- | ----------------------------------- |
| Enabled by default                | Yes                     | No — add it to `sentry.edge.config` |
| `experimental_telemetry` per call | Not needed              | Required, or no spans are created   |
| Record inputs and outputs         | Integration or per call | Per call only                       |
| `force`                           | Available               | Not available — always active       |
| AI SDK v7                         | Supported               | Not supported                       |

## [Setup](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#setup)

### [Node Runtime](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#node-runtime)

The integration is enabled by default. No setup code is needed beyond enabling tracing:

```javascript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
  tracesSampleRate: 1.0,
});
```

If spans are missing here, your build most likely bundled the `ai` package so module detection fails. See [Troubleshooting](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#troubleshooting).

### [Edge Runtime](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#edge-runtime)

The integration is not enabled by default. Add it yourself:

```javascript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
  tracesSampleRate: 1.0,
  integrations: [Sentry.vercelAIIntegration()],
});
```

Adding the integration is not enough on its own. The Edge runtime can't patch your call sites, so you must also pass `experimental_telemetry` on every call. See [Turn on telemetry](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#turn-on-telemetry).

## [Record Inputs and Outputs](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#record-inputs-and-outputs)

Prompts and completions are not captured by default, because they usually contain user data. Turn recording on with `recordInputs` and `recordOutputs`.

Sentry resolves both settings in this order, and stops at the first one that is set:

1. The integration option — applies to every call.
2. The call's `experimental_telemetry` — applies to that call.
3. [`dataCollection.genAI`](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options.md#dataCollection) — applies to every call.

The integration option wins over the call, not the other way around. If you set `recordInputs: false` on the integration, no call site can turn it back on.

### [Node Runtime](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#node-runtime-1)

Set the options on the integration to cover every call. Re-adding the integration replaces the default instance and configures it:

```javascript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
  tracesSampleRate: 1.0,
  integrations: [
    Sentry.vercelAIIntegration({
      recordInputs: true,
      recordOutputs: true,
    }),
  ],
});
```

To record only some calls, leave the integration options unset and set them per call instead:

```javascript
const result = await generateText({
  model: openai("gpt-4o"),
  experimental_telemetry: {
    recordInputs: true,
    recordOutputs: true,
  },
});
```

### [Edge runtime](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#edge-runtime-1)

The Edge runtime ignores `recordInputs` and `recordOutputs` on the integration. It accepts no error and logs no warning — your prompts are simply missing. Set both per call.

```javascript
const result = await generateText({
  model: openai("gpt-4o"),
  experimental_telemetry: {
    isEnabled: true,
    recordInputs: true,
    recordOutputs: true,
  },
});
```

`dataCollection: {}` also turns recording on, but it opts you into the SDK's permissive defaults for every other category too: user identity, cookies, headers, HTTP bodies, query parameters, and stack-frame locals. Prefer the integration and per-call options above unless you want all of it. See [`dataCollection`](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options.md#dataCollection).

## [Configure individual calls](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#configure-individual-calls)

Every instrumented `ai` function takes an `experimental_telemetry` object. Use it to control one call instead of all of them. For the full list of fields, see the [AI SDK telemetry metadata docs](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry#telemetry-metadata).

### [Turn on Telemetry](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#turn-on-telemetry)

This applies to the **Edge** runtime only. On the Node runtime, Sentry patches your call sites for you.

Set `isEnabled` to `true` on every instrumented call. Without it, the AI SDK emits no spans and Sentry has nothing to capture:

```javascript
const result = await generateText({
  model: openai("gpt-4o"),
  experimental_telemetry: { isEnabled: true },
});
```

For `ToolLoopAgent`, set it on the constructor instead. See [ToolLoopAgent](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#toolloopagent).

### [Skip a Call](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#skip-a-call)

To capture no span for one call, set `isEnabled` to `false`:

```javascript
const result = await generateText({
  model: openai("gpt-4o"),
  experimental_telemetry: { isEnabled: false },
});
```

### [Identify Your Call Sites](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#identify-your-call-sites)

Spans carry the AI SDK function name, not yours, so a trace with several `generateText` calls is hard to read. Set `functionId` to label the call site. It appears on the span as `gen_ai.function_id`:

```javascript
const result = await generateText({
  model: openai("gpt-4o"),
  experimental_telemetry: {
    functionId: "summarize-ticket",
  },
});
```

### [ToolLoopAgent](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#toolloopagent)

The integration captures spans for the [`ToolLoopAgent`](https://ai-sdk.dev/docs/agents/overview#toolloopagent-class) class. Each call to `generate()` or `stream()` creates an agent span, with the individual LLM requests and tool executions as child spans.

`ToolLoopAgent` takes its telemetry settings on the constructor, not on `generate()` or `stream()`:

This applies to the **Edge** runtime only. On the Node runtime, Sentry patches your call sites for you — pass `experimental_telemetry` only to set `functionId` or the recording options.

```javascript
const agent = new ToolLoopAgent({
  model: openai("gpt-4o"),
  tools: {
    /* ... */
  },
  experimental_telemetry: {
    isEnabled: true,
    functionId: "weather-agent",
  },
});

const result = await agent.generate({
  prompt: "What is the weather in San Francisco?",
});
```

## [Options](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#options)

Pass these to `Sentry.vercelAIIntegration()`. The Edge runtime accepts `enableTruncation` only.

### [`enableTruncation`](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#enabletruncation)

*Type: `boolean`*

Truncates recorded input messages so large payloads stay within span size limits. Affects inputs only, not outputs.

Defaults to `true`.

```javascript
Sentry.init({
  integrations: [Sentry.vercelAIIntegration({ enableTruncation: false })],
});
```

### [`force`](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#force)

*Type: `boolean`*

Registers the integration's span processors even when the `ai` module can't be detected. Set this when your build bundles `ai`, which defeats module detection. See [Troubleshooting](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#troubleshooting).

Defaults to `false`.

```javascript
Sentry.init({
  integrations: [Sentry.vercelAIIntegration({ force: true })],
});
```

Not available in the Edge runtime, where the integration is always active once you add it.

### [`recordInputs`](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#recordinputs)

*Type: `boolean`*

Records inputs to the `ai` function call. See [Record inputs and outputs](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#record-inputs-and-outputs) for the full resolution order and the per-call alternative.

### [`recordOutputs`](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#recordoutputs)

*Type: `boolean`*

Records outputs from the `ai` function call. See [Record inputs and outputs](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#record-inputs-and-outputs) for the full resolution order and the per-call alternative.

## [Supported Operations](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#supported-operations)

Spans are captured for these `ai` functions. On the Edge runtime, pass `experimental_telemetry` to each one, as described in [Turn on telemetry](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#turn-on-telemetry):

* `generateText()`
* `streamText()`
* `generateObject()`
* `streamObject()`
* `embed()`
* `embedMany()`
* `rerank()`

Plus `generate()` and `stream()` on [`ToolLoopAgent`](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#toolloopagent).

## [Supported Versions](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#supported-versions)

* `ai`: `>=3.0.0 <=7`

- Sentry SDK: `10.6.0`+
- Edge runtime: `ai` v7 is not supported. Use v6 or below, or run the call in the Node runtime.

## [Troubleshooting](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#troubleshooting)

Why do my AI spans show 'ai.toolCall' instead of 'gen\_ai.execute\_tool' on Vercel?

When deploying to Vercel, you may notice that AI SDK spans have raw names like `ai.toolCall` or `ai.streamText` instead of the expected semantic names like `gen_ai.execute_tool` or `gen_ai.stream_text`.

This happens because the `ai` package is bundled (not externalized) in Next.js production builds, which prevents the integration from automatically detecting and instrumenting the module.

To fix this, explicitly enable the integration with `force: true` in your `sentry.server.config.ts`:

```javascript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
  integrations: [Sentry.vercelAIIntegration({ force: true })],
});
```

The `force` option ensures the integration registers its span processors regardless of module detection.

Why are my prompts and completions missing?

Recording is off unless you turn it on. Check, in order:

1. `recordInputs` and `recordOutputs` are set. See [Record inputs and outputs](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/integrations/vercelai.md#record-inputs-and-outputs).
2. You set them in a place the runtime reads. Some runtimes ignore the integration options and take them per call only.
3. No integration option is overriding your per-call value. The integration option wins.
