.NET SDK — install and configure
The .NET client SDK embeds Oclavex into your application: it activates a license, tells you what the current license permits, and reports what gets used. Everything it does is also available over the REST API — the SDK is the convenience layer for .NET.
Install
Section titled “Install”The SDK ships as NuGet packages. Most applications need these:
dotnet add package Revenusion.MonetizeIt.Client.LicenseConsumerdotnet add package Revenusion.MonetizeIt.Client.LicenseConsumer.Connecteddotnet add package Revenusion.MonetizeIt.Client.AspNetCoreClient.LicenseConsumer— the licensing engine (activation, validation, usage). Targetsnetstandard2.0, so it runs on .NET Framework, .NET 8+, MAUI, and Unity.Client.LicenseConsumer.Connected— the online add-on: HTTP transport, background license refresh and usage upload. Any application that activates over the network needs it; it pulls in itsClient.Provisioning(API wrappers) andHttpConnector(transport) dependencies for you.Client.AspNetCore— dependency-injection wiring, the authenticated HTTP client, and the background usage reporter for host-based apps.
For disconnected devices, add Client.OfflineStore.
Configure
Section titled “Configure”Two configuration sections drive the SDK. Oclavex:Tenant says which tenant to
talk to; Oclavex:LicenseConsumer says how licenses behave on this machine.
{ "Oclavex": { "Tenant": { "HostName": "example.com", "TenantName": "acme" }, "LicenseConsumer": { "LicenseKey": "the-license-key-for-this-install", "PublicKey": "<base64 provider public key>", "License": { "AllowUnsignedLicenses": false }, "Scheduler": { "UsageReportingIntervalSeconds": 60, "LicenseRefreshIntervalSeconds": 300 } } }}HostName + TenantName resolve to your tenant endpoint (https://acme.example.com);
LicenseKey is what this install activates. A shipped app needs nothing more — the
activation endpoints are anonymous, so it carries no
API client of its own.
Register
Section titled “Register”builder.Services .AddMonetizeItHttpClientWithAuthentication(builder.Configuration) .AddMonetizeItLicenseConsumer(builder.Configuration);AddMonetizeItLicenseConsumer registers ILicenseSession (scoped) as the entry point
your code uses. AddMonetizeItHttpClientWithAuthentication gives it an HTTP client pointed
at your tenant — anonymous by default, or authenticating with the client credentials when
you configure them.
The provider key is mandatory
Section titled “The provider key is mandatory”Licenses are signed by the provider. The SDK verifies that signature with the provider’s
public key, so a tampered or forged license is rejected. Obtain the key once from the
admin API — GET /api/v1/provision/admin/providers/license-signing-key — and set it as
Oclavex:LicenseConsumer:PublicKey.
If no key is configured, the SDK refuses to start rather than silently trusting
unverified licenses — a licensing runtime that fails open is not enforcing anything. The
only opt-out is License:AllowUnsignedLicenses = true, intended for
transport-authenticated test setups, never production.
Pinning more than one key, for rotation without downtime
Section titled “Pinning more than one key, for rotation without downtime”UsePublicKey has a second overload that pins a key by the id it’s published
under, and you can call it more than once to pin a set:
.UsePublicKey("provider_a1b2c3...", currentKeyBase64).UsePublicKey("provider_d4e5f6...", nextKeyBase64)A license is verified against whichever key its own key_id names; one naming a
key you haven’t pinned is rejected rather than falling back to some other key you
happened to pin. That’s what makes rotating the provider’s signing key a
non-event for deployed clients — see
rotating the signing key
for the publish → pin both → promote → retire sequence. The single-key overload
above still works unchanged; a bare pinned key verifies a license carrying
any key_id, so applications built before key rotation existed keep working,
no code change.
Single-tenant vs. multi-tenant
Section titled “Single-tenant vs. multi-tenant”A single-install application sets LicenseKey (and optionally NodeId) in
configuration. An application that serves many customer tenants from one process supplies
the license key per request instead: register your own scoped ILicenseKeyProvider
before calling AddMonetizeItLicenseConsumer, and resolve the key from the current
request’s tenant.
builder.Services.AddScoped<ILicenseKeyProvider>(sp => StaticLicenseKeyProvider.Create(CurrentTenant.LicenseKey));The same pattern applies to INodeIdProvider when each tenant needs a distinct device
identity. See device fingerprints.
Without a host: the fluent builder
Section titled “Without a host: the fluent builder”Desktop and plain-.NET applications that don’t run a generic host build the client
directly. LicenseClientBuilder assembles it from small parts — what identifies the
license, what identifies the device, where to cache, and how to talk to the API:
using Revenusion.MonetizeIt.Client.LicenseConsumer;using Revenusion.MonetizeIt.Client.AspNetCore;using Revenusion.MonetizeIt.HttpConnector;
// The transport the builder needs. Activation is anonymous — the license token the// server returns is what authenticates every call after it. Treat this as a singleton:// each call allocates a fresh HttpClient.var httpClient = MonetizeItClientFactory.Create( $"https://{tenantName}.{hostName}", new AnonymousAuthentication());
var client = new LicenseClientBuilder() .UseMonetizeItHttpClient(httpClient) // points at your API base URL .UseLicenseKey(StaticLicenseKeyProvider.Create(code)) // the activation code .UseNodeId(new DeviceIdDeviceFingerprint()) // the device fingerprint .UsePublicKey(base64PublicKey) // pin the signing key .UseLicenseStoreBuilder() // cache the license on disk .UseSystemInfo() // report OS/app diagnostics .Build();
var session = client.Session;Build() returns an ILicenseClient: it owns the background schedulers (usage
upload, scheduled reporting), exposes the Session, and is IDisposable — keep
it for the application’s lifetime and dispose it on shutdown. Call FlushAsync()
to push pending usage before exit. BuildSession() is a shortcut when you only
want the ILicenseSession.
Two more builder calls appear in most real integrations: WithOptions(...)
applies a LicenseConsumerOptions instance — scheduler intervals, license
behavior — without a configuration host, and
UseApplicationInfo(RuntimeApplicationInfo.Create(...)) reports your
application’s identity and version explicitly. UseSystemInfo, shown above, is
separate: it collects OS and runtime details for usage reports, and takes an
optional lambda that selects what is collected.
Add UseLoggerFactory(loggerFactory) — without it the client logs nowhere, and an
activation failure (revoked key, 401, network error) is undiagnosable beyond the
LastError on the session.
The provider key requirement applies here too:
the builder refuses to build unless you pin the public key with UsePublicKey or
explicitly opt out via LicenseConfiguration.AllowUnsignedLicenses.
From here on, everything is identical to the hosted path — the same
ILicenseSession, the same activation,
entitlement checks and
usage reporting.
Lower-level API wrappers
Section titled “Lower-level API wrappers”If you want thin HTTP wrappers instead of the full consumer,
Revenusion.MonetizeIt.Client.Provisioning exposes them directly:
LicenseActivationApi—FetchJwtByActivationCodeAsync,FetchLicenseAsync,RenewLicenseAsync,CheckInAsync,CheckOutAsync.UsageApi—ProcessTransactionsForSessionAsync,ProcessTransactionsForEntitlementAsync,TryConsumeAsync,TryPreAllocateAsync,AssetConsumptionAsync,AssetUsageAsync,GetRatingPromptAsync.TryConsumeAsynctakes an optionalidempotentKey— a retried commit with the same key returns the original decision instead of consuming twice.
They map one-to-one onto the REST endpoints and share the authentication providers.