← Blog

Claude API .NET SDK Integration Example

2026-10-22 · 4 min read · SubToAPI Team

Does Anthropic Have an Official .NET SDK?

No. Anthropic publishes official SDKs for Python and TypeScript/JavaScript, but there is no official Claude API .NET SDK as of this writing. If you're searching for "claude api dotnet sdk integration example" because you expected a NuGet package to drop in and work like the Python client, you won't find one maintained by Anthropic.

That's not a blocker. The Claude API is a plain HTTPS/JSON REST API, which means any .NET application — ASP.NET Core, a console app, a Blazor service, an Azure Function — can call it directly with HttpClient and System.Text.Json. You get full control over serialization, retries, and timeouts without depending on a third-party package's release cycle. This article shows exactly how to build that integration, plus a simpler path if you'd rather skip the plumbing.

Calling Claude Directly from C# with HttpClient

The Messages endpoint expects a POST with your API key in the x-api-key header, an anthropic-version header, and a JSON body containing the model, a token limit, and a messages array.

using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var client = new HttpClient { BaseAddress = new Uri("https://api.anthropic.com/") };
client.DefaultRequestHeaders.Add("x-api-key", Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY"));
client.DefaultRequestHeaders.Add("anthropic-version", "2023-06-01");

var payload = new
{
    model = "claude-3-5-sonnet-20241022",
    max_tokens = 1024,
    messages = new[]
    {
        new { role = "user", content = "Summarize the benefits of static typing in two sentences." }
    }
};

var json = JsonSerializer.Serialize(payload);
var request = new HttpRequestMessage(HttpMethod.Post, "v1/messages")
{
    Content = new StringContent(json, Encoding.UTF8, "application/json")
};

var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);

This works, but every call needs the same headers and error handling scattered across your codebase unless you wrap it.

A Reusable Claude Client Class

A small wrapper class keeps the integration maintainable and testable:

public class ClaudeClient
{
    private readonly HttpClient _http;

    public ClaudeClient(HttpClient http)
    {
        _http = http;
    }

    public async Task<string> AskAsync(string prompt, string model = "claude-3-5-sonnet-20241022")
    {
        var payload = new
        {
            model,
            max_tokens = 1024,
            messages = new[] { new { role = "user", content = prompt } }
        };

        var response = await _http.PostAsJsonAsync("v1/messages", payload);
        response.EnsureSuccessStatusCode();

        var doc = await response.Content.ReadFromJsonAsync<JsonDocument>();
        return doc!.RootElement
            .GetProperty("content")[0]
            .GetProperty("text")
            .GetString() ?? "";
    }
}

Register it in Program.cs with IHttpClientFactory so connections are pooled correctly:

builder.Services.AddHttpClient<ClaudeClient>(c =>
{
    c.BaseAddress = new Uri("https://api.anthropic.com/");
    c.DefaultRequestHeaders.Add("x-api-key", builder.Configuration["Anthropic:ApiKey"]);
    c.DefaultRequestHeaders.Add("anthropic-version", "2023-06-01");
});

Now any controller or service can inject ClaudeClient and call AskAsync, no raw HTTP code in business logic.

A Simpler Path: SubToAPI as the Endpoint

If you'd rather not manage Anthropic billing, console setup, and rate-limit tiers separately from your app, SubToAPI turns your existing Claude access into a standard HTTPS API with its own application keys (sub_live_...). The request/response shape mirrors the Messages API, so the C# code above barely changes — swap the base URL and header:

builder.Services.AddHttpClient<ClaudeClient>(c =>
{
    c.BaseAddress = new Uri("https://api.subtoapi.app/");
    c.DefaultRequestHeaders.Authorization =
        new AuthenticationHeaderValue("Bearer", builder.Configuration["SubToAPI:Key"]);
});
var response = await _http.PostAsJsonAsync("v1/messages", payload);

This is useful in .NET shops where multiple services or team members need isolated API keys, usage visibility, and billing in one dashboard instead of sharing a single Anthropic console key across projects. Full request/response details are in /docs/messages and the fastest way to get a working call is /docs/quickstart. Streaming responses — useful for chat UIs built with SignalR or Blazor Server — are documented at /docs/streaming, and function/tool calling from .NET follows the same JSON schema described at /docs/tools.

Handling Errors and Retries

Claude's API returns standard HTTP status codes: 429 for rate limits, 401 for bad credentials, 529 for overloaded upstream. In .NET, wrap calls with Polly for retry-with-backoff instead of writing retry loops by hand:

builder.Services.AddHttpClient<ClaudeClient>(c =>
{
    c.BaseAddress = new Uri("https://api.anthropic.com/");
})
.AddTransientHttpErrorPolicy(policy =>
    policy.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i))));

This retries transient failures (5xx, timeouts) three times with exponential backoff, which handles most temporary overload situations without extra code in your client class.

Streaming in .NET

Claude supports server-sent events for token-by-token streaming. In .NET this means reading the response stream line by line rather than awaiting a full JSON body:

var request = new HttpRequestMessage(HttpMethod.Post, "v1/messages")
{
    Content = JsonContent.Create(new { model = "claude-3-5-sonnet-20241022", max_tokens = 1024,
        stream = true, messages = new[] { new { role = "user", content = "Count to five." } } })
};

using var response = await _http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
using var stream = await response.Content.ReadAsStreamAsync();
using var reader = new StreamReader(stream);

while (!reader.EndOfStream)
{
    var line = await reader.ReadLineAsync();
    if (line?.StartsWith("data: ") == true)
        Console.Write(line["data: ".Length..]);
}

This pattern works identically whether you're pointed at Anthropic's endpoint directly or at SubToAPI's /v1/messages with streaming enabled.

Getting Started

If you want to skip Anthropic console setup, per-project billing headaches, and build a .NET integration against a single stable API key, sign up for a free trial and check /pricing for Solo, Team, and Scale plans.

Questions

Is there an official Claude .NET NuGet package? No. Anthropic maintains official SDKs for Python and JavaScript/TypeScript only. .NET developers call the REST API directly with HttpClient, which is straightforward since the API is plain JSON over HTTPS.

Can I use dependency injection with a Claude client in ASP.NET Core? Yes. Register your wrapper class with AddHttpClient<T>() in Program.cs, configure the base address and auth header once, and inject the typed client into controllers or services as needed.

Do I need to handle streaming differently in .NET than in Python or JS? The protocol is the same server-sent-events format, but in .NET you read the response body as a raw stream with StreamReader and parse data: lines manually, since there's no built-in SDK helper to do it for you.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →