.NET SDK
The TruthVouch .NET SDK provides drop-in replacements for OpenAI, Anthropic, and Google AI providers. Fully integrated with .NET’s dependency injection system for automatic PII detection, policy enforcement, and hallucination detection.
Installation
dotnet add package TruthVouch.SdkRequires .NET 9.0+.
Quick Start
1. Register with Dependency Injection
In Program.cs:
builder.Services.AddTruthVouch(options =>{ options.GatewayUrl = "https://gateway.truthvouch.com"; options.ApiKey = "tv_..."; // From TruthVouch dashboard → Settings → API Keys options.FailMode = FailMode.Open; // Open = bypass on outage; Closed = block on outage});2. Inject and Use
public class MyService(ITruthVouchClient client){ public async Task<string> AskQuestionAsync(string question, CancellationToken ct) { var response = await client.Chat.CreateAsync(new ChatRequest { Model = "gpt-4o", Messages = [new("user", question)] }, ct);
// Governance metadata available on every response if (response.Governance.Verdict == "blocked") throw new GovernancePolicyViolationException(response.Governance);
if (response.Governance.PiiDetected) _logger.LogWarning("PII detected in response");
return response.Content; }}Provider Examples
OpenAI (drop-in replacement)
var response = await client.Chat.CreateAsync(new ChatRequest{ Model = "gpt-4o", Messages = [new("user", "Summarise this document")], Temperature = 0.7, MaxTokens = 1024});Console.WriteLine(response.Content);Console.WriteLine($"Verdict: {response.Governance.Verdict}");Console.WriteLine($"Overhead: {response.Governance.OverheadMs}ms");Anthropic (drop-in replacement)
var response = await client.Messages.CreateAsync(new AnthropicMessageRequest{ Model = "claude-3-5-sonnet-20241022", MaxTokens = 1024, System = "You are a helpful assistant.", Messages = [new("user", "What is quantum computing?")]});Console.WriteLine(response.Content);Google AI / Gemini (drop-in replacement)
var response = await client.Google.GenerateContentAsync(new GoogleContentRequest{ Model = "gemini-1.5-pro", Contents = [new("user", "Explain AI governance")]});Console.WriteLine(response.Text);Streaming
await using var stream = await client.Chat.CreateStreamAsync(new ChatRequest{ Model = "gpt-4o", Messages = [new("user", "Write me a short story")]});
await foreach (var chunk in stream.ReadChunksAsync(ct)){ if (!string.IsNullOrEmpty(chunk.Content)) Console.Write(chunk.Content);
if (chunk.IsLast) { var gov = stream.GovernanceReport; Console.WriteLine($"\nVerdict: {gov?.Verdict}"); }}Batch Scanning
Submit a document corpus for offline governance analysis:
var job = await client.Batch.SubmitAsync(new BatchScanRequest{ SourceUrl = "s3://my-bucket/documents.jsonl", Format = "jsonl", ScanMode = "deep", // fast | standard | deep CallbackUrl = "https://my-app.com/webhooks/scan-complete"});
Console.WriteLine($"Job {job.Id} submitted — ETA: {job.EstimatedCompletion}");
// Poll for statusvar status = await client.Batch.GetStatusAsync(job.Id);Console.WriteLine($"Progress: {status.Scanned}/{status.Total} ({status.ProgressPercent}%)");Console.WriteLine($"Flagged: {status.FlaggedCount}");Circuit Breaker and Fail Modes
The SDK includes a built-in circuit breaker that opens after consecutive gateway failures.
| FailMode | Behavior |
|---|---|
FailMode.Open (default) | Bypass the gateway; call succeeds with governance.verdict = "bypassed" |
FailMode.Closed | Throw GatewayUnreachableException; no LLM call is made |
builder.Services.AddTruthVouch(options =>{ options.FailMode = FailMode.Closed; // Compliance mode options.CircuitBreakerFailureThreshold = 5; // Open after 5 failures options.CircuitBreakerRecoverySeconds = 60; // Retry after 60 seconds options.MaxRetries = 3; // Exponential backoff retries});Error Handling
try{ var response = await client.Chat.CreateAsync(request);}catch (GovernancePolicyViolationException ex){ _logger.LogWarning("Blocked by governance: {Violations}", string.Join(", ", ex.GovernanceReport!.PolicyViolations));}catch (TruthVouchAuthException ex){ _logger.LogError("Auth failed — check your API key. RequestId: {RequestId}", ex.RequestId);}catch (QuotaExceededException ex){ _logger.LogWarning("Rate limited. RetryAfter: {RetryAfter}", ex.RetryAfterUnixSeconds);}catch (TruthVouchException ex){ _logger.LogError("TruthVouch error [{Code}]: {Message}", ex.ErrorCode, ex.Message);}All SDK exceptions extend TruthVouchException and carry:
ErrorCode— standardised code string for programmatic handlingGovernanceReport— governance metadata when availableRequestId— for tracing with TruthVouch support
Configuration Reference
| Option | Type | Default | Description |
|---|---|---|---|
GatewayUrl | string | required | TruthVouch Gateway base URL |
ApiKey | string | required | API key from TruthVouch dashboard |
FailMode | FailMode | Open | Behaviour when gateway is unreachable |
TimeoutSeconds | int | 30 | HTTP request timeout |
MaxRetries | int | 3 | Retry attempts (exponential backoff) |
CircuitBreakerFailureThreshold | int | 5 | Failures before circuit opens |
CircuitBreakerRecoverySeconds | int | 60 | Seconds until recovery probe |
ServiceName | string? | null | OpenTelemetry service name for trace propagation |
Verification API
Verify content independently of the gateway proxy — call the Trust API and data verification endpoints directly.
Verify Data Grounding
var result = await client.Verify.DataGroundingAsync(new DataGroundingRequest{ Query = "What country had the highest uplift?", Response = "Germany had the highest uplift at 23%.", Sql = "SELECT country, uplift FROM sales ORDER BY uplift DESC", RawResults = """[{"country": "France", "uplift": 0.181}]"""});
Console.WriteLine($"Score: {result.OverallScore}"); // 0.15Console.WriteLine($"Verdict: {result.Verdict}"); // "contradicted"foreach (var claim in result.Claims) Console.WriteLine($" {claim.Text}: {claim.Verdict} (score={claim.Score})");Verify a Claim
var result = await client.Verify.ClaimAsync("Paris is the capital of France", mode: "standard");Console.WriteLine($"Trust: {result.TrustScore}"); // 0.97Console.WriteLine($"Verdict: {result.Verdict}"); // "accurate"Check Faithfulness
var result = await client.Verify.FaithfulnessAsync(new FaithfulnessRequest{ Response = "The project was completed in March 2026.", Context = "The project wrapped up during March 2026 after 3 months of development.", Strictness = "moderate"});Console.WriteLine($"Score: {result.Score}"); // 0.95Console.WriteLine($"Faithful: {result.Faithful}"); // TrueEvaluate Prompt Quality
var result = await client.Verify.PromptQualityAsync( "You are a financial advisor who can access customer account balances and make transfers...");Console.WriteLine($"Risk: {result.RiskLevel}"); // "high"Console.WriteLine($"Issues: {string.Join(", ", result.Issues)}");License
Apache-2.0