Go SDK Reference
TL;DR: Run
go get github.com/canopy-labs/featureflip-go, callclient.BoolVariation("flag-key", ctx, false), and you’re evaluating flags from any Go service.
The featureflip Go package provides a goroutine-safe client for evaluating feature flags. It requires Go 1.25+, supports real-time updates via SSE streaming, and uses the standard library’s net/http for all network communication with no external dependencies.
Requirements
Section titled “Requirements”- Go 1.25+
Installation
Section titled “Installation”go get github.com/canopy-labs/featureflip-goImport in your code:
import "github.com/canopy-labs/featureflip-go"All public types and functions are in the featureflip package.
Configuration
Section titled “Configuration”The client uses the functional options pattern. All options have sensible defaults.
| Option | Default | Description |
|---|---|---|
WithBaseURL(url) | "https://eval.featureflip.io" | Base URL of the Evaluation API |
WithStreaming(bool) | true | Enable SSE for real-time flag updates |
WithPollInterval(d) | 30s | Polling interval (used when streaming is disabled) |
WithFlushInterval(d) | 30s | Interval between event flush batches |
WithFlushBatchSize(n) | 100 | Maximum number of events per flush batch |
WithInitTimeout(d) | 10s | Maximum time to wait for initial flag fetch |
WithConnectTimeout(d) | 5s | Timeout for establishing HTTP connections |
WithReadTimeout(d) | 10s | Timeout for reading HTTP responses |
Example configuration
Section titled “Example configuration”client, err := featureflip.Get("sdk-dev-abc123", featureflip.WithBaseURL("https://eval.featureflip.io"), featureflip.WithStreaming(true), featureflip.WithPollInterval(60 * time.Second), featureflip.WithFlushInterval(15 * time.Second), featureflip.WithInitTimeout(30 * time.Second),)Initialization
Section titled “Initialization”Create a client by calling Get with an SDK key and optional configuration:
client, err := featureflip.Get("sdk-dev-abc123")if err != nil { log.Fatalf("Failed to initialize: %v", err)}defer client.Close()Get blocks until the initial flag configuration is fetched (up to initTimeout). It returns an error if:
- The SDK key is empty and
FEATUREFLIP_SDK_KEYis not set - The initial flag fetch fails
- The initialization times out
SDK key resolution
Section titled “SDK key resolution”If the sdkKey parameter is empty, the client falls back to the FEATUREFLIP_SDK_KEY environment variable.
// SDK key read from FEATUREFLIP_SDK_KEY environment variableclient, err := featureflip.Get("")Initialized()
Section titled “Initialized()”ready := client.Initialized()Returns true once the client has successfully loaded flag data. Since Get blocks until initialization, this always returns true for a successfully created client.
Evaluating Flags
Section titled “Evaluating Flags”All evaluation methods accept a flag key, an evaluation context, and a default value. If the flag is not found or an error occurs, the default value is returned.
BoolVariation()
Section titled “BoolVariation()”ctx := featureflip.EvaluationContext{UserID: "u-123"}enabled := client.BoolVariation("dark-mode", ctx, false)Signature:
func (c *Client) BoolVariation(key string, ctx EvaluationContext, defaultValue bool) boolStringVariation()
Section titled “StringVariation()”plan := client.StringVariation("pricing-tier", ctx, "free")Signature:
func (c *Client) StringVariation(key string, ctx EvaluationContext, defaultValue string) stringFloat64Variation()
Section titled “Float64Variation()”limit := client.Float64Variation("rate-limit", ctx, 100.0)Signature:
func (c *Client) Float64Variation(key string, ctx EvaluationContext, defaultValue float64) float64Note: JSON numbers are always deserialized as float64 in Go. Use Float64Variation for all numeric flags.
JSONVariation()
Section titled “JSONVariation()”Returns the raw deserialized value for JSON flags:
config := client.JSONVariation("banner-config", ctx, map[string]any{ "text": "Welcome", "color": "#000",})Signature:
func (c *Client) JSONVariation(key string, ctx EvaluationContext, defaultValue any) anyThe returned value is the Go representation of the JSON value (maps, slices, strings, float64, bool, nil).
Evaluation Details
Section titled “Evaluation Details”VariationDetail()
Section titled “VariationDetail()”Returns an EvaluationDetail struct with the evaluated value and metadata about the decision.
detail := client.VariationDetail("dark-mode", ctx, false)
fmt.Println(detail.Value) // truefmt.Println(detail.Reason) // "RuleMatch"fmt.Println(detail.Variation) // "true-variation"fmt.Println(detail.RuleID) // "rule-abc"Signature:
func (c *Client) VariationDetail(key string, ctx EvaluationContext, defaultValue any) EvaluationDetailEvaluationDetail
Section titled “EvaluationDetail”type EvaluationDetail struct { Value any Variation string Reason EvaluationReason RuleID string}| Field | Type | Description |
|---|---|---|
Value | any | The evaluated flag value |
Variation | string | The key of the matched variation |
Reason | EvaluationReason | Why this value was returned |
RuleID | string | The ID of the matched targeting rule (empty if not applicable) |
EvaluationReason
Section titled “EvaluationReason”The EvaluationReason type is a string with the following constants:
| Constant | Value | Description |
|---|---|---|
ReasonRuleMatch | "RuleMatch" | A targeting rule matched the context |
ReasonFallthrough | "Fallthrough" | No rules matched; the fallthrough variation was served |
ReasonFlagDisabled | "FlagDisabled" | The flag is disabled; the off variation was served |
ReasonFlagNotFound | "FlagNotFound" | The flag key does not exist |
ReasonError | "Error" | An error occurred during evaluation |
Evaluation Context
Section titled “Evaluation Context”The EvaluationContext struct provides user attributes for flag evaluation. Custom attributes feed into targeting rules, and UserID anchors percentage rollouts:
ctx := featureflip.EvaluationContext{ UserID: "u-123", Attributes: map[string]any{ "country": "US", "plan": "pro", },}Fields
Section titled “Fields”| Field | Type | Description |
|---|---|---|
UserID | string | Unique user identifier, used for percentage rollouts |
Attributes | map[string]any | Custom attributes for targeting rules |
Event Tracking
Section titled “Event Tracking”Track()
Section titled “Track()”Records a custom analytics event.
metadata := map[string]any{ "plan": "pro", "amount": 29.99,}client.Track("purchase-completed", ctx, metadata)Signature:
func (c *Client) Track(eventKey string, ctx EvaluationContext, metadata map[string]any)Events are batched and flushed automatically based on WithFlushInterval and WithFlushBatchSize.
Identify()
Section titled “Identify()”Records an identify event for user association and analytics.
client.Identify(featureflip.EvaluationContext{ UserID: "u-123",})Signature:
func (c *Client) Identify(ctx EvaluationContext)Flush()
Section titled “Flush()”Forces all buffered events to be sent to the server immediately.
client.Flush()Cleanup
Section titled “Cleanup”Close()
Section titled “Close()”Shuts down the client, stops background goroutines (streaming or polling), and flushes remaining events. Returns nil (the error return is reserved for future use). Safe to call multiple times.
err := client.Close()Signature:
func (c *Client) Close() errorAlways defer Close() after creating a client:
client, err := featureflip.Get("sdk-key")if err != nil { log.Fatal(err)}defer client.Close()Testing
Section titled “Testing”ForTesting()
Section titled “ForTesting()”Creates a client pre-populated with flag overrides. No network calls or background goroutines are started.
client := featureflip.ForTesting(map[string]any{ "dark-mode": true, "pricing-tier": "enterprise", "rate-limit": 500.0,})defer client.Close()
ctx := featureflip.EvaluationContext{UserID: "test-user"}client.BoolVariation("dark-mode", ctx, false) // trueclient.StringVariation("pricing-tier", ctx, "free") // "enterprise"Signature:
func ForTesting(overrides map[string]any) *ClientSupported value types: bool, string, float64/int, and any JSON-serializable type. The client is fully initialized immediately and returns override values regardless of the evaluation context.
Types Summary
Section titled “Types Summary”| Type | Description |
|---|---|
Client | Main client for flag evaluation and event tracking |
Option | Functional option for configuring the client (func(*config)) |
EvaluationContext | User attributes for flag evaluation |
EvaluationDetail | Detailed result of a flag evaluation |
EvaluationReason | String type describing why a value was returned |
See also
Section titled “See also”- Go Quickstart — get started in under 5 minutes
- Targeting & Segments — control which users see which variation
- Rollout Strategies — gradual percentage-based rollouts
- Evaluation API — REST API reference
- SDK Overview — compare server-side and client-side SDKs