Skip to main content

How to install

Install the package from NuGet.
Bash
dotnet add package Fingerprint.ServerSdk
Initialize the client instance and use it to make API requests. You need to specify your secret API key and region (if it is not US/Global).
C#
using Fingerprint.ServerSdk.Api;
using Fingerprint.ServerSdk.Extensions;
using Fingerprint.ServerSdk.Client;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddFingerprint(options =>
{
    options.AddTokens(new BearerToken("SECRET-API-KEY"));
    // options.Region = Region.Eu;
});

var app = builder.Build();
var api = app.Services.GetRequiredService<IFingerprintApi>();

// Search events
var events = await api.SearchEventsAsync(new SearchEventsRequest().WithVisitorId("VISITOR_ID"));
Console.WriteLine(events.Ok());

// Get a specific identification event
var getEvent = await api.GetEventAsync("EVENT_ID");
Console.WriteLine(getEvent.Ok());

Migration guide for .NET SDK v8

Version 8 migrates the SDK from Server API v3 to v4. This is a breaking change. This section summarizes the most important changes from previous versions.

Package and namespace rename

The package name changed from FingerprintPro.ServerSdk to Fingerprint.ServerSdk, and all namespaces changed from FingerprintPro.ServerSdk.* to Fingerprint.ServerSdk.*.
Project.csproj
<PackageReference Include="FingerprintPro.ServerSdk" Version="7.11.0" />
<PackageReference Include="Fingerprint.ServerSdk" Version="8.4.0" />
C#
using FingerprintPro.ServerSdk.Api; 
using FingerprintPro.ServerSdk.Client; 
using FingerprintPro.ServerSdk.Model; 
using Fingerprint.ServerSdk.Api; 
using Fingerprint.ServerSdk.Client; 
using Fingerprint.ServerSdk.Model; 

Client construction

In v7, you created a Configuration object and passed it to a FingerprintApi constructor. In v8, you register a service on a generichost builder with AddFingerprint and resolve it as IFingerprintApi.
C#
var configuration = new Configuration("SECRET_API_KEY"); 
// configuration.Region = Region.Eu;
var api = new FingerprintApi(configuration); 
var builder = WebApplication.CreateBuilder(args); 
builder.Services.AddFingerprint(options =>
{ 
    options.AddTokens(new BearerToken("SECRET_API_KEY")); 
    // options.Region = Region.Eu;
}); 
var app = builder.Build(); 
var api = app.Services.GetRequiredService<IFingerprintApi>(); 

Async methods and response objects

All API methods are now asynchronous and return a response object instead of the deserialized model directly. Use IsOk and Ok() to access the result, or the TryOk helper.
C#
var ev = api.GetEvent("REQUEST_ID"); 
var response = await api.GetEventAsync("EVENT_ID"); 
if (response.IsOk) 
{ 
    var ev = response.Ok(); 
} 

requestId renamed to eventId

Server API v4 renamed the request_id parameter to event_id, so the identifier passed to GetEventAsync and UpdateEventAsync is now called eventId.
C#
var response = await api.GetEventAsync(requestId: "REQUEST_ID"); 
var response = await api.GetEventAsync(eventId: "EVENT_ID"); 

Event structure

GetEventAsync returns an Event with a flatter structure. The data that was previously nested under Products.<signal>.Data is now available at the top level.
C#
EventsGetResponse response = api.GetEvent("REQUEST_ID"); 
var visitorId = response.Products.Identification.Data.VisitorId; 
var botResult = response.Products.Botd.Data.Bot.Result; 
Event ev = (await api.GetEventAsync("EVENT_ID")).Ok(); 
var visitorId = ev.Identification.VisitorId; 
var botResult = ev.Bot; 

Search events

SearchEventsAsync takes a SearchEventsRequest builder instead of positional and named arguments.
C#
var response = api.SearchEvents(10, bot: "bad", visitorId: "VISITOR_ID"); 
var request = new SearchEventsRequest() 
    .WithLimit(10) 
    .WithBot(SearchEventsBot.Bad) 
    .WithVisitorId("VISITOR_ID"); 
var response = await api.SearchEventsAsync(request); 

GetVisits and GetRelatedVisitors removed

GetVisits and GetRelatedVisitors have been removed. Use SearchEventsAsync with WithVisitorId to get the events for a visitor.
C#
var visits = api.GetVisits("VISITOR_ID"); 
var request = new SearchEventsRequest().WithVisitorId("VISITOR_ID"); 
var response = await api.SearchEventsAsync(request); 

Handling sealed client results from a v3 JavaScript agent

.NET SDK v8 will fail to deserialize the decrypted payload of a sealed client result sent by a v3 JavaScript agent into an Event because the payload is an EventsGetResponse (i.e., the v3 event format), not an Event. To upgrade to .NET SDK v8 without requiring a concurrent upgrade to the v4 JavaScript agent, you can fall back to using the Server API if unsealing the sealed client results fails. To enable this fallback path, your frontend must send the event ID alongside the sealed client results, as recommended by the sealed client results guide. Instead of Sealed.UnsealEventResponse, which decrypts and deserializes in one call, use Sealed.Unseal to decrypt the payload and then deserialize it into an Event separately. This lets you detect a deserialization failure and fall back to the Server API, which also returns an Event.
C#
// Partial example (imports and surrounding class omitted).
private static async Task<Event> GetEvent(
    IFingerprintApi api,
    byte[] sealedResult,
    string eventId,
    Sealed.DecryptionKey[] keys)
{
    // First, decrypt the sealed results.
    var payload = Sealed.Unseal(sealedResult, keys);

    // Next, attempt to deserialize the payload into an event.
    try
    {
        var ev = JsonSerializer.Deserialize<Event>(payload);
        if (ev == null)
        {
            throw new JsonException("Deserialized event was null");
        }
        return ev;
    }
    catch (JsonException)
    {
        // The payload could not be deserialized as a v4 Event. Fall back to the
        // Server API using the event ID sent alongside the sealed client results.
        Console.WriteLine("Could not deserialize unsealed payload as a v4 Event, falling back to Server API");
        var response = await api.GetEventAsync(eventId);
        return response.Ok();
    }
}

Documentation

You can find the full documentation in the official GitHub repository.