Trace Vercel AI SDK calls in Next.js
Configure the traceAI span processor and OTLP/HTTP export for model calls in a Node.js Next.js API route.
Send model-call spans from a Node.js Next.js API route to an Observe project in Future AGI.
1. Install
Use this setup in an existing Next.js application with the Node.js runtime, not Edge. It uses AI SDK 6.0.0 and @traceai/vercel 0.1.0. The traceAI processor extends the OpenTelemetry 1.x span processor, so keep the SDK packages on the versions below rather than mixing them with OpenTelemetry 2.x.
npm install @traceai/vercel@0.1.0 @vercel/otel@1.13.0 \
@opentelemetry/api@1.9.0 @opentelemetry/sdk-trace-base@1.30.1 \
@opentelemetry/exporter-trace-otlp-http@0.57.2 \
ai@6.0.0 @ai-sdk/openai@3.0.0 zod@3.25.76yarn add @traceai/vercel@0.1.0 @vercel/otel@1.13.0 \
@opentelemetry/api@1.9.0 @opentelemetry/sdk-trace-base@1.30.1 \
@opentelemetry/exporter-trace-otlp-http@0.57.2 \
ai@6.0.0 @ai-sdk/openai@3.0.0 zod@3.25.76pnpm add @traceai/vercel@0.1.0 @vercel/otel@1.13.0 \
@opentelemetry/api@1.9.0 @opentelemetry/sdk-trace-base@1.30.1 \
@opentelemetry/exporter-trace-otlp-http@0.57.2 \
ai@6.0.0 @ai-sdk/openai@3.0.0 zod@3.25.76 For the processor API, see the traceAI Vercel package.
2. Set credentials
Set these in the environment of your Next.js server. For local development, use Next.js’s environment-file support; do not commit credentials.
FI_API_KEY=YOUR_FI_API_KEY
FI_SECRET_KEY=YOUR_FI_SECRET_KEY
OPENAI_API_KEY=YOUR_OPENAI_API_KEY
# Self-hosted: set your collector origin, without /tracer/v1/traces.
# FI_BASE_URL=https://your-futureagi-instance.example
3. Register tracing at server startup
Create instrumentation.ts in the project root, or in src/ if your application uses that directory. Next.js calls register() once per server instance; do not import or call it from _app.tsx or an API handler. If you already configure OpenTelemetry, add the Future AGI processor to that setup instead of registering another provider.
export async function register() {
if (process.env.NEXT_RUNTIME !== "nodejs") return;
const { registerOTel } = await import("@vercel/otel");
const { FISimpleSpanProcessor, isFISpan } = await import("@traceai/vercel");
const { OTLPTraceExporter } = await import("@opentelemetry/exporter-trace-otlp-http");
const apiKey = process.env.FI_API_KEY;
const secretKey = process.env.FI_SECRET_KEY;
if (!apiKey || !secretKey) {
throw new Error("Set FI_API_KEY and FI_SECRET_KEY before starting Next.js.");
}
const baseUrl = (process.env.FI_BASE_URL || "https://api.futureagi.com").replace(/\/+$/, "");
registerOTel({
serviceName: "vercel-project",
attributes: {
project_name: "vercel-project",
project_type: "observe",
},
spanProcessors: [
new FISimpleSpanProcessor({
exporter: new OTLPTraceExporter({
url: `${baseUrl}/tracer/v1/traces`,
headers: { "X-Api-Key": apiKey, "X-Secret-Key": secretKey },
}),
spanFilter: isFISpan,
}),
],
});
}
The HTTP exporter sends traces with both Future AGI auth headers. project_name and project_type are resource attributes, not camel-case settings. isFISpan limits export to spans recognized by the traceAI processor rather than unrelated Next.js spans.
4. Add a model call
In AI SDK 6.0.0, enable telemetry on the call with experimental_telemetry. The versioned telemetry settings record inputs and outputs by default; this example disables both.
Warning
Input/output switches are not complete redaction. Errors, custom telemetry metadata and request headers can still contain sensitive data. Do not put secrets or private request data in telemetry metadata, and review exported data before using private workloads.
import type { NextApiRequest, NextApiResponse } from "next";
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const result = await generateText({
model: openai("gpt-4o-mini"),
prompt: "Write a short creative story about a time-traveling detective.",
maxOutputTokens: 300,
experimental_telemetry: {
isEnabled: true,
recordInputs: false,
recordOutputs: false,
},
});
res.status(200).json({ story: result.text });
}
To include prompts and responses, set recordInputs and recordOutputs to true only for data you are allowed to store in Future AGI.
5. Open the trace
Run your Next.js application and request /api/story. Open Observe in Future AGI and select vercel-project to inspect the model-call spans. Input and Output content is hidden by the call’s settings above.
Troubleshooting
- No spans: confirm the Node.js server loads
instrumentation.ts, both Future AGI keys are set, and the call hasexperimental_telemetry.isEnabled=true. - Collector rejects the export: check both auth headers, the collector URL and the
project_nameresource attribute. - Processor type errors: keep the OpenTelemetry SDK on the pinned 1.x line; do not install a 2.x span processor alongside this traceAI release.
Questions & Discussion