> This page is for version v5.0 (default).
> For other versions, use one of these documentation indexes:
> - v5.0 (default): https://humanloop.com/docs/v5/llms.txt
> - v4.0: https://humanloop.com/docs/v4/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://humanloop.com/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://humanloop.com/docs/_mcp/server.

> Learn about the ways you can use Humanloop with the Vercel AI SDK.

![](/docs/_fern-img/be6cfd840b8ba9cfbc826627334e2508a650f29063d987c87abb4d5f4d7aea9a.webp)

## Observability integration

The Vercel AI SDK supports [tracing via OpenTelemetry](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry). You can export these traces to Humanloop by enabling telemetry and configuring the OpenTelemetry Exporter.

> **Warning**
>
> The Vercel AI SDK tracing feature is experimental and subject to change. You
> must enable it with the `experimental_telemetry` parameter on each AI SDK
> function call that you want to trace.

Learn how to add tracing to your AI SDK application below.

### Metadata parameters

Humanloop's AI SDK OpenTelemetry Receiver will automatically extract the following metadata parameters from the `experimental_telemetry` metadata object:

* `humanloop.directoryPath`: **\[Required]** The path to the directory on Humanloop. Generation spans will create Logs for this Directory on Humanloop.
* `humanloop.traceId`: **\[Optional]** The ID of a Flow Log on Humanloop. Set this to group multiple calls to the AI SDK into a single Flow Log on Humanloop.

### Prerequisites

The following steps assume you're already using the AI SDK in your application. If not, follow [Vercel's quickstarts](https://sdk.vercel.ai/docs/getting-started) to get started.

#### Next.js

> **Info**
>
> Versions of Next \< 15 must set `experimental.instrumentationHook` in `next.config.js`. Learn more [here](https://nextjs.org/docs/app/building-your-application/optimizing/open-telemetry).

You can find an example Next.js application that uses the AI SDK to stream chat responses [here](https://sdk.vercel.ai/cookbook/next/stream-text-with-chat-prompt).

### Set up OpenTelemetry

Install dependencies.

**`npm`**

```bash title="npm" wordWrap
npm install @vercel/otel @opentelemetry/sdk-logs @opentelemetry/api-logs @opentelemetry/instrumentation
```

**`pnpm`**

```bash title="pnpm" wordWrap
pnpm add @vercel/otel @opentelemetry/sdk-logs @opentelemetry/api-logs @opentelemetry/instrumentation
```

**`yarn`**

```bash title="yarn" wordWrap
yarn add @vercel/otel @opentelemetry/sdk-logs @opentelemetry/api-logs @opentelemetry/instrumentation
```

Create a file called `instrumentation.ts` in your root or /src directory and add the following:

**`instrumentation.ts`**

```typescript title="instrumentation.ts"
import { registerOTel } from '@vercel/otel';

export function register() {
    registerOTel({
        serviceName: 'humanloop-vercel-ai-sdk'
    });
}
```

### Configure OpenTelemetry

Configure the [OpenTelemetry exporter](https://opentelemetry.io/docs/specs/otel/protocol/exporter/) to forward logs to Humanloop.

**`.env.local`**

```plaintext title=".env.local" wordWrap
HUMANLOOP_API_KEY=<YOUR_HUMANLOOP_KEY>

# Configure the OpenTelemetry OTLP Exporter
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.humanloop.com/v5/import/otel
OTEL_EXPORTER_OTLP_PROTOCOL=http/json
OTEL_EXPORTER_OTLP_HEADERS="X-API-KEY=<YOUR_HUMANLOOP_KEY>" # Humanloop API key
```

### Trace AI SDK calls

Now add the `experimental_telemetry` parameter to your AI SDK function calls to trace them.

With a simple one-step generation, each call to `streamText` or `generateText` will be traced as a Prompt Log on Humanloop.

**`app/api/chat/route.ts`**

```typescript title="app/api/chat/route.ts" highlight={7-12} maxLines={50}
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';

// Allow streaming responses up to 30 seconds
export const maxDuration = 30;

export async function POST(req: Request) {
    const { messages, id } = await req.json();

    const result = streamText({
        model: openai('gpt-4o'),
        messages,
        experimental_telemetry: {
            isEnabled: true,
            metadata: {
                "humanloop.directoryPath": "path/to/directory",
            },
        },
    });

    // Respond with the stream
    return result.toDataStreamResponse();
}
```

You can also group each step of a multi-step generation into a Flow by passing the `humanloopFlowPath` metadata value.

**`app/api/chat/route.ts`**

```typescript title="app/api/chat/route.ts" highlight={10-16} maxLines={50}
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';

// Allow streaming responses up to 30 seconds
export const maxDuration = 30;

export async function POST(req: Request) {
    const { messages, id } = await req.json();

    const result = streamText({
        model: openai('gpt-4o'),
        messages,
        maxSteps: 3,
        toolCallStreaming: true,
        system: "You are a helpful assistant that answers questions about the weather in a given city.",
        experimental_telemetry: {
            isEnabled: true,
            metadata: {
                "humanloop.directoryPath": "path/to/directory",
            }
        },
        tools: {
            getWeatherInformation: {
                description: 'show the weather in a given city to the user',
                parameters: z.object({ city: z.string() }),
                execute: async ({}: { city: string }) => {
                    const weatherOptions = ['sunny', 'cloudy', 'rainy', 'snowy', 'windy'];
                    return {
                    weather:
                        weatherOptions[Math.floor(Math.random() * weatherOptions.length)],
                    temperature: Math.floor(Math.random() * 50 - 10),
                    };
                }
            },
        },
    });

    // Respond with the stream
    return result.toDataStreamResponse();
}
```

#### Node.js

> **Info**
>
> Node.js projects can use OpenTelemetry auto-instrumentation to trace requests without manually instrumenting code. Learn more about Node.js auto-instrumentation [here](https://opentelemetry.io/docs/languages/js/getting-started/nodejs).

### Set up OpenTelemetry

Install dependencies.

**`npm`**

```bash title="npm" wordWrap
npm install dotenv @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
```

**`pnpm`**

```bash title="pnpm" wordWrap
pnpm add dotenv @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
```

**`yarn`**

```bash title="yarn" wordWrap
yarn add dotenv @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
```

Add the following code to your file to initialize and clean up the OpenTelemetry SDK.

> **Info**
>
> Do not forget to call await sdk.shutdown() before your application shuts down in order to flush any remaining traces to Humanloop.

**`main.ts`**

```typescript title="main.ts"
import dotenv from 'dotenv';
import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";

dotenv.config();

// Start the OpenTelemetry SDK
const sdk = new NodeSDK({
    instrumentations: [getNodeAutoInstrumentations()]
});

sdk.start();

async function main() {
    // ... Your code here ...

    await sdk.shutdown();
}

main().catch(console.error);
```

### Configure OpenTelemetry

Configure the [OpenTelemetry exporter](https://opentelemetry.io/docs/specs/otel/protocol/exporter/) to forward logs to Humanloop.

**`.env.local`**

```plaintext title=".env.local" wordWrap
HUMANLOOP_API_KEY=<YOUR_HUMANLOOP_KEY>

# Configure the OpenTelemetry OTLP Exporter
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.humanloop.com/v5/import/otel
OTEL_EXPORTER_OTLP_PROTOCOL=http/json
OTEL_EXPORTER_OTLP_HEADERS="X-API-KEY=<YOUR_HUMANLOOP_KEY>" # Humanloop API key
```

### Trace AI SDK calls

Now add the `experimental_telemetry` parameter to your AI SDK function calls to trace them.

With a simple one-step generation, each call to `streamText` or `generateText` will be traced as a Prompt Log on Humanloop.

**`main.ts`**

```typescript title="main.ts" highlight={9-14} maxLines={50}
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';

async function main() {
    // Example of a simple one-step generation
    const result = await streamText({
        model: openai('gpt-4o'),
        messages,
        experimental_telemetry: {
            isEnabled: true,
            metadata: {
                "humanloop.directoryPath": "path/to/directory",
            }
        }
    });
}
```

You can also group each step of a multi-step generation into a Flow by passing the `humanloopFlowPath` metadata value.

**`main.ts`**

```typescript title="main.ts" highlight={12-18} maxLines={50}
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';

async function main() {
    // Example of a multi-step generation
    const result = await streamText({
        model: openai('gpt-4o'),
        messages,
        maxSteps: 3,
        toolCallStreaming: true,
        system: "You are a helpful assistant that answers questions about the weather in a given city.",
        experimental_telemetry: {
            isEnabled: true,
            metadata: {
                "humanloop.directoryPath": "path/to/directory",
            }
        },
        tools: {
            getWeatherInformation: {
                description: 'show the weather in a given city to the user',
                parameters: z.object({ city: z.string() }),
                execute: async ({}: { city: string }) => {
                    const weatherOptions = ['sunny', 'cloudy', 'rainy', 'snowy', 'windy'];
                    return {
                    weather:
                        weatherOptions[Math.floor(Math.random() * weatherOptions.length)],
                    temperature: Math.floor(Math.random() * 50 - 10),
                    };
                }
            },
        },
    });
}
```

## Learn more

To see the integration in action, check out our [Vercel AI SDK guides](/docs/v5/integrations/vercel-ai-sdk).