Docs/SDKs/

C# / .NET SDK

Use Flagpool feature flags in C# and .NET applications

The official C# SDK for Flagpool. Evaluate feature flags locally with deterministic rollouts, encrypted target lists, and automatic polling. Supports .NET 6.0, 8.0, and 10.0.

Installation

dotnet add package Flagpool.Sdk

Requirements: .NET 6.0 or later

Quick Start

using Flagpool.Sdk;

var client = new FlagpoolClient(new FlagpoolClientOptions
{
    ProjectId = "your-project-uuid",
    ApiKey = "your-api-key",
    DecryptionKey = "your-decryption-key",
    Context = new Dictionary<string, object?>
    {
        ["userId"] = "user-123",
        ["email"] = "alice@example.com",
        ["plan"] = "pro",
    },
});

await client.InitAsync();

// Boolean flag
if (client.IsEnabled("new-dashboard"))
{
    ShowNewDashboard();
}

// String, number, or JSON flag
var theme = client.GetValue("theme-color"); // "blue", "dark", etc.

// Clean up when done
client.Dispose();

Configuration

var client = new FlagpoolClient(new FlagpoolClientOptions
{
    // Required
    ProjectId = "your-project-uuid",
    ApiKey = "your-api-key",
    DecryptionKey = "your-decryption-key",

    // Optional
    Context = new Dictionary<string, object?>
    {
        ["userId"] = "user-123",
    },
    PollingIntervalMs = 30000,  // Polling interval in ms (default: 30000)
    Streaming = true,           // Enable polling for real-time updates
    UrlOverride = null,         // Override CDN URL (for testing)

    // Analytics (opt-in)
    Analytics = new AnalyticsConfig
    {
        Enabled = true,
        FlushIntervalMs = 60000,
        FlushThreshold = 100,
        SampleRate = 1.0,
    },
});
OptionTypeRequiredDescription
ProjectIdstringYesProject UUID from the dashboard
ApiKeystringYesEnvironment-specific API key
DecryptionKeystringYesFor CDN URL hashing and target list decryption
ContextDictionaryNoUser context for targeting rules
PollingIntervalMsintNoPolling interval in ms (default: 30000)
StreamingboolNoEnable polling for real-time updates
UrlOverridestringNoComplete URL override for self-hosted setups
AnalyticsAnalyticsConfigNoAnalytics configuration (opt-in)

API Reference

MethodDescription
InitAsync()Initialize client and fetch flags (required before evaluation)
IsEnabled(key, defaultValue?)Check if a boolean flag is enabled
GetValue(key)Get flag value (any type, returned as object?)
GetVariation(key)Alias for GetValue
GetAllFlags()Get all evaluated flag values as a dictionary
UpdateContext(ctx)Update user context — flags re-evaluate automatically
OnChange(callback)Subscribe to flag value changes; returns an unsubscribe action
Close()Stop polling (keeps analytics running)
Dispose()Full teardown — stops polling and flushes analytics

Flag Types

Boolean Flags

if (client.IsEnabled("feature-flag"))
{
    // Feature is enabled for this user
}

// With explicit default
bool enabled = client.IsEnabled("missing-flag", false); // false

String Flags

var variant = client.GetValue("button-color") as string;
// "blue" | "green" | "orange"

Number Flags

var limit = client.GetValue("rate-limit");
// 100 | 1000 | 10000

JSON Flags

var config = client.GetValue("checkout-config");
// Returns a deserialized object

Dynamic Context Updates

Update user context on the fly — flags re-evaluate automatically:

// User on free plan
Console.WriteLine(client.GetValue("max-upload-size-mb")); // 10

// User upgrades to pro
client.UpdateContext(new Dictionary<string, object?>
{
    ["plan"] = "pro",
});

// Instantly gets pro limits
Console.WriteLine(client.GetValue("max-upload-size-mb")); // 100

Real-Time Updates

Enable polling and listen for changes:

var unsubscribe = client.OnChange((flagKey, newValue) =>
{
    Console.WriteLine($"Flag changed: {flagKey} = {newValue}");
});

// Later: stop listening
unsubscribe();

Missing Flags

Accessing a flag that doesn't exist is safe and never throws:

client.IsEnabled("nonexistent");   // false
client.GetValue("nonexistent");    // null

Framework Examples

ASP.NET Core

// Program.cs
var flagpool = new FlagpoolClient(new FlagpoolClientOptions
{
    ProjectId = builder.Configuration["Flagpool:ProjectId"]!,
    ApiKey = builder.Configuration["Flagpool:ApiKey"]!,
    DecryptionKey = builder.Configuration["Flagpool:DecryptionKey"]!,
    Streaming = true,
});
await flagpool.InitAsync();

builder.Services.AddSingleton(flagpool);
// In a controller
public class FeatureController : ControllerBase
{
    private readonly FlagpoolClient _flags;

    public FeatureController(FlagpoolClient flags) => _flags = flags;

    [HttpGet("dashboard")]
    public IActionResult GetDashboard()
    {
        _flags.UpdateContext(new Dictionary<string, object?>
        {
            ["userId"] = User.FindFirst("sub")?.Value,
        });

        if (_flags.IsEnabled("new-dashboard"))
            return Ok(new { version = "v2" });

        return Ok(new { version = "v1" });
    }
}

Lifecycle

// Stop polling (keeps analytics running)
client.Close();

// Full teardown (stops polling + flushes analytics)
client.Dispose();

// Or use 'using' statement for automatic cleanup
using var client = new FlagpoolClient(options);
await client.InitAsync();
// Automatically disposed at end of scope

Analytics

Track flag evaluation counts. Analytics is opt-in and disabled by default.

var client = new FlagpoolClient(new FlagpoolClientOptions
{
    // ...required options
    Analytics = new AnalyticsConfig
    {
        Enabled = true,
        FlushIntervalMs = 60000,
        FlushThreshold = 100,
        SampleRate = 1.0,
    },
});
OptionTypeDefaultDescription
EnabledboolfalseEnable/disable analytics
FlushIntervalMsint60000Flush interval in ms (minimum: 30000)
FlushThresholdint100Flush after N evaluations
SampleRatedouble1.0Sample rate (0.0–1.0)

Supported Platforms

FrameworkStatus
.NET 6.0Supported
.NET 8.0Supported
.NET 10.0Supported

Targeting Operators

OperatorDescriptionExample
eqEqualsplan == "enterprise"
neqNot equalsplan != "free"
inIn listcountry in ["US", "CA"]
ninNot in listcountry not in ["CN", "RU"]
containsString containsemail contains "@company.com"
startsWithString starts withuserId startsWith "admin-"
inTargetListIn target listuserId in beta-testers
notInTargetListNot in target listuserId not in blocked-users

Next Steps

Start Managing Feature Flags Today

Join teams who trust Flagpool to deliver features safely and efficiently.

No credit card required • Cancel anytime