Docs/SDKs/

Go SDK

Use Flagpool feature flags in Go applications

The official Go SDK for Flagpool. Evaluate feature flags locally with deterministic rollouts, advanced targeting, and automatic polling. Thread-safe with zero external dependencies.

Installation

go get github.com/flagpool/flagpool-sdk-go/flagpool

Requirements: Go 1.19+

Quick Start

package main

import (
    "fmt"
    "github.com/flagpool/flagpool-sdk-go/flagpool"
)

func main() {
    client := flagpool.NewClient(flagpool.ClientOptions{
        ProjectID:     "your-project-uuid",
        APIKey:        "your-api-key",
        DecryptionKey: "your-decryption-key",
        Context: flagpool.Context{
            "userId": "user-123",
            "email":  "alice@example.com",
            "plan":   "pro",
        },
    })

    if err := client.Init(); err != nil {
        panic(err)
    }
    defer client.Close()

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

    // String, number, or JSON flag
    buttonColor := client.GetValue("cta-button-color")
    fmt.Println(buttonColor)
}

Configuration

client := flagpool.NewClient(flagpool.ClientOptions{
    // Required
    ProjectID:     "your-project-uuid",
    APIKey:        "your-api-key",
    DecryptionKey: "your-decryption-key",

    // Optional
    Context: flagpool.Context{
        "userId": "user-123",
        "email":  "user@example.com",
        "plan":   "pro",
    },
    PollingInterval: 30, // Auto-refresh interval in seconds (default: 30)
    URLOverride:     "", // Complete URL override (for self-hosted/testing)
})
OptionTypeRequiredDescription
ProjectIDstringYesProject UUID from the dashboard
APIKeystringYesEnvironment-specific API key
DecryptionKeystringYesFor CDN URL hashing and target list decryption
ContextContextNoUser context for targeting rules
PollingIntervalintNoPolling interval in seconds (default: 30)
URLOverridestringNoComplete URL override for self-hosted setups
Analytics*AnalyticsConfigNoAnalytics configuration (opt-in)

API Reference

MethodDescription
Init()Initialize client and fetch flags (required before evaluation)
IsEnabled(key)Check if a boolean flag is enabled
GetValue(key)Get flag value (any type, returned as interface{})
GetVariation(key)Alias for GetValue
GetAllFlags()Get all evaluated flag values as a map
UpdateContext(ctx)Update user context — flags re-evaluate automatically
OnChange(callback)Subscribe to flag value changes
Close()Stop polling and clean up resources

Flag Types

Boolean Flags

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

String Flags

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

Number Flags

limit := client.GetValue("rate-limit").(float64)
// 100 | 1000 | 10000

JSON Flags

config := client.GetValue("checkout-config").(map[string]interface{})
// map[string]interface{}{"showCoupons": true, "maxItems": 50, ...}

Dynamic Context Updates

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

fmt.Println(client.GetValue("max-upload-size-mb")) // 10

client.UpdateContext(flagpool.Context{"plan": "pro"})

fmt.Println(client.GetValue("max-upload-size-mb")) // 100

Real-Time Updates

Flags automatically refresh in the background. Listen for changes:

client.OnChange(func(flagKey string, newValue interface{}) {
    fmt.Printf("Flag %s changed to: %v\n", flagKey, newValue)
})

Thread Safety

The Client is fully thread-safe. You can safely call GetValue(), IsEnabled(), and other methods from multiple goroutines.

Framework Examples

net/http

package main

import (
    "net/http"
    "github.com/flagpool/flagpool-sdk-go/flagpool"
)

var client *flagpool.Client

func main() {
    client = flagpool.NewClient(flagpool.ClientOptions{
        ProjectID:     "your-project-uuid",
        APIKey:        "your-api-key",
        DecryptionKey: "your-decryption-key",
    })
    client.Init()
    defer client.Close()

    http.HandleFunc("/api/data", handleData)
    http.ListenAndServe(":8080", nil)
}

func handleData(w http.ResponseWriter, r *http.Request) {
    userID := r.Header.Get("X-User-ID")
    client.UpdateContext(flagpool.Context{"userId": userID})

    if client.IsEnabled("new-api-response") {
        // Return new response format
    }
}

Gin

flags := flagpool.NewClient(flagpool.ClientOptions{
    ProjectID:     "your-project-uuid",
    APIKey:        "your-api-key",
    DecryptionKey: "your-decryption-key",
})
flags.Init()
defer flags.Close()

r := gin.Default()

r.GET("/dashboard", func(c *gin.Context) {
    userID := c.GetHeader("X-User-ID")
    flags.UpdateContext(flagpool.Context{"userId": userID})

    if flags.IsEnabled("new-dashboard") {
        c.JSON(200, gin.H{"version": "v2"})
        return
    }
    c.JSON(200, gin.H{"version": "v1"})
})

Analytics

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

client := flagpool.NewClient(flagpool.ClientOptions{
    // ...required options
    Analytics: &flagpool.AnalyticsConfig{
        Enabled:        true,
        FlushThreshold: 100,
        SampleRate:     1.0,
    },
})
OptionTypeDefaultDescription
EnabledboolfalseEnable/disable analytics
FlushIntervaltime.Duration60sFlush interval (minimum: 30s)
FlushThresholdint100Flush after N evaluations
SampleRatefloat641.0Sample rate (0.0–1.0)
SyncFlushOnShutdownboolfalseFlush synchronously on SIGTERM/SIGINT

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