
Official documentation for Amplitude Experiment's server-side Go SDK implementation.

This documentation is split into two sections for [remote](/docs/feature-experiment/remote-evaluation) and [local](/docs/feature-experiment/local-evaluation) evaluation:

## Remote evaluation

Implements fetching variants for a user through [remote evaluation](/docs/feature-experiment/remote-evaluation).

### Install

Install the Go Server SDK using `go get`.

```bash
go get github.com/amplitude/experiment-go-server
```

{% callout type="tip" heading="Quick start" %}

1. [Initialize the experiment client](#initialize)
2. [Fetch variants for the user](#fetch)
3. [Access a flag's variant](#fetch)

```go
// (1) Initialize the local evaluation client with a server deployment key.
client := remote.Initialize("<DEPLOYMENT_KEY>", nil)

// (2) Fetch variants for a user
user := &experiment.User{
  UserId:   "user@company.com",
  DeviceId: "abcdefg",
  UserProperties: map[string]interface{}{
    "premium": true,
  },
}
variants, err := client.Fetch(user)
if err != nil {
  // Handle error
}

// (3) Access a flag's variant
variant := variants["<FLAG_KEY>"]
if variant.Value == "on" {
    // Flag is on
} else {
    // Flag is off
}
```

{% /callout %}

### Initialize

Initialize the SDK client in your server on startup. The [deployment key](/docs/feature-experiment/data-model#deployments) argument you pass to the `apiKey` parameter must reside within the same project that you are sending analytics events to.

```go
func Initialize(apiKey string, config *Config) *Client
```

| Parameter | Requirement | Description                                                                                                                                               |
| --------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey`  | required    | The [deployment key](/docs/feature-experiment/data-model#deployments) that authorizes fetch requests and determines which flags to evaluate for the user. |
| `config`  | optional    | The client [configuration](#configuration) used to customize SDK client behavior.                                                                         |

```go
client := remote.Initialize("<DEPLOYMENT_KEY>", nil)
```

#### Configuration

Configure the SDK client upon initialization.

{% callout type="info" heading="EU data center" %}
If you're using Amplitude's EU data center, configure the `ServerZone` option on initialization.
{% /callout %}

| Name                                   | Description                                                                                                                                              | Default Value                                   |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `Debug`                                | Set to `true` to enable debug logging.                                                                                                                   | `false`                                         |
| `LogLevel`                             | The minimum log level to output. Options: `Verbose`, `Debug`, `Info`, `Warn`, `Error`, `Disable`. Go to [custom logging](#custom-logging).               | `Error`                                         |
| `LoggerProvider`                       | Custom logger implementation. Implement the `LoggerProvider` interface to integrate with your logging solution. Go to [custom logging](#custom-logging). | `defaultLoggerProvider` which outputs to stdout |
| `ServerZone`                           | The Amplitude data center to use. Either `USServerZone` or `EUServerZone`.                                                                               | `USServerZone`                                  |
| `ServerUrl`                            | The host to fetch flag configurations from.                                                                                                              | `https://api.lab.amplitude.com`                 |
| `FlagConfigPollingInterval`            | The timeout for fetching variants in milliseconds. This timeout only applies to the initial request, not subsequent retries                              | `500 * time.Millisecond`                        |
| `RetryBackoff.FetchRetries`            | The number of retries to attempt if a request to fetch variants fails.                                                                                   | `1`                                             |
| `RetryBackoff.FetchRetryBackoffMin`    | The minimum (initial) backoff after a request to fetch variants fails. The SDK scales this delay by the `RetryBackoff.FetchRetryBackoffScalar`           | `0`                                             |
| `RetryBackoff.FetchRetryBackoffMax`    | The maximum backoff between retries. If the scaled backoff becomes greater than the max, the SDK uses the max for all subsequent requests                | `10 * time.Second`                              |
| `RetryBackoff.FetchRetryBackoffScalar` | Scales the minimum backoff exponentially.                                                                                                                | `1`                                             |
| `RetryBackoff.FetchRetryTimeout`       | The request timeout for retrying variant fetches.                                                                                                        | `500 * time.Millisecond`                        |

### Fetch

Fetches variants for a [user](/docs/feature-experiment/data-model#users) and returns the results. The function [remote evaluates](/docs/feature-experiment/remote-evaluation) the user for flags associated with the deployment used to initialize the SDK client.

```go
func (c *Client) Fetch(user *experiment.User) (map[string]experiment.Variant, error)
```

| Parameter | Requirement | Description                                                                       |
| --------- | ----------- | --------------------------------------------------------------------------------- |
| `user`    | required    | The [user](/docs/feature-experiment/data-model#users) for whom to fetch variants. |

```go
user := &experiment.User{
    UserId:   "user@company.com",
    DeviceId: "abcdefg",
    UserProperties: map[string]interface{}{
        "premium": true,
    },
}
variants, err := client.Fetch(user)
if err != nil {
    // Handle error
}
```

After fetching variants for a user, you may to access the variant for a specific flag.

```go
variant := variants["<FLAG_KEY>"]
if variant.Value == "on" {
    // Flag is on
} else {
    // Flag is off
}
```

{% accordion title="Account-level bucketing and analysis (v1.7.0+)" %}
If your organization has purchased the [Accounts add-on](/docs/analytics/account-level-reporting) you may perform bucketing and analysis on groups rather than users. Reach out to your representative to gain access to this beta feature.

Groups must either be included in the user sent with the fetch request (recommended), or identified with the user through a group identify call from the [Group Identify API](/docs/apis/analytics/group-identify) or through [`setGroup()` from an analytics SDK](/docs/sdks/analytics/browser/browser-sdk-2#user-groups).

```go
user := &experiment.User{
    UserId:   "user@company.com",
    DeviceId: "abcdefg",
    UserProperties: map[string]interface{}{
        "premium": true,
    },
    Groups: map[string]interface{}(
      "org name": ["Amplitude"]
    )
}
variants, err := client.Fetch(user)
```

To pass freeform group properties, review this example:

```go
user := &experiment.User{
    UserId:   "user@company.com",
    DeviceId: "abcdefg",
    UserProperties: map[string]interface{}{
        "premium": true,
    },
    GroupsProperties: map[string]interface{}(
      "org name": ["Amplitude"]
    )
}
variants, err := client.Fetch(user)
```

{% /accordion %}

### Fetch V2 with options

Fetches variants for a [user](/docs/feature-experiment/data-model#users) with options and returns the results. The function [remote evaluates](/docs/feature-experiment/remote-evaluation) the user for flags associated with the deployment used to initialize the SDK client.

```go
func (c *Client) FetchV2WithOptions(user *experiment.User, fetchOptions *experiment.FetchOptions) (map[string]experiment.Variant, error)
```

| Parameter      | Requirement | Description                                                                                                                                 |
| -------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `user`         | required    | The [user](/docs/feature-experiment/data-model#users) for whom to fetch variants.                                                           |
| `fetchOptions` | optional    | The [options](#fetch-options) for the fetch request. If `nil`, uses the server's default behavior (track assignment, don't track exposure). |

```go
user := &experiment.User{
    UserId:   "user@company.com",
    DeviceId: "abcdefg",
    UserProperties: map[string]interface{}{
        "premium": true,
    },
}
variants, err := client.FetchV2WithOptions(user, &experiment.FetchOptions{
    TracksAssignment: true,
    TracksExposure:   true,
})
if err != nil {
    // Handle error
}
```

**FetchOptions**

| Name               | Description                                                             | Default Value |
| ------------------ | ----------------------------------------------------------------------- | ------------- |
| `TracksExposure`   | If `true`, the SDK tracks an exposure event for the fetched variants.   | `false`       |
| `TracksAssignment` | If `true`, the SDK tracks an assignment event for the fetched variants. | `true`        |

## Local evaluation

Implements evaluating variants for a user through [local evaluation](/docs/feature-experiment/local-evaluation). If you plan to use local evaluation, you should [understand the tradeoffs](/docs/feature-experiment/local-evaluation#targeting-capabilities).

### Install

Install the Go Server SDK using `go get`.

```bash
go get github.com/amplitude/experiment-go-server
```

{% callout type="tip" heading="Quick start" %}

1.  [Initialize the local evaluation client.](#initialize-1)
2.  [Start the local evaluation client.](#start)
3.  [Evaluate a user.](#evaluate)

 ```go
 // (1) Initialize the local evaluation client with a server deployment key.
 client := local.Initialize("<DEPLOYMENT_KEY>", &local.Config{
  // (Recommended) Enable local evaluation cohort targeting.
  CohortSyncConfig: &local.CohortSyncConfig {
    ApiKey: "<API_KEY>",
    SecretKey: "<SECRET_KEY>"
  }
 })

 // (2) Start the local evaluation client.
 err := client.Start()
 if err != nil {
   panic(err)
 }

   // (3) Evaluate a user.
 user := &experiment.User{DeviceId: "abcdefg"}
 variants, err := client.EvaluateV2(user, nil)
 if err != nil {
   panic(err)
 }
 ```

{% /callout %}

### Initialize

Initializes a [local evaluation](/docs/feature-experiment/local-evaluation) client.

{% callout type="warning" heading="Server deployment key" %}
You must [initialize](#initialize-1) the local evaluation client with a server [deployment](/docs/feature-experiment/data-model#deployments) key to get access to local evaluation flag configs.
{% /callout %}

```go
func Initialize(apiKey string, config *Config) *Client
```

| Parameter | Requirement | Description                                                                                                                                                      |
| --------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey`  | required    | The server [deployment key](/docs/feature-experiment/data-model#deployments) that authorizes fetch requests and determines which flags to evaluate for the user. |
| `config`  | optional    | The client [configuration](#configuration) used to customize SDK client behavior.                                                                                |

{% callout type="tip" heading="Flag streaming" %}
Use the `StreamUpdates` [configuration](#configuration-1) to push flag config updates to the SDK (default `false`), instead of polling every `FlagConfigPollingInterval` milliseconds. Typically, the time for SDK to receive the update after saving is less than one second. The SDK reverts to polling if streaming fails. Configure `FlagConfigPollingInterval` [configuration](#configuration-1) to set how much time flag configs take to update after they are modified (default 30s), as well for fallback.
{% /callout %}

#### Configuration

Configure the SDK client upon initialization.

{% callout type="info" heading="EU data center" %}
If you're using Amplitude's EU data center, configure the `ServerZone` option on initialization.
{% /callout %}

**Config**

| Name                             | Description                                                                                                                                                                                                                                                                                  | Default Value                                   |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `Debug`                          | Set to `true` to enable debug logging.                                                                                                                                                                                                                                                       | `false`                                         |
| `LogLevel`                       | The minimum log level to output. Options: `Verbose`, `Debug`, `Info`, `Warn`, `Error`, `Disable`. Go to [custom logging](#custom-logging).                                                                                                                                                   | `Error`                                         |
| `LoggerProvider`                 | Custom logger implementation. Implement the `LoggerProvider` interface to integrate with your logging solution. Go to [custom logging](#custom-logging).                                                                                                                                     | `defaultLoggerProvider` which outputs to stdout |
| `ServerZone`                     | The Amplitude data center to use. Either `USServerZone` or `EUServerZone`.                                                                                                                                                                                                                   | `USServerZone`                                  |
| `ServerUrl`                      | The host to fetch flag configurations from.                                                                                                                                                                                                                                                  | `https://api.lab.amplitude.com`                 |
| `FlagConfigPollingInterval`      | The interval to poll for updated flag configs after calling [`Start()`](#start)                                                                                                                                                                                                              | `30 * time.Second`                              |
| `FlagConfigPollerRequestTimeout` | The timeout for the request made by the flag config poller                                                                                                                                                                                                                                   | `10 * time.Second`                              |
| `AssignmentConfig`               | **Deprecated.** Configuration for automatically tracking assignment events after an evaluation.                                                                                                                                                                                              | `nil`                                           |
| `ExposureConfig`                 | Configuration for tracking exposure events after an evaluation.                                                                                                                                                                                                                              | `nil`                                           |
| `StreamUpdates`                  | Enable streaming to replace polling for receiving flag config updates. Instead of polling every second, Amplitude servers push updates to SDK. Typically within one second. If the stream fails for any reason, it reverts to polling automatically and retry streaming after some interval. | `false`                                         |
| `StreamServerUrl`                | The URL of the stream server.                                                                                                                                                                                                                                                                | `https://stream.lab.amplitude.com`              |
| `StreamFlagConnTimeout`          | The timeout for establishing a valid flag config stream. This includes time for establishing a connection to stream server and time for receiving initial flag configs.                                                                                                                      | `1500`                                          |
| `CohortSyncConfig`               | Configuration to enable cohort downloading for [local evaluation cohort targeting](#local-evaluation-cohort-targeting).                                                                                                                                                                      | `nil`                                           |

**AssignmentConfig**

| Name                                                         | Description                                                                                 | Default Value |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | ------------- |
| `CacheCapacity`                                              | The maximum number of assignments stored in the assignment cache                            | `524288`      |
| [`Config`](/docs/sdks/analytics/go/go-sdk#configure-the-sdk) | Options to configure the underlying Amplitude Analytics SDK used to track assignment events |               |

**ExposureConfig**

| Name                                                         | Description                                                                               | Default Value |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------------------- | ------------- |
| `CacheCapacity`                                              | The maximum number of exposures stored in the exposure cache                              | `524288`      |
| [`Config`](/docs/sdks/analytics/go/go-sdk#configure-the-sdk) | Options to configure the underlying Amplitude Analytics SDK used to track exposure events |               |

**CohortSyncConfig**

| Name                          | Description                                                                                                                                                                         | Default Value                         |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| `ApiKey`                      | The analytics API key and NOT the experiment deployment key                                                                                                                         | _required_                            |
| `SecretKey`                   | The analytics secret key                                                                                                                                                            | _required_                            |
| `MaxCohortSize`               | The maximum size of cohort that the SDK downloads. Cohorts larger than this size won't download.                                                                                    | `2147483647`                          |
| `CohortPollingIntervalMillis` | The interval, in milliseconds, to poll Amplitude for cohort updates (60000 minimum).                                                                                                | `60000`                               |
| `CohortServerUrl`             | The cohort server endpoint from which to fetch cohort data. For hitting the EU data center, set `ServerZone` to `EUServerZone`. Setting this value overrides `ServerZone` defaults. | `https://cohort-v2.lab.amplitude.com` |

### Start

Start the local evaluation client, pre-fetching local evaluation mode flag configs for [evaluation](#evaluate) and starting the flag config poller at the [configured](#configuration) interval.

```go
func (c *Client) Start() error
```

You should await the result of `Start()` to ensure that flag configs are ready before calling [`Evaluate()`](#evaluate)

```go
err := client.Start()
if err != nil {
    panic(err)
}
```

### Evaluate

Executes the [evaluation logic](/docs/feature-experiment/implementation) using the flags pre-fetched on [`Start()`](#start). You must give `evaluate` a user object argument. You can optionally pass an array of flag keys if you require only a specific subset of flag variants.

{% callout type="tip" heading="Exposure tracking" %}
Set [`ExposureConfig`](#configuration) to enable exposure tracking. Then, set `TracksExposure` to `true` in `EvaluateOptions` when calling `EvaluateV2WithOptions()`.
{% /callout %}

```go
func (c *Client) EvaluateV2(user *experiment.User, flagKeys []string) (map[string]experiment.Variant, error)
```

| Parameter  | Requirement | Description                                                                                              |
| ---------- | ----------- | -------------------------------------------------------------------------------------------------------- |
| `user`     | required    | The [user](/docs/feature-experiment/data-model#users) to evaluate.                                       |
| `flagKeys` | optional    | Specific flags or experiments to evaluate. If nil or empty, the SDK evaluates all flags and experiments. |

```go
// The user to evaluate
user := &experiment.User{DeviceId: "abcdefg"}

// Evaluate all flag variants
allVariants, err := client.EvaluateV2(user, nil)
if err != nil {
    // Handle Error
}

// Evaluate a specific subset of flag variants
specificVariants, err := client.EvaluateV2(user, []string{
    "<FLAG_KEY_1>",
    "<FLAG_KEY_2>",
})

// Access a variant
variant := allVariants["<FLAG_KEY>"]
if variant.Value == "on" {
    // Flag is on
} else {
    // Flag is off
}
```

### Evaluate V2 With Options

Executes the [evaluation logic](/docs/feature-experiment/implementation) using the flags pre-fetched on [`Start()`](#start). You must give `evaluate` a user object argument. You can optionally pass an array of flag keys if you require only a specific subset of flag variants.

```go
func (c *Client) EvaluateV2WithOptions(user *experiment.User, options *EvaluateOptions) (map[string]experiment.Variant, error)
```

| Parameter | Requirement | Description                                                        |
| --------- | ----------- | ------------------------------------------------------------------ |
| `user`    | required    | The [user](/docs/feature-experiment/data-model#users) to evaluate. |
| `options` | optional    | The [options](#evaluate-options) for the evaluation.               |

```go
user := &experiment.User{DeviceId: "abcdefg"}
variants, err := client.EvaluateV2WithOptions(user, &local.EvaluateOptions{
    FlagKeys: []string{"flag-key-1", "flag-key-2"},
    TracksExposure: true,
})
if err != nil {
    // Handle Error
}
```

**EvaluateOptions**

| Name             | Description                                                                                              | Default Value |
| ---------------- | -------------------------------------------------------------------------------------------------------- | ------------- |
| `FlagKeys`       | Specific flags or experiments to evaluate. If nil or empty, the SDK evaluates all flags and experiments. | `nil`         |
| `TracksExposure` | If `true`, the SDK tracks an exposure event for the evaluated variants.                                  | `false`       |

### Local evaluation cohort targeting

Since version `1.7.0`, the local evaluation SDK client supports downloading cohorts for local evaluation targeting. Configure the `CohortSyncConfig` option with the analytics `ApiKey` and `SecretKey` on initialization to enable this support.

```go
client := local.Initialize("<DEPLOYMENT_KEY>", &local.Config{
  // (Recommended) Enable local evaluation cohort targeting.
  CohortSyncConfig: &local.CohortSyncConfig {
    ApiKey: "<API_KEY>",
    SecretKey: "<SECRET_KEY>"
  }
})
```

## Custom logging

Control log verbosity with the `LogLevel` configuration, or implement the `LoggerProvider` interface to integrate your own logger.

### Log levels

The SDK supports these log levels:

- `Verbose`: Detailed logging for deep debugging
- `Debug`: Logging for development and troubleshooting
- `Info`: General informational messages
- `Warn`: Warning messages
- `Error`: Error messages (default)
- `Disable`: No logging

### Custom logger

Implement the `LoggerProvider` interface to integrate your logging solution:

```go
import "github.com/amplitude/experiment-go-server/logger"

type MyCustomLogger struct {
    // Your logger implementation
}

func (l *MyCustomLogger) Verbose(message string, args ...interface{}) {
    // Implement verbose logging
}

func (l *MyCustomLogger) Debug(message string, args ...interface{}) {
    // Implement debug logging
}

func (l *MyCustomLogger) Info(message string, args ...interface{}) {
    // Implement info logging
}

func (l *MyCustomLogger) Warn(message string, args ...interface{}) {
    // Implement warn logging
}

func (l *MyCustomLogger) Error(message string, args ...interface{}) {
    // Implement error logging
}

// Initialize with custom logger
client := local.Initialize("<DEPLOYMENT_KEY>", &local.Config{
    LogLevel: logger.Debug,
    LoggerProvider: &MyCustomLogger{},
})
```

{% callout type="note" heading="Backward compatibility" %}
The `Debug` configuration field is still supported. When set to `true`, it overrides `LogLevel` to `Debug`.
{% /callout %}
