---
title: Statsig
slug: statsig
docTags: 
createdAt: 2026-09-15T18:08:39.192Z
---

The **Statsig** destination sends events to [Statsig](https://www.statsig.com/) using the server-side [`log_event HTTP API`](https://docs.statsig.com/api/content/api-reference/events/log-custom-events), so that Chord CDP events can be used as metrics for Statsig experiments and feature gates.

This is a **cloud-mode (server-side) destination only**, and deliberately so. The metrics that decide a Statsig experiment are revenue events — `Order Completed`, refunds, subscription renewals — and in Chord CDP those frequently arrive from backend sources (Shopify webhooks, server-to-server ingest) that never touch a browser. A device-mode plugin could not see them, which would leave you with an experiment that cannot measure its own success metric. Segment ships Statsig the same way, cloud-mode only.

Feature gate and experiment **evaluation stays in your storefront's own Statsig SDK.** This destination only ever calls `log_event`; it never calls `check_gate`, because that endpoint automatically logs exposure events and would double-count exposures the storefront SDK already records.

You will need:

- **Server Secret Key** — found in **Project Settings > API Keys** in the Statsig console. It starts with `secret-`. Do not use a client SDK key here.

# Connecting to the Statsig CDP Destination

:::BlockQuote
**Warning:** Before connecting destinations in the Chord CDP, please verify with all Destination owners that all **non-Chord CDP** configured destinations are **disabled**. Running external destinations alongside configured Chord CDP destinations **can result in duplicate events downstream.**
:::

1. Log into the Chord data platform.
2. Navigate to the CDP.
3. Click the **"Add"** button next to Destinations.
4. Select **Statsig** from the destination catalog.
5. Enter the destination name and your **Server Secret Key**.
6. Confirm the **Anonymous ID Key** matches your experiment unit (see [Identity and experiment units](#) below).
7. Click **"Create"** to connect.

# Identity and experiment units

This is the setting that most often breaks a Statsig integration, so it is worth getting right before you ship.

Statsig randomizes each experiment on a **unit ID**. If the storefront's Statsig SDK assigns a visitor to a variant using one ID, but Chord CDP sends the conversion event under a different one, the event will not join to the experiment group — every readout comes back flat, with no error anywhere to explain why.

The destination sends:

| Statsig field                       | Chord source  |
| ----------------------------------- | ------------- |
| `user.userID`                       | `userId`      |
| `user.customIDs.<Anonymous ID Key>` | `anonymousId` |

The **Anonymous ID Key** defaults to `stableID`, which is Statsig's own convention for an anonymous unit. For this to line up, your storefront must be configured to pass the Chord `anonymousId` as Statsig's `stableID` rather than letting the Statsig SDK generate its own. If your experiments are randomized on a different custom ID, set the Anonymous ID Key to match it.

Migrating off Segment? Whatever field you mapped to Statsig's `userID` in the Segment destination is the unit your existing experiments are already keyed on. Carry that exact mapping over, or your readouts will break at cutover.

# Event Mapping

Statsig has no fixed event taxonomy — custom event names are first class — so **track events pass through under their own name**. No allowlist, no renaming.

| Chord Event Type | Statsig `eventName`            | Notes                                                                |
| ---------------- | ------------------------------ | -------------------------------------------------------------------- |
| `track`          | The Chord event name, verbatim | Custom events pass through unchanged                                 |
| `page`           | `Page View`                    | Sent only when **Send page events** is enabled (default on)          |
| `identify`       | `Identify`                     | Sent only when **Send identify events** is enabled (default **off**) |

Any other event type (`group`, `screen`, …) is skipped with an explicit log line, never dropped silently.

## Track Events

| Statsig Field | Chord Source                                                   | Notes                                                                                  |
| ------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `eventName`   | `event`                                                        | Passed through verbatim                                                                |
| `value`       | `properties.revenue` > `properties.total` > `properties.value` | Overridable via the **Value Property** setting. Numeric strings are coerced to numbers |
| `time`        | `timestamp`                                                    | Unix milliseconds                                                                      |
| `metadata`    | `properties`                                                   | See [Metadata flattening](#)                                                           |
| `user`        | Identity + context                                             | See [Identity and experiment units](#)                                                 |

## Page Events

| Statsig Field                                     | Chord Source              | Notes                                                                                                                                |
| ------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `eventName`                                       | *(hardcoded)* `Page View` | Page identity lives in `metadata`, so a single metric can be filtered per page rather than fragmenting into one metric per page name |
| `metadata.url` / `.path` / `.title` / `.referrer` | `context.page`            | Explicit `properties` of the same name win over the context values                                                                   |
| `metadata.name`                                   | `name`                    | Present when the page event is named                                                                                                 |

`value` is never set on page events.

## Identify Events

Statsig has no user-profile API, so an identify call is logged as an ordinary `Identify` event with the user's traits in `metadata`. This is **off by default** to avoid inflating event volume for no analytical gain — enable it only if you want identify calls to be countable as a metric.

# Metadata flattening

Statsig's `metadata` is a flat key/value map. Nested values (`products[]`, `address`, …) are **JSON-stringified rather than dropped**, so the data still reaches Statsig and remains queryable as a string instead of silently disappearing. Primitives (string, number, boolean) pass through unchanged; `null` and `undefined` are omitted.

Because `metadata` accepts arbitrary keys, any custom property mappings you configure in Hub flow through automatically — there is no destination-side schema to add them to.

# Email and PII

The **Email Handling** setting controls where a user's email address goes:

| Mode                | Behavior                                                                                                |
| ------------------- | ------------------------------------------------------------------------------------------------------- |
| `Private` (default) | Sent as `user.privateAttributes.email` — usable for targeting, but never written to Statsig's event log |
| `Attribute`         | Sent as `user.email`, which **is** logged                                                               |
| `Omit`              | Never sent                                                                                              |

In `Private` and `Omit` mode, `email` is also stripped from `metadata`, so a value arriving via traits or properties cannot defeat the setting.

**Email Handling covers email and nothing else.** Every other trait and property is forwarded to `metadata` verbatim, and `metadata` **is** written to Statsig's event log. An identify event carrying `phone`, `firstName`, `lastName` or `address` sends those to Statsig in plaintext, with no setting to suppress them. This matters most for identify events, which carry a full trait set — one reason **Send identify events** is off by default. If a trait must not reach Statsig, drop it upstream in a transformation function rather than relying on this destination to filter it.

# Environments

The **Environment Tier** setting is sent as `user.statsigEnvironment.tier`. Set it to `staging` or `development` on non-production connections — otherwise staging traffic silently pollutes your production experiment metrics, which is painful to unwind after the fact.

# Retry Behavior

| Response          | Behavior                                                                                              |
| ----------------- | ----------------------------------------------------------------------------------------------------- |
| `202`             | Accepted                                                                                              |
| `429`, `5xx`      | Retried                                                                                               |
| Other `4xx`       | Not retried — a bad secret key or malformed payload cannot be fixed by sending the same request again |
| Transport failure | Retried                                                                                               |

