Skip to main content

Overview

In this quickstart, you’ll add Fingerprint to a C# ASP.NET Core server using ASP.NET APIs to prevent fraudulent account creation. The example use case in this quickstart is stopping new account fraud, where attackers create multiple fake accounts to abuse promotions, exploit systems, or evade bans. However, the steps you’ll follow apply to most use cases. You can flag and block suspicious users by identifying the device behind each sign-up attempt, login, or transaction. In this quickstart, you’ll learn how to:
  • Set up a ASP.NET Core API server with a Fingerprint integration
  • Retrieve visitor identification data using the Server API
  • Block bots and suspicious devices
  • Prevent multiple signups from the same device
This guide focuses on the backend integration and must be completed after identifying a visitor and generating a request ID. Before starting this quickstart, start with one of the frontend or mobile quickstarts to see how to identify a visitor in your frontend.
Estimated time: < 10 minutes

Prerequisites

Before you begin, make sure you have the following:
  • A completed frontend or mobile Fingerprint implementation (See the quickstarts)
  • .NET SDK (.NET 8.0 or later)
  • Your favorite code editor
  • Basic knowledge of C# and .NET

1. Get your secret API key

Before starting this quickstart, you should already have a frontend Fingerprint implementation that sends the event_id to your server. If not, pause here and check out one of our frontend or mobile quickstarts first.
If you’re ready:
  1. Sign in and go to the API keys page in the Fingerprint dashboard.
  2. Create a new secret API key.
  3. Copy it somewhere safe so you can use it to retrieve full visitor identification data from the Server API.

2. Set up your project

To get started, set up a basic server. If you already have a project you want to use, you can skip to the next section.
  1. Create a new ASP.NET project and add the Fingerprint .NET Server SDK:
Terminal
dotnet new web -o fingerprint-dotnet-quickstart -f net9.0
cd fingerprint-dotnet-quickstart
dotnet add package Fingerprint.ServerSdk
Note: This quickstart is written for version 8.x of the Fingerprint .NET Server SDK
  1. The dotnet new web command creates a starter Program.cs file. Replace the entire contents of Program.cs with the following code:
Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseUrls("http://localhost:3000");

var app = builder.Build();

app.MapPost("/api/create-account", () => Results.Ok("{ status: \"Account created!\" }"));

app.Run();
Here we are running the server at port 3000 and have created a new POST route for account creation. Note that the /api/create-account route should match what you have set up in your frontend implementation where you are sending the Fingerprint event_id to your server. Your server will receive the initial identification information from identifying a visitor on the frontend and use it to get the full visitor data on the backend.

3. Initialize Fingerprint and retrieve visitor data

Now you’ll configure the Fingerprint .NET Server SDK using your secret API key and use it to fetch detailed visitor data for each signup attempt. When making the initial visitor identification request in the frontend, you received an event_id. This ID is unique to each identification event. Your server can then use the Fingerprint Events API to retrieve complete identification data, including the trusted visitor ID and other actionable insights like whether they are using a VPN or are a bot.
  1. At the top of your Program.cs file, import and initialize the SDK with your secret API key just after the builder object is constructed:
Program.cs
using Fingerprint.ServerSdk.Api;
using Fingerprint.ServerSdk.Extensions;
using Fingerprint.ServerSdk.Client;
using Fingerprint.ServerSdk.Model;

...

builder.Services.AddFingerprint(options =>
{
    options.AddTokens(new BearerToken("<your-secret-api-key>")); // Replace with your actual secret key
    // Uncomment and change if necessary:
    // options.Region = Region.Eu;
});
For a production implementation make sure to store and reference your secret key securely.
  1. In your /api/create-account route, retrieve the event_id you are sending from the frontend and fetch the full visitor identification details with GetEventAsync():
requestId vs event_id: Depending on which quickstart you completed, your frontend may send either requestId (older SDKs) or event_id (v4 and newer). Both refer to the same identification event and work with the Server API in the same way. Use whichever value your frontend sends (requestId or event_id) as the eventId you pass to GetEventAsync() below.
Program.cs
app.MapPost("/api/create-account", async (CreateAccountRequest request, IFingerprintApi api) =>
{
    var getEvent = await api.GetEventAsync(request.EventId);
    return Results.Ok("{ status: \"Account created!\" }");
});
  1. Add the declaration of CreateAccountRequest to the bottom of Program.cs:
Program.cs
public record CreateAccountRequest(string EventId, string Username, string Password);
Using the eventId the Fingerprint server client will retrieve the full data for the visitor identification request. The returned object will contain the visitor ID, IP address, device and browser details, and Smart Signals like bot detection, incognito mode detection, and detections for VPN or virtual machine use. You can see a full example of the event structure, and test it with your own device, in the demo playground. For additional checks to ensure the validity of the data coming from your frontend view how to protect from client-side tampering and replay attacks.

4. Block bots and suspicious devices

This optional step uses the Bot Detection Smart Signal which is available only on paid plans.
A simple but powerful way to prevent fraudulent account creation is to block automated signups that come from bots. The event object includes the Bot Detection Smart Signal that flags automated activity, making it easy to reject bot traffic.
  1. Continuing in your /api/create-account route, after getting getEvent, check the operation status:
Program.cs
if (!getEvent.TryOk(out var result))
{
    return Results.InternalServerError("{ status: \"Internal server error!\" }");
}
Now we can check the bot signal returned in the object:
Program.cs
if (result.Bot != BotResult.NotDetected)
{
    return Results.Problem("{ error: \"Failed to create account.\" }", statusCode: 403);
}
This signal returns BotResult.Good for known bots like search engine crawlers, BotResult.Bad for automation tools, headless browsers, or other signs of automation, and BotResult.NotDetected when no bot activity is found. You can also layer in other Smart Signals to catch more suspicious devices. For example, you can use Fingerprint’s Suspect Score to determine when to add additional friction to create an account.

5. Prevent multiple signups from the same device

To catch repeated signups from the same device, you can use the visitorId from the Fingerprint identification event. By saving this ID alongside each created account, you can detect and block duplicate signups from the same device. We’ll be using a simple database to demonstrate how this works with SQLite.
  1. Install the SQLite package:
Terminal
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
  1. At the top of your Program.cs file, import and initialize the database:
Program.cs
using Microsoft.Data.Sqlite;
var connectionString = "Data Source=database.db";
using var connection = new SqliteConnection(connectionString);
connection.Open();

var command = connection.CreateCommand();
command.CommandText = @"
    CREATE TABLE IF NOT EXISTS accounts (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        username TEXT,
        password TEXT,
        visitorId TEXT
    )";
command.ExecuteNonQuery();

  1. In your /api/create-account route handler, after getting the event and the bot detection code, extract the visitorId:
Program.cs
var visitorId = result.Identification.VisitorId;
  1. Then check if this device (visitor ID) has already created an account; if yes, block the account creation:
Program.cs
using var checkConnection = new SqliteConnection(connectionString);
checkConnection.Open();

var checkCommand = checkConnection.CreateCommand();
checkCommand.CommandText = "SELECT COUNT(*) FROM accounts WHERE visitorId = @visitorId";
checkCommand.Parameters.AddWithValue("@visitorId", visitorId);

var count = (long?)checkCommand.ExecuteScalar();

if (count.HasValue && count > 0)
{
    return Results.Problem("{ error: \"Failed to create account.\" }", statusCode: 429);
}

// Otherwise, insert the new account
var insertCommand = checkConnection.CreateCommand();
insertCommand.CommandText = "INSERT INTO accounts (username, password, visitorId) VALUES (@username, @password, @visitorId)";
insertCommand.Parameters.AddWithValue("@username", request.Username);
insertCommand.Parameters.AddWithValue("@password", request.Password);
insertCommand.Parameters.AddWithValue("@visitorId", visitorId);
insertCommand.ExecuteNonQuery();

This gives you a basic system to detect and block repeat signups. You can expand on this by allowing a limited number of accounts per device, adjusting your response based on business rules, only evaluating recent signups, etc.
This is a minimal example to show how to use the Fingerprint .NET Server SDK. In a real application, make sure to implement proper security practices, especially around password handling and storage.

6. Test your implementation

Now that everything is set up, you can test the full flow using your existing frontend.

Before you test

If your frontend is running on a different port (like localhost:5173 or localhost:3001), you may run into CORS issues for testing. To quickly fix this for local development & testing:
  1. Add the following lines in Program.cs, just after the builder object is constructed:
Program.cs
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy =>
    {
        policy.AllowAnyOrigin()
              .AllowAnyMethod()
              .AllowAnyHeader();
    });
});

var app = builder.Build(); // <- Existing code!
app.UseCors();

Test the implementation

  1. Start your ASP.NET server:
Terminal
dotnet run
  1. In your frontend, trigger a sign-up request that sends the event_id, username, and password to your /api/create-account endpoint. To see the reply messages make sure to parse and display or console log the response from your server.
  2. Within your frontend, input a username and password to create a user. Then try to create another user and see that the second attempt will be rejected.
  3. Bonus: Try creating an account using a headless browser.

Next steps

You now have a working backend fraud check using Fingerprint. From here, you can expand your logic with more Smart Signals, adjust thresholds based on your risk tolerance, or introduce additional checks for suspicious users. These same techniques apply to a wide range of fraud prevention use cases, from detecting fake reviews to blocking payment abuse or preventing account takeovers. To go further, check out the use case tutorials for step-by-step guides tailored to specific problems you can solve with Fingerprint. Check out these related resources: