> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squasher.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# .NET / C#

> Send errors and logs from .NET and ASP.NET Core applications to Squasher.

## Recommended: OpenTelemetry SDK

Auto-instrument ASP.NET Core, Entity Framework, HttpClient, and more.

### 1. Install

```bash theme={null}
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Instrumentation.Http
```

### 2. Configure

```csharp theme={null}
// Program.cs
using OpenTelemetry.Trace;
using OpenTelemetry.Logs;
using OpenTelemetry.Resources;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry()
    .ConfigureResource(r => r.AddService("my-dotnet-service"))
    .WithTracing(t => t
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        .AddOtlpExporter(o =>
        {
            o.Endpoint = new Uri("https://ingest.squasher.ai");
            o.Headers = "x-squasher-key=sq_pk_your_api_key";
        }))
    .WithLogging(l => l
        .AddOtlpExporter(o =>
        {
            o.Endpoint = new Uri("https://ingest.squasher.ai");
            o.Headers = "x-squasher-key=sq_pk_your_api_key";
        }));
```

### 3. Run

```bash theme={null}
dotnet run
```

All unhandled exceptions, error-level logs, and failed HTTP calls are automatically sent to Squasher.

## Alternative: Direct HTTP API

```csharp theme={null}
using System.Net.Http.Json;

public class SquasherClient
{
    private static readonly HttpClient _client = new();
    private const string Endpoint = "https://ingest.squasher.ai/v1/ingest/YOUR_PROJECT_ID";
    private const string ApiKey = "sq_pk_your_api_key";

    public static async Task CaptureErrorAsync(Exception ex, Dictionary<string, string>? tags = null)
    {
        var payload = new
        {
            message = ex.Message,
            type = ex.GetType().Name,
            level = "error",
            stack = ex.StackTrace,
            environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "production",
            tags = tags,
        };

        var request = new HttpRequestMessage(HttpMethod.Post, Endpoint)
        {
            Content = JsonContent.Create(payload),
        };
        request.Headers.Add("x-squasher-key", ApiKey);

        await _client.SendAsync(request);
    }
}
```

### Usage

```csharp theme={null}
try
{
    await ProcessOrderAsync(order);
}
catch (Exception ex)
{
    await SquasherClient.CaptureErrorAsync(ex, new() { ["orderId"] = order.Id });
    throw;
}
```

## Agent handoff

```text theme={null}
For .NET, prefer OpenTelemetry instrumentation for ASP.NET Core and HttpClient. Keep the Squasher key in configuration, set a service name, verify one exception, and use direct HTTP only when OTel is not practical.
```
