# .NET SDK

> Official SfwApi package for .NET 8 and .NET Standard 2.0: analyze URLs, files, streams and bytes with typed results, typed errors and retries that honour Retry-After.

Rendered page: https://sfwapi.dev/docs/sdks/dotnet · All docs in one file: https://sfwapi.dev/llms-full.txt

```bash
dotnet add package SfwApi
```

```csharp
using SfwApi;

using var api = new SfwApiClient(Environment.GetEnvironmentVariable("SFWAPI_API_KEY")!);

try
{
    var r = await api.AnalyzeUrlAsync("https://example.com/photo.jpg", new AnalyzeOptions
    {
        Policy = new Policy { BlockLevel = NudityLevel.ImpliedNudity, BlockSexObjects = true },
    });
    Console.WriteLine($"{r.Nudity.Level} blocked={r.Policy?.Blocked}");
}
catch (SfwApiException e)
{
    Console.Error.WriteLine($"{e.Status} {e.Code} {e.ApiMessage} {e.RequestId}");
}

// uploads
var g = await api.AnalyzeFileAsync("clip.gif", new AnalyzeOptions { MaxFrames = 5, IncludeFrames = true });
```

Methods: `AnalyzeUrlAsync`, `AnalyzeFileAsync`, `AnalyzeBytesAsync`, `AnalyzeStreamAsync`, `AnalyzeBase64Async`, `GetAccountAsync`, `GetUsageAsync`. Options: `MaxFrames`, `IncludeFrames`, `Policy`; every method takes a `CancellationToken`. 429/503/504 are retried twice honouring `Retry-After` (not uploads); set `MaxRetries = 0` in `SfwApiClientOptions` to disable.

The client is thread-safe, so create one and reuse it. In ASP.NET Core, pass an `HttpClient` from `IHttpClientFactory` to the second constructor:

```csharp
builder.Services.AddHttpClient("sfwapi");
builder.Services.AddSingleton(services => new SfwApiClient(
    services.GetRequiredService<IHttpClientFactory>().CreateClient("sfwapi"),
    builder.Configuration["SfwApi:Key"]!));
```

Levels are the `NudityLevel` enum (`Everyday`, `Revealing`, `ImpliedNudity`, `Explicit`); `SfwApiClient.LevelName(level)` gives the display name. Targets .NET 8 and .NET Standard 2.0, so it also runs on .NET Framework 4.6.2+ and Unity.
