The SDK reads BRAINTRUST_API_KEY from the environment, or from a .env.braintrust file discovered upward from your working directory. Keep your API key out of version control.
Initialize Braintrust, get an ActivitySource, and wrap the client with BraintrustOpenAI.WrapOpenAI. Every call on the wrapped client is traced.
using System;using System.Threading.Tasks;using Braintrust.Sdk;using Braintrust.Sdk.OpenAI;using OpenAI;using OpenAI.Chat;class OpenAITracing{ static async Task Main(string[] args) { var braintrust = Braintrust.Sdk.Braintrust.Get(); var activitySource = braintrust.GetActivitySource(); var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY"); if (string.IsNullOrEmpty(apiKey)) { Console.WriteLine("Error: OPENAI_API_KEY environment variable is not set."); return; } // Wrap the OpenAI client with Braintrust instrumentation var client = BraintrustOpenAI.WrapOpenAI( activitySource, apiKey ); // All API calls are automatically logged var chatClient = client.GetChatClient("gpt-4o-mini"); var messages = new ChatMessage[] { new SystemChatMessage("You are a helpful assistant."), new UserChatMessage("What is machine learning?") }; var result = await chatClient.CompleteChatAsync(messages); }}
Call .WithBraintrust() on the Anthropic client. Once wrapped, every Messages.Create call (including streaming) emits a span.
using System;using System.Collections.Generic;using System.Threading.Tasks;using Anthropic;using Anthropic.Models.Messages;using Braintrust.Sdk.Anthropic;class AnthropicTracing{ static async Task Main(string[] args) { // Wrap the Anthropic client with Braintrust instrumentation var client = new AnthropicClient().WithBraintrust(); // All API calls are automatically logged var result = await client.Messages.Create(new MessageCreateParams { Model = "claude-sonnet-4-5-20250929", MaxTokens = 1024, Messages = new List<MessageParam> { new MessageParam { Role = "user", Content = "What is machine learning?" } } }); if (result.Content[0].TryPickText(out var textBlock)) { Console.WriteLine(textBlock.Text); } }}
Azure OpenAI
1
Add the Azure OpenAI integration package
dotnet add package Braintrust.Sdk.AzureOpenAI
2
Wrap the Azure OpenAI client
Create an instrumented client with WrapAzureOpenAI, then pass your Azure deployment name to GetChatClient.
#skip-compile
using Azure.AI.OpenAI;using Braintrust.Sdk;using Braintrust.Sdk.AzureOpenAI;using OpenAI.Chat;var braintrust = Braintrust.Sdk.Braintrust.Get();var activitySource = braintrust.GetActivitySource();var endpoint = new Uri(Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"));var apiKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY");// Create an instrumented Azure OpenAI clientvar client = BraintrustAzureOpenAI.WrapAzureOpenAI(activitySource, endpoint, apiKey);// Use your Azure deployment name, not the underlying model namevar chatClient = client.GetChatClient("gpt-5-mini");var response = await chatClient.CompleteChatAsync( new ChatMessage[] { new UserChatMessage("What is the capital of France?") });
For Microsoft Entra ID authentication, pass a TokenCredential to WrapAzureOpenAI in place of the API key. See the Azure AI Foundry integration for details.
UseBraintrustTracing instruments the LLM and tool calls on the ChatClientBuilder, and WithBraintrustAgentTracing wraps the agent so each run is captured as a span.
#skip-compile
using Braintrust.Sdk;using Braintrust.Sdk.AgentFramework;using Microsoft.Agents.AI;using Microsoft.Extensions.AI;using OpenAI;var braintrust = Braintrust.Sdk.Braintrust.Get();var activitySource = braintrust.GetActivitySource();// Add Braintrust tracing to the chat client (LLM calls + function calls)var chatClient = new OpenAIClient(Environment.GetEnvironmentVariable("OPENAI_API_KEY")) .GetChatClient("gpt-5-mini").AsIChatClient() .AsBuilder() .UseBraintrustTracing(activitySource) .Build();var getWeather = AIFunctionFactory.Create( (string city) => $"The weather in {city} is sunny, 72°F.", "GetWeather", "Gets the current weather for a city.");// Wrap the agent so each run is tracedvar agent = new ChatClientAgent( chatClient, instructions: "You are a helpful assistant. Use tools when appropriate.", name: "WeatherAgent", tools: [getWeather]) .WithBraintrustAgentTracing(activitySource);var session = await agent.CreateSessionAsync();var response = await agent.RunAsync("What's the weather like in Seattle?", session);Console.WriteLine(response.Text);
To learn more about what each integration captures, find your provider in SDK integrations.