Oppex.Integration.Sdk 1.0.0

Prefix Reserved
dotnet add package Oppex.Integration.Sdk --version 1.0.0
                    
NuGet\Install-Package Oppex.Integration.Sdk -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Oppex.Integration.Sdk" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Oppex.Integration.Sdk" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Oppex.Integration.Sdk" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Oppex.Integration.Sdk --version 1.0.0
                    
#r "nuget: Oppex.Integration.Sdk, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Oppex.Integration.Sdk@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Oppex.Integration.Sdk&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Oppex.Integration.Sdk&version=1.0.0
                    
Install as a Cake Tool

Oppex .NET SDK

A .NET client for posting incidents to Oppex.

POST https://api.oppex.ai/api/v1/incident/post

Requirements

.NET 10 or newer. This SDK targets the current stable .NET release only, and its target framework moves forward with it. The only dependency is Microsoft.Extensions.Logging.Abstractions.

Install

dotnet add package Oppex.Integration.Sdk

Usage

Create one client per application, share it across threads, and dispose it during shutdown.

using Oppex.Integration.Sdk;

await using var client = new IncidentClient(new IncidentClientOptions
{
    ApiKey = Environment.GetEnvironmentVariable("OPPEX_API_KEY")!,
    ServiceKey = Environment.GetEnvironmentVariable("OPPEX_SERVICE_KEY"),
});

var response = await client.PostAsync(new IncidentRequest
{
    Title = "Checkout latency breached the SLO",
    Source = "checkout-api",
    Severity = Severity.High,
    Details = """{"p99Millis":1200}""",
});

Console.WriteLine(response.IncidentId);

Title, Source and Severity are required. Every other property is optional, and an absent optional property is left out of the payload rather than sent as null. A property that is present but blank is rejected, because that is nearly always a bug at the call site. Priority defaults to 1 and SrcTimestamp defaults to the current time in milliseconds since the Unix epoch.

IncidentRequest is a record, so a caller can derive one request from another with with.

Service routing

The service key is optional. A client built with only an ApiKey posts with PostWithServiceRoutingAsync, which omits serviceKey so Oppex resolves the target service itself. The request must not carry its own service key in that case.

A request's own ServiceKey overrides the client's.

Fire and forget

Enqueue and EnqueueWithServiceRouting queue a best-effort delivery and return immediately. They are deliberately not named PostAsync: in .NET that suffix promises an awaitable, and these are not. Validation and the disposed check still run on the calling thread, so a misuse is thrown to you rather than lost in a worker. A delivery failure after queueing is logged at debug level.

client.Enqueue(request);

Errors

Situation Thrown
Invalid options or request ArgumentException
Any post after disposal ObjectDisposedException
Delivery failure IncidentException
try
{
    await client.PostAsync(request);
}
catch (IncidentException failure) when (failure.StatusCode == 401)
{
    // Bad credentials, not a transient failure.
}

IncidentException.StatusCode is IncidentException.NoStatusCode (-1) when the delivery never reached a status line; HasHttpStatus answers that directly.

Severity

Severity.Lowest (1) through Severity.Critical (5). The enum values are the wire values, so casting to int is the conversion.

Logging

Pass any ILogger as IncidentClientOptions.Logger:

new IncidentClientOptions { ApiKey = key, Logger = loggerFactory.CreateLogger<IncidentClient>() }

The default is NullLogger.Instance, so the SDK never writes anywhere the host did not ask for.

Delivery behavior

  • 3 second connect timeout, 5 second response timeout, 8 second attempt budget.
  • HTTP 429, 500, 502, 503 and 504, plus failures that never reached a status line, retry after 0.5s, 1s, 2s, 4s and 8s. Every other status fails immediately.
  • Queued delivery is best effort through a channel bounded at 5000 that drops the oldest entry under saturation. Drops are counted and summarized at most once a minute.
  • Disposal drains for up to 10 seconds, then cancels whatever is still running.

None of these are configurable. They are part of the incident contract every Oppex SDK shares, not per-caller settings.

Trimming and native AOT

The assembly is marked IsAotCompatible. JSON is written and read through Utf8JsonWriter and JsonDocument, and logging goes through source-generated LoggerMessage delegates, so nothing here uses reflection or dynamic code. A consumer can trim or publish ahead-of-time without this SDK being the reason they cannot.

Build and test

cd dotnet
dotnet build Oppex.Integration.Sdk.slnx -c Release
dotnet test  Oppex.Integration.Sdk.slnx -c Release

Warnings are errors, and the .NET analyzers run as part of the build. Integration tests run against a loopback HttpListener, so the suite is network-free beyond loopback and never reaches the real Oppex service.

Release

Tag dotnet-vX.Y.Z. The release workflow packs the library, verifies that exact .nupkg against an external consumer, and pushes the same file to NuGet without rebuilding.

git tag dotnet-v1.0.0
git push origin dotnet-v1.0.0

The tag's version must match <Version> in the csproj; the workflow fails if it does not.

License

Apache License 2.0.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 96 9/25/2026