Send Traces to Projects
Send traces to different projects on Confident AI
Overview
You can specify which project each trace should be sent to by selecting a project API key at runtime. This is especially useful when you need to separate traces to different projects within the same LLM application — for example, one project per tenant in a multi-tenant SaaS, or a separate project for a specific feature.
Configure the Default Project
Every trace goes to the default project unless you say otherwise. Set the default once at startup, either with the CONFIDENT_API_KEY environment variable or by passing api_key / apiKey to init():
export CONFIDENT_API_KEY="<your-default-project-key>"Route Traces to Projects
To send a specific request's trace somewhere else, wrap the traced work in a project scope with the API key of the project you want it to land in. Everything traced inside the scope — including auto-instrumented LLM calls — is exported to that project.
import os
from langchain_openai import ChatOpenAI
from confident_trace import init, project_context
init()
model = ChatOpenAI(model="gpt-4o")
def handle_request(query: str):
if query == "Write me a poem.":
key = os.environ["POETRY_PROJECT_KEY"]
else:
key = os.environ["OTHER_PROJECT_KEY"]
with project_context(api_key=key):
return model.invoke(query)project_context(...) also works with async with in async code.
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { init, projectContext } from "confident-trace";
init();
function handleRequest(query: string) {
const apiKey = query === "Write me a poem."
? process.env.POETRY_PROJECT_KEY!
: process.env.OTHER_PROJECT_KEY!;
return projectContext({ apiKey }, () =>
generateText({ model: openai("gpt-4o"), prompt: query }),
);
}Run your entry point with the Node preload so the Vercel AI SDK call is instrumented and routed with the rest of the request.
In a real app the key usually comes from the authenticated customer's server-side configuration rather than the request contents. A few things to keep in mind:
- Open the scope before traced work starts. Changing projects from inside an active traced span is rejected — pick the project in your request handler, then call into your instrumented code.
- Scopes are request-local. Concurrent requests keep their own destinations, and when a scope exits the caller's destination is restored. Spans that were created inside the scope stay with the project they were routed to.
- No silent fallback. If routing to a project fails, the trace is not quietly sent to the default project instead, so a misconfigured key won't leak one customer's traces into another project.
- You don't need a custom span. If your provider calls are auto-instrumented, wrapping them in a project context is enough to route them.
Next Steps
Multi-Tenant Project Isolation
A full walkthrough of routing each customer's traces to their own project.
Environment
Separate production, staging, and development traffic within a single project.
Last updated on