> ## Documentation Index
> Fetch the complete documentation index at: https://docs.growthbook.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks Events

> Reference of the event types GrowthBook can send to event webhooks, covering experiments, feature flags, and user changes.

We currently support the following event types.

Revision events (`*.revision.*`) carry the revision's ID, version and base version, status, title, description, dates, author, schedule and the entity it belongs to, plus the event's own fields such as the reviewer. They also carry its content: for Configs, Constants and Saved Groups, the entity before and after the draft (`baseConfig` and `proposedConfig`, for example) and the patch it applies (`proposedChanges`); for Feature Flags, the draft's default value, rules, prerequisites and other settings. Reviews and history are on the [REST API](https://docs.growthbook.io/api.md). Feature Flag revision events also keep the deprecated `featureId`, `date`, `createdBy` and `publishedBy` fields for existing integrations.

| Event name | Description |
| - | - |
| **[feature.created](#feature-created)** | Triggered when a feature is created |
| **[feature.updated](#feature-updated)** | Triggered when a feature is updated |
| **[feature.deleted](#feature-deleted)** | Triggered when a feature is deleted |
| **[feature.saferollout.ship](#feature-saferollout-ship)** | Triggered when a safe rollout is completed and safe to roll out to 100%. |
| **[feature.saferollout.rollback](#feature-saferollout-rollback)** | Triggered when a safe rollout has a failing guardrail and should be reverted. |
| **[feature.saferollout.unhealthy](#feature-saferollout-unhealthy)** | Triggered when a safe rollout is failing a health check and may not be working as expected. |
| **[feature.rampSchedule.created](#feature-rampschedule-created)** | Triggered when a ramp schedule is created for a feature |
| **[feature.rampSchedule.deleted](#feature-rampschedule-deleted)** | Triggered when a ramp schedule is deleted from a feature |
| **[feature.rampSchedule.actions.started](#feature-rampschedule-actions-started)** | Triggered when a feature ramp schedule starts |
| **[feature.rampSchedule.actions.completed](#feature-rampschedule-actions-completed)** | Triggered when a feature ramp schedule completes all steps |
| **[feature.rampSchedule.actions.rolledBack](#feature-rampschedule-actions-rolledback)** | Triggered when a feature ramp schedule is rolled back or reset to start |
| **[feature.rampSchedule.actions.jumped](#feature-rampschedule-actions-jumped)** | Triggered when a feature ramp schedule is jumped to a specific step |
| **[feature.rampSchedule.actions.step.advanced](#feature-rampschedule-actions-step-advanced)** | Triggered when a feature ramp schedule advances. Overdue steps are caught up in a single advance: when `currentStepIndex - previousStepIndex > 1`, the intermediate steps were folded into this one event (one revision publish) rather than fired individually. |
| **[feature.rampSchedule.actions.step.approvalRequired](#feature-rampschedule-actions-step-approvalrequired)** | Triggered when a feature ramp step is waiting for approval |
| **[feature.rampSchedule.actions.awaitingStartApproval](#feature-rampschedule-actions-awaitingstartapproval)** | Triggered when a feature ramp schedule is published but held at the start, awaiting an explicit start approval |
| **[feature.rampSchedule.actions.startApproved](#feature-rampschedule-actions-startapproved)** | Triggered when a held ramp schedule's start is approved by a user |
| **[feature.rampSchedule.actions.errorPaused](#feature-rampschedule-actions-errorpaused)** | Triggered when a feature ramp schedule pauses because a step could not be applied, for example a plan the engine refuses; `reason` says why |
| **[feature.rampSchedule.actions.stepHeld](#feature-rampschedule-actions-stepheld)** | Triggered when a monitored ramp step is held by a health check (SRM, multiple exposures, no traffic, a guardrail metric that failed to compute, an unhealthy signal metric). Sent once per check per step; `reason` says why |
| **[feature.rampSchedule.actions.paused](#feature-rampschedule-actions-paused)** | Triggered when a feature ramp schedule is paused by a user or by its monitoring policy |
| **[feature.rampSchedule.actions.resumed](#feature-rampschedule-actions-resumed)** | Triggered when a paused feature ramp schedule is resumed |
| **[feature.revision.created](#feature-revision-created)** | Triggered when a new draft revision is created for a feature |
| **[feature.revision.updated](#feature-revision-updated)** | Triggered when a draft revision is modified (rules, default value, toggles, prerequisites, metadata, etc.). The `change` field indicates the specific kind of mutation. |
| **[feature.revision.reviewRequested](#feature-revision-reviewrequested)** | Triggered when a draft revision is submitted for review |
| **[feature.revision.approved](#feature-revision-approved)** | Triggered when a draft revision is approved by a reviewer |
| **[feature.revision.changesRequested](#feature-revision-changesrequested)** | Triggered when a reviewer requests changes on a draft revision |
| **[feature.revision.commented](#feature-revision-commented)** | Triggered when a comment is added to a draft revision |
| **[feature.revision.discarded](#feature-revision-discarded)** | Triggered when a draft revision is discarded |
| **[feature.revision.reopened](#feature-revision-reopened)** | Triggered when a discarded draft revision is reopened as a draft |
| **[feature.revision.recalled](#feature-revision-recalled)** | Triggered when the author (or an editor) recalls a review request, returning the revision to `draft`. Distinct from `revision.reopened`, which restores a discarded revision. |
| **[feature.revision.reviewRetracted](#feature-revision-reviewretracted)** | Triggered when a reviewer retracts their own verdict. The status is recomputed from the verdicts that remain, so the revision may end up `pending-review`, or stay `approved` or `changes-requested` when another reviewer's verdict still stands. Carries no content change — the revision's proposed changes are untouched. |
| **[feature.revision.publishScheduleChanged](#feature-revision-publishschedulechanged)** | Triggered when a deferred publish is armed, re-armed, or cancelled on a revision. Carries no content change. |
| **[feature.revision.rebased](#feature-revision-rebased)** | Triggered when a draft revision is rebased onto the latest published version |
| **[feature.revision.published](#feature-revision-published)** | Triggered when a draft revision is published. Overlaps with `feature.updated` but identifies the revision and its author. |
| **[feature.revision.reverted](#feature-revision-reverted)** | Triggered when a feature is reverted to a previous published revision |
| **[feature.revision.publishFailed](#feature-revision-publishfailed)** | Triggered when a deferred publish (scheduled publish or auto-publish-on-approval) is given up on after failing — terminally, or after exhausting retries. The draft is left open for a human to resolve. |
| **[experiment.created](#experiment-created)** | Triggered when an experiment is created |
| **[experiment.updated](#experiment-updated)** | Triggered when an experiment is updated |
| **[experiment.deleted](#experiment-deleted)** | Triggered when an experiment is deleted |
| **[experiment.warning](#experiment-warning)** | Triggered when a warning condition is detected on an experiment, such as a sample ratio mismatch, multiple exposures, low power, no data, or a failed results update. The `type` field identifies the condition. |
| **[experiment.status.started](#experiment-status-started)** | Triggered when an experiment starts or resumes running. |
| **[experiment.status.stopped](#experiment-status-stopped)** | Triggered when an experiment stops, including its result and any temporary rollout. |
| **[experiment.status.endingSoon](#experiment-status-endingsoon)** | Triggered when a running experiment is within 3 days of its scheduled end date. |
| **[experiment.status.stale](#experiment-status-stale)** | Triggered when a running experiment has been active for a long time without a decision. |
| **[experiment.guardrailFailed](#experiment-guardrailfailed)** | Triggered when a running experiment has a failing guardrail metric. |
| **[experiment.bandit.weightsChanged](#experiment-bandit-weightschanged)** | Triggered when a multi-armed bandit materially changes variation weights. |
| **[experiment.info.significance](#experiment-info-significance)** | Triggered when a goal or guardrail metric reaches significance in an experiment (e.g. either above 95% or below 5% chance to win). Be careful using this without Sequential Testing as it can lead to peeking problems. |
| **[experiment.info.scheduled-status-update](#experiment-info-scheduled-status-update)** | Triggered when a scheduled start or stop is automatically applied to an experiment, including the auto-ship outcome for a scheduled end. |
| **[experiment.decision.ship](#experiment-decision-ship)** | Triggered when an experiment is ready to ship a variation. |
| **[experiment.decision.rollback](#experiment-decision-rollback)** | Triggered when an experiment should be rolled back to the control. |
| **[experiment.decision.review](#experiment-decision-review)** | Triggered when an experiment has reached the desired power point, but the results may be ambiguous. |
| **[holdout.created](#holdout-created)** | Triggered when a holdout is created. |
| **[holdout.status.changed](#holdout-status-changed)** | Triggered when a holdout moves between its lifecycle stages, such as running or analysis. |
| **[holdout.config.newLinkage](#holdout-config-newlinkage)** | Triggered when feature flags or experiments are linked to a holdout. |
| **[sdkConnection.payloadSize.warning](#sdkconnection-payloadsize-warning)** | Triggered when an SDK Connection's payload grows past half, 80%, or all of the 16 MB its cache can store. The `level` field is `warning`, `danger`, or `over-limit`, and `recommendations` lists ways to shrink it. Fires once per level reached, not on every publish. |
| **[savedGroup.created](#savedgroup-created)** | Triggered when a saved group is created |
| **[savedGroup.updated](#savedgroup-updated)** | Triggered when a saved group is updated |
| **[savedGroup.deleted](#savedgroup-deleted)** | Triggered when a saved group is deleted |
| **[savedGroup.revision.created](#savedgroup-revision-created)** | Triggered when a new draft revision is created for a saved group |
| **[savedGroup.revision.updated](#savedgroup-revision-updated)** | Triggered when a draft revision's proposed changes are modified (values, condition, archive, or metadata). The `change` field indicates the kind of mutation. |
| **[savedGroup.revision.reviewRequested](#savedgroup-revision-reviewrequested)** | Triggered when a draft revision is submitted for review |
| **[savedGroup.revision.approved](#savedgroup-revision-approved)** | Triggered when a draft revision is approved by a reviewer |
| **[savedGroup.revision.changesRequested](#savedgroup-revision-changesrequested)** | Triggered when a reviewer requests changes on a draft revision |
| **[savedGroup.revision.commented](#savedgroup-revision-commented)** | Triggered when a comment is added to a draft revision |
| **[savedGroup.revision.discarded](#savedgroup-revision-discarded)** | Triggered when a draft revision is discarded |
| **[savedGroup.revision.rebased](#savedgroup-revision-rebased)** | Triggered when a draft revision is rebased onto the latest live state |
| **[savedGroup.revision.published](#savedgroup-revision-published)** | Triggered when a draft revision is published. Overlaps with `savedGroup.updated` but provides revision-specific context. |
| **[savedGroup.revision.reverted](#savedgroup-revision-reverted)** | Triggered when a saved group is reverted to a previous published revision |
| **[savedGroup.revision.reopened](#savedgroup-revision-reopened)** | Triggered when a discarded revision is reopened |
| **[savedGroup.revision.recalled](#savedgroup-revision-recalled)** | Triggered when the author (or an editor) recalls a review request, returning the revision to `draft`. Distinct from `revision.reopened`, which restores a discarded revision. |
| **[savedGroup.revision.reviewRetracted](#savedgroup-revision-reviewretracted)** | Triggered when a reviewer retracts their own verdict. The status is recomputed from the verdicts that remain, so the revision may end up `pending-review`, or stay `approved` or `changes-requested` when another reviewer's verdict still stands. Carries no content change — the revision's proposed changes are untouched. |
| **[savedGroup.revision.publishScheduleChanged](#savedgroup-revision-publishschedulechanged)** | Triggered when a deferred publish is armed, re-armed, or cancelled on a revision. Carries no content change. |
| **[savedGroup.revision.publishFailed](#savedgroup-revision-publishfailed)** | Triggered when a deferred publish (scheduled publish or auto-publish-on-approval) is given up on after failing — terminally, or after exhausting retries. The draft is left open for a human to resolve. |
| **[constant.created](#constant-created)** | Triggered when a constant is created |
| **[constant.updated](#constant-updated)** | Triggered when a constant is updated |
| **[constant.deleted](#constant-deleted)** | Triggered when a constant is deleted |
| **[constant.revision.created](#constant-revision-created)** | Triggered when a new draft revision is created for a constant |
| **[constant.revision.updated](#constant-revision-updated)** | Triggered when a draft revision's proposed changes are modified (value, archive, or metadata). The `change` field indicates the kind of mutation. |
| **[constant.revision.reviewRequested](#constant-revision-reviewrequested)** | Triggered when a draft revision is submitted for review |
| **[constant.revision.approved](#constant-revision-approved)** | Triggered when a draft revision is approved by a reviewer |
| **[constant.revision.changesRequested](#constant-revision-changesrequested)** | Triggered when a reviewer requests changes on a draft revision |
| **[constant.revision.commented](#constant-revision-commented)** | Triggered when a comment is added to a draft revision |
| **[constant.revision.discarded](#constant-revision-discarded)** | Triggered when a draft revision is discarded |
| **[constant.revision.rebased](#constant-revision-rebased)** | Triggered when a draft revision is rebased onto the latest live state |
| **[constant.revision.published](#constant-revision-published)** | Triggered when a draft revision is published. Overlaps with `constant.updated` but provides revision-specific context. |
| **[constant.revision.reverted](#constant-revision-reverted)** | Triggered when a constant is reverted to a previous published revision |
| **[constant.revision.reopened](#constant-revision-reopened)** | Triggered when a discarded revision is reopened |
| **[constant.revision.recalled](#constant-revision-recalled)** | Triggered when the author (or an editor) recalls a review request, returning the revision to `draft`. Distinct from `revision.reopened`, which restores a discarded revision. |
| **[constant.revision.reviewRetracted](#constant-revision-reviewretracted)** | Triggered when a reviewer retracts their own verdict. The status is recomputed from the verdicts that remain, so the revision may end up `pending-review`, or stay `approved` or `changes-requested` when another reviewer's verdict still stands. Carries no content change — the revision's proposed changes are untouched. |
| **[constant.revision.publishScheduleChanged](#constant-revision-publishschedulechanged)** | Triggered when a deferred publish is armed, re-armed, or cancelled on a revision. Carries no content change. |
| **[constant.revision.publishFailed](#constant-revision-publishfailed)** | Triggered when a deferred publish (scheduled publish or auto-publish-on-approval) is given up on after failing — terminally, or after exhausting retries. The draft is left open for a human to resolve. |
| **[config.created](#config-created)** | Triggered when a config is created |
| **[config.updated](#config-updated)** | Triggered when a config is updated |
| **[config.deleted](#config-deleted)** | Triggered when a config is deleted |
| **[config.revision.created](#config-revision-created)** | Triggered when a new draft revision is created for a config |
| **[config.revision.updated](#config-revision-updated)** | Triggered when a draft revision's proposed changes are modified (value, schema, archive, or metadata). The `change` field indicates the kind of mutation. |
| **[config.revision.reviewRequested](#config-revision-reviewrequested)** | Triggered when a draft revision is submitted for review |
| **[config.revision.approved](#config-revision-approved)** | Triggered when a draft revision is approved by a reviewer |
| **[config.revision.changesRequested](#config-revision-changesrequested)** | Triggered when a reviewer requests changes on a draft revision |
| **[config.revision.commented](#config-revision-commented)** | Triggered when a comment is added to a draft revision |
| **[config.revision.discarded](#config-revision-discarded)** | Triggered when a draft revision is discarded |
| **[config.revision.rebased](#config-revision-rebased)** | Triggered when a draft revision is rebased onto the latest live state |
| **[config.revision.published](#config-revision-published)** | Triggered when a draft revision is published. Overlaps with `config.updated` but provides revision-specific context. |
| **[config.revision.reverted](#config-revision-reverted)** | Triggered when a config is reverted to a previous published revision |
| **[config.revision.reopened](#config-revision-reopened)** | Triggered when a discarded revision is reopened |
| **[config.revision.recalled](#config-revision-recalled)** | Triggered when the author (or an editor) recalls a review request, returning the revision to `draft`. Distinct from `revision.reopened`, which restores a discarded revision. |
| **[config.revision.reviewRetracted](#config-revision-reviewretracted)** | Triggered when a reviewer retracts their own verdict. The status is recomputed from the verdicts that remain, so the revision may end up `pending-review`, or stay `approved` or `changes-requested` when another reviewer's verdict still stands. Carries no content change — the revision's proposed changes are untouched. |
| **[config.revision.publishScheduleChanged](#config-revision-publishschedulechanged)** | Triggered when a deferred publish is armed, re-armed, or cancelled on a revision. Carries no content change. |
| **[config.revision.publishFailed](#config-revision-publishfailed)** | Triggered when a deferred publish (scheduled publish or auto-publish-on-approval) is given up on after failing — terminally, or after exhausting retries. The draft is left open for a human to resolve. |
| **[user.login](#user-login)** | Triggered when a user logs in |
| **[apiKey.expiring](#apikey-expiring)** | Triggered once when a secret API key is within a week of expiring |
| **[apiKey.expired](#apikey-expired)** | Triggered once when a secret API key passes its expiration date |

### feature.created

Triggered when a feature is created

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.created";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             dateCreated: string;
>             dateUpdated: string;
>             archived: boolean;
>             description: string;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner: string;
>             project: string;
>             valueType: "boolean" | "string" | "number" | "json";
>             defaultValue: string;
>             tags: string[];
>             environments: Record<string, any>;
>             /** Feature IDs. Each feature must evaluate to `true` */
>             prerequisites?: string[] | undefined;
>             revision: {
>                 version: number;
>                 comment: string;
>                 date: string;
>                 createdBy: string;
>                 publishedBy: string;
>             };
>             customFields?: Record<string, {}> | undefined;
>             holdout?: ({
>                 /** Holdout ID */
>                 id: string;
>                 /** The feature value assigned to users in the holdout treatment group */
>                 value: string;
>             } | null) | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.updated

Triggered when a feature is updated

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.updated";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             dateCreated: string;
>             dateUpdated: string;
>             archived: boolean;
>             description: string;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner: string;
>             project: string;
>             valueType: "boolean" | "string" | "number" | "json";
>             defaultValue: string;
>             tags: string[];
>             environments: Record<string, any>;
>             /** Feature IDs. Each feature must evaluate to `true` */
>             prerequisites?: string[] | undefined;
>             revision: {
>                 version: number;
>                 comment: string;
>                 date: string;
>                 createdBy: string;
>                 publishedBy: string;
>             };
>             customFields?: Record<string, {}> | undefined;
>             holdout?: ({
>                 /** Holdout ID */
>                 id: string;
>                 /** The feature value assigned to users in the holdout treatment group */
>                 value: string;
>             } | null) | undefined;
>         };
>         previous_attributes: {
>             id?: string | undefined;
>             dateCreated?: string | undefined;
>             dateUpdated?: string | undefined;
>             archived?: boolean | undefined;
>             description?: string | undefined;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             project?: string | undefined;
>             valueType?: ("boolean" | "string" | "number" | "json") | undefined;
>             defaultValue?: string | undefined;
>             tags?: string[] | undefined;
>             environments?: Record<string, any> | undefined;
>             /** Feature IDs. Each feature must evaluate to `true` */
>             prerequisites?: string[] | undefined;
>             revision?: {
>                 version: number;
>                 comment: string;
>                 date: string;
>                 createdBy: string;
>                 publishedBy: string;
>             } | undefined;
>             customFields?: Record<string, {}> | undefined;
>             holdout?: ({
>                 /** Holdout ID */
>                 id: string;
>                 /** The feature value assigned to users in the holdout treatment group */
>                 value: string;
>             } | null) | undefined;
>         };
>         changes?: {
>             added: Record<string, unknown>;
>             removed: Record<string, unknown>;
>             modified: unknown[];
>         } | undefined;
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.deleted

Triggered when a feature is deleted

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.deleted";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             dateCreated: string;
>             dateUpdated: string;
>             archived: boolean;
>             description: string;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner: string;
>             project: string;
>             valueType: "boolean" | "string" | "number" | "json";
>             defaultValue: string;
>             tags: string[];
>             environments: Record<string, any>;
>             /** Feature IDs. Each feature must evaluate to `true` */
>             prerequisites?: string[] | undefined;
>             revision: {
>                 version: number;
>                 comment: string;
>                 date: string;
>                 createdBy: string;
>                 publishedBy: string;
>             };
>             customFields?: Record<string, {}> | undefined;
>             holdout?: ({
>                 /** Holdout ID */
>                 id: string;
>                 /** The feature value assigned to users in the holdout treatment group */
>                 value: string;
>             } | null) | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.saferollout.ship

Triggered when a safe rollout is completed and safe to roll out to 100%.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.saferollout.ship";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             featureId: string;
>             safeRolloutId: string;
>             environment: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.saferollout.rollback

Triggered when a safe rollout has a failing guardrail and should be reverted.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.saferollout.rollback";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             featureId: string;
>             safeRolloutId: string;
>             environment: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.saferollout.unhealthy

Triggered when a safe rollout is failing a health check and may not be working as expected.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.saferollout.unhealthy";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             featureId: string;
>             safeRolloutId: string;
>             environment: string;
>             unhealthyReason: ("srm" | "multipleExposures")[];
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.created

Triggered when a ramp schedule is created for a feature

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.created";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             entityType: string;
>             entityId: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.deleted

Triggered when a ramp schedule is deleted from a feature

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.deleted";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.started

Triggered when a feature ramp schedule starts

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.started";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.completed

Triggered when a feature ramp schedule completes all steps

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.completed";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>             previousStepIndex?: number | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.rolledBack

Triggered when a feature ramp schedule is rolled back or reset to start

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.rolledBack";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>             targetStepIndex: number;
>             reason?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.jumped

Triggered when a feature ramp schedule is jumped to a specific step

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.jumped";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>             targetStepIndex: number;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.step.advanced

Triggered when a feature ramp schedule advances. Overdue steps are caught up in a single advance: when `currentStepIndex - previousStepIndex > 1`, the intermediate steps were folded into this one event (one revision publish) rather than fired individually.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.step.advanced";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>             previousStepIndex?: number | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.step.approvalRequired

Triggered when a feature ramp step is waiting for approval

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.step.approvalRequired";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>             approvalNotes?: (string | null) | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.awaitingStartApproval

Triggered when a feature ramp schedule is published but held at the start, awaiting an explicit start approval

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.awaitingStartApproval";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.startApproved

Triggered when a held ramp schedule's start is approved by a user

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.startApproved";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.errorPaused

Triggered when a feature ramp schedule pauses because a step could not be applied, for example a plan the engine refuses; `reason` says why

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.errorPaused";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>             reason: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.stepHeld

Triggered when a monitored ramp step is held by a health check (SRM, multiple exposures, no traffic, a guardrail metric that failed to compute, an unhealthy signal metric). Sent once per check per step; `reason` says why

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.stepHeld";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>             reason: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.paused

Triggered when a feature ramp schedule is paused by a user or by its monitoring policy

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.paused";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>             reason?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.rampSchedule.actions.resumed

Triggered when a paused feature ramp schedule is resumed

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.rampSchedule.actions.resumed";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             rampScheduleId: string;
>             rampName: string;
>             orgId: string;
>             currentStepIndex: number;
>             status: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.created

Triggered when a new draft revision is created for a feature

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.created";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.updated

Triggered when a draft revision is modified (rules, default value, toggles, prerequisites, metadata, etc.). The `change` field indicates the specific kind of mutation.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.updated";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>             change: "rule.add" | "rule.update" | "rule.delete" | "rule.reorder" | "rule.rampSchedule.set" | "rule.rampSchedule.remove" | "toggle" | "defaultValue" | "prerequisites" | "holdout" | "archive" | "metadata";
>             environments?: string[] | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.reviewRequested

Triggered when a draft revision is submitted for review

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.reviewRequested";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>             reviewComment: string | null;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.approved

Triggered when a draft revision is approved by a reviewer

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.approved";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string | null;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.changesRequested

Triggered when a reviewer requests changes on a draft revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.changesRequested";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string | null;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.commented

Triggered when a comment is added to a draft revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.commented";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.discarded

Triggered when a draft revision is discarded

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.discarded";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.reopened

Triggered when a discarded draft revision is reopened as a draft

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.reopened";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.recalled

Triggered when the author (or an editor) recalls a review request, returning the revision to `draft`. Distinct from `revision.reopened`, which restores a discarded revision.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.recalled";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.reviewRetracted

Triggered when a reviewer retracts their own verdict. The status is recomputed from the verdicts that remain, so the revision may end up `pending-review`, or stay `approved` or `changes-requested` when another reviewer's verdict still stands. Carries no content change — the revision's proposed changes are untouched.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.reviewRetracted";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.publishScheduleChanged

Triggered when a deferred publish is armed, re-armed, or cancelled on a revision. Carries no content change.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.publishScheduleChanged";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.rebased

Triggered when a draft revision is rebased onto the latest published version

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.rebased";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.published

Triggered when a draft revision is published. Overlaps with `feature.updated` but identifies the revision and its author.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.published";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>             bulkPublishId?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.reverted

Triggered when a feature is reverted to a previous published revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.reverted";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>             revertedToVersion: number;
>             bulkPublishId?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### feature.revision.publishFailed

Triggered when a deferred publish (scheduled publish or auto-publish-on-approval) is given up on after failing — terminally, or after exhausting retries. The draft is left open for a human to resolve.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "feature.revision.publishFailed";
>     object: "feature";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             feature: {
>                 id: string;
>             };
>             /** Deprecated: use `feature.id`. */
>             featureId: string;
>             /** Deprecated: use `dateCreated`. */
>             date: string;
>             createdBy?: string | undefined;
>             publishedBy?: string | undefined;
>             /** The draft's default value */
>             defaultValue?: string | undefined;
>             rules: Record<string, unknown[]>;
>             environmentsEnabled?: Record<string, boolean> | undefined;
>             prerequisites?: {
>                 /** Feature ID */
>                 id: string;
>                 condition: string;
>             }[] | undefined;
>             metadata?: {} | undefined;
>             /** Ramp schedule steps the draft attaches to its rules */
>             rampActions?: unknown[] | undefined;
>             bulkPublishId?: string | undefined;
>             failureReason: string;
>             terminal: boolean;
>             attempts: number;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.created

Triggered when an experiment is created

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.created";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             trackingKey: string;
>             dateCreated: string;
>             dateUpdated: string;
>             name: string;
>             type: "standard" | "multi-armed-bandit" | "holdout";
>             project: string;
>             hypothesis: string;
>             description: string;
>             tags: string[];
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner: string;
>             ownerEmail?: string | undefined;
>             archived: boolean;
>             status: string;
>             autoRefresh: boolean;
>             hashAttribute: string;
>             fallbackAttribute?: string | undefined;
>             hashVersion: 1 | 2;
>             disableStickyBucketing?: boolean | undefined;
>             bucketVersion?: number | undefined;
>             minBucketVersion?: number | undefined;
>             variations: {
>                 variationId: string;
>                 key: string;
>                 name: string;
>                 description: string;
>                 screenshots: string[];
>             }[];
>             phases: {
>                 name: string;
>                 dateStarted: string;
>                 dateEnded: string;
>                 reasonForStopping: string;
>                 seed: string;
>                 coverage: number;
>                 trafficSplit: {
>                     variationId: string;
>                     weight: number;
>                 }[];
>                 namespace?: {
>                     namespaceId: string;
>                     enabled?: boolean | undefined;
>                     range?: number[] | undefined;
>                     ranges?: [
>                         number,
>                         number
>                     ][] | undefined;
>                 } | undefined;
>                 targetingCondition: string;
>                 prerequisites?: {
>                     id: string;
>                     condition: string;
>                 }[] | undefined;
>                 savedGroupTargeting?: {
>                     matchType: "all" | "any" | "none";
>                     savedGroups: string[];
>                 }[] | undefined;
>             }[];
>             settings: {
>                 datasourceId: string;
>                 /** The assignment query, grouping its ID with the identifier type analyzed on. */
>                 assignmentQuery: {
>                     /** The ID of one of the data source's assignment queries. */
>                     id: string;
>                     /** The identifier type analyzed on. Null when none can be resolved: no assignment query is selected, or a record saved before identifier types were stored points at a query that no longer exists. */
>                     identifierType: string | null;
>                 };
>                 /** Deprecated: use `assignmentQuery`. */
>                 assignmentQueryId: string;
>                 experimentId: string;
>                 segmentId: string;
>                 queryFilter: string;
>                 inProgressConversions: "include" | "exclude";
>                 /** Setting attribution model to `"experimentDuration"` is the same as selecting "Ignore Conversion Windows" for the Conversion Window Override. Setting it to `"lookbackOverride"` requires a `lookbackOverride` object to be provided. */
>                 attributionModel: "firstExposure" | "experimentDuration" | "lookbackOverride";
>                 /** Controls the lookback override for the experiment. For type "window", value must be a non-negative number and valueUnit is required. */
>                 lookbackOverride?: {
>                     type: "date" | "window";
>                     /** For "window" type - non-negative numeric value (e.g. 7 for 7 days). For "date" type a date string. */
>                     value: number | string;
>                     /** Used when type is "window". Defaults to "days". */
>                     valueUnit?: ("minutes" | "hours" | "days" | "weeks") | undefined;
>                 } | undefined;
>                 statsEngine: "bayesian" | "frequentist";
>                 regressionAdjustmentEnabled?: boolean | undefined;
>                 sequentialTestingEnabled?: boolean | undefined;
>                 sequentialTestingTuningParameter?: number | undefined;
>                 /** When null, the organization default is used. */
>                 postStratificationEnabled?: (boolean | null) | undefined;
>                 /** Controls the decision framework and metric overrides for the experiment. Replaces the entire stored object on update (does not patch individual fields). */
>                 decisionFrameworkSettings?: {
>                     decisionCriteriaId?: string | undefined;
>                     decisionFrameworkMetricOverrides?: {
>                         /** ID of the metric to override settings for. */
>                         id: string;
>                         /** The target relative MDE to use for the metric, expressed as proportions (e.g. use 0.1 for 10%). Must be greater than 0. */
>                         targetMDE?: number | undefined;
>                     }[] | undefined;
>                 } | undefined;
>                 /** Per-metric analysis overrides; also reflected in goals/secondaryMetrics/guardrails overrides when applicable. On create/update, this replaces the entire stored array (it does not patch individual entries). */
>                 metricOverrides?: {
>                     /** ID of the metric to override settings for. */
>                     id: string;
>                     windowType?: ("conversion" | "lookback" | "") | undefined;
>                     windowHours?: number | undefined;
>                     delayHours?: number | undefined;
>                     /** Must be true for the override to take effect. If true, the other proper prior settings in this object will be used if present. */
>                     properPriorOverride?: boolean | undefined;
>                     properPriorEnabled?: boolean | undefined;
>                     properPriorMean?: number | undefined;
>                     properPriorStdDev?: number | undefined;
>                     /** Must be true for the override to take effect. If true, the other regression adjustment settings in this object will be used if present. */
>                     regressionAdjustmentOverride?: boolean | undefined;
>                     regressionAdjustmentEnabled?: boolean | undefined;
>                     regressionAdjustmentDays?: number | undefined;
>                 }[] | undefined;
>                 goals: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 secondaryMetrics: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 guardrails: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 activationMetric?: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 } | undefined;
>             };
>             resultSummary?: {
>                 status: string;
>                 winner: string;
>                 conclusions: string;
>                 releasedVariationId: string;
>                 excludeFromPayload: boolean;
>             } | undefined;
>             shareLevel?: ("public" | "organization") | undefined;
>             publicUrl?: string | undefined;
>             banditScheduleValue?: number | undefined;
>             banditScheduleUnit?: ("days" | "hours") | undefined;
>             banditBurnInValue?: number | undefined;
>             banditBurnInUnit?: ("days" | "hours") | undefined;
>             banditConversionWindowValue?: number | undefined;
>             banditConversionWindowUnit?: ("days" | "hours") | undefined;
>             linkedFeatures?: string[] | undefined;
>             attributeScopeAllProjects?: boolean | undefined;
>             hasVisualChangesets?: boolean | undefined;
>             hasURLRedirects?: boolean | undefined;
>             customFields?: Record<string, any> | undefined;
>             /** Custom slices that apply to ALL applicable metrics in the experiment */
>             customMetricSlices?: {
>                 slices: {
>                     column: string;
>                     levels: string[];
>                 }[];
>             }[] | undefined;
>             precomputedUnitDimensionIds?: string[] | undefined;
>             /** ID of the default dashboard for this experiment. */
>             defaultDashboardId?: string | undefined;
>             templateId?: string | undefined;
>             statusUpdateSchedule?: ({
>                 startAt?: string | undefined;
>                 stopAt?: string | undefined;
>                 /** Relative end offset. Deferred: resolved to a concrete `stopAt` at the experiment's actual start (or off `dateStarted` when already running). */
>                 stopAfter?: {
>                     value: number;
>                     unit: "hours" | "days";
>                 } | undefined;
>                 /** What happens at the scheduled end date. `notify` keeps the experiment running and just notifies (soft). `auto-ship` (requires the Decision Framework) ships the winning variation and stops; multi-winner ties break on `tiebreakerMetricId` (higher lift); with no clear winner, `fallback` either keeps running (`notify`) or ships `fallbackVariationId`. `force-ship` stops and rolls out `fallbackVariationId`. `stop` is a hard deadline that stops with no rollout. For `force-ship` and `stop`, the Decision Framework verdict (won/lost/inconclusive) is recorded as metadata when available. */
>                 scheduledStopPlan?: {
>                     mode: "notify" | "auto-ship" | "force-ship" | "stop";
>                     tiebreakerMetricId?: string | undefined;
>                     /** What to do at the scheduled end when there is no clear winner. Required when `mode` is `"auto-ship"`; ignored for other modes. */
>                     fallback?: ("notify" | "force-ship") | undefined;
>                     fallbackVariationId?: string | undefined;
>                 } | undefined;
>             } | null) | undefined;
>             nextScheduledStatusUpdate?: ({
>                 type: "start" | "stop";
>                 date: string;
>             } | null) | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.updated

Triggered when an experiment is updated

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.updated";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             trackingKey: string;
>             dateCreated: string;
>             dateUpdated: string;
>             name: string;
>             type: "standard" | "multi-armed-bandit" | "holdout";
>             project: string;
>             hypothesis: string;
>             description: string;
>             tags: string[];
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner: string;
>             ownerEmail?: string | undefined;
>             archived: boolean;
>             status: string;
>             autoRefresh: boolean;
>             hashAttribute: string;
>             fallbackAttribute?: string | undefined;
>             hashVersion: 1 | 2;
>             disableStickyBucketing?: boolean | undefined;
>             bucketVersion?: number | undefined;
>             minBucketVersion?: number | undefined;
>             variations: {
>                 variationId: string;
>                 key: string;
>                 name: string;
>                 description: string;
>                 screenshots: string[];
>             }[];
>             phases: {
>                 name: string;
>                 dateStarted: string;
>                 dateEnded: string;
>                 reasonForStopping: string;
>                 seed: string;
>                 coverage: number;
>                 trafficSplit: {
>                     variationId: string;
>                     weight: number;
>                 }[];
>                 namespace?: {
>                     namespaceId: string;
>                     enabled?: boolean | undefined;
>                     range?: number[] | undefined;
>                     ranges?: [
>                         number,
>                         number
>                     ][] | undefined;
>                 } | undefined;
>                 targetingCondition: string;
>                 prerequisites?: {
>                     id: string;
>                     condition: string;
>                 }[] | undefined;
>                 savedGroupTargeting?: {
>                     matchType: "all" | "any" | "none";
>                     savedGroups: string[];
>                 }[] | undefined;
>             }[];
>             settings: {
>                 datasourceId: string;
>                 /** The assignment query, grouping its ID with the identifier type analyzed on. */
>                 assignmentQuery: {
>                     /** The ID of one of the data source's assignment queries. */
>                     id: string;
>                     /** The identifier type analyzed on. Null when none can be resolved: no assignment query is selected, or a record saved before identifier types were stored points at a query that no longer exists. */
>                     identifierType: string | null;
>                 };
>                 /** Deprecated: use `assignmentQuery`. */
>                 assignmentQueryId: string;
>                 experimentId: string;
>                 segmentId: string;
>                 queryFilter: string;
>                 inProgressConversions: "include" | "exclude";
>                 /** Setting attribution model to `"experimentDuration"` is the same as selecting "Ignore Conversion Windows" for the Conversion Window Override. Setting it to `"lookbackOverride"` requires a `lookbackOverride` object to be provided. */
>                 attributionModel: "firstExposure" | "experimentDuration" | "lookbackOverride";
>                 /** Controls the lookback override for the experiment. For type "window", value must be a non-negative number and valueUnit is required. */
>                 lookbackOverride?: {
>                     type: "date" | "window";
>                     /** For "window" type - non-negative numeric value (e.g. 7 for 7 days). For "date" type a date string. */
>                     value: number | string;
>                     /** Used when type is "window". Defaults to "days". */
>                     valueUnit?: ("minutes" | "hours" | "days" | "weeks") | undefined;
>                 } | undefined;
>                 statsEngine: "bayesian" | "frequentist";
>                 regressionAdjustmentEnabled?: boolean | undefined;
>                 sequentialTestingEnabled?: boolean | undefined;
>                 sequentialTestingTuningParameter?: number | undefined;
>                 /** When null, the organization default is used. */
>                 postStratificationEnabled?: (boolean | null) | undefined;
>                 /** Controls the decision framework and metric overrides for the experiment. Replaces the entire stored object on update (does not patch individual fields). */
>                 decisionFrameworkSettings?: {
>                     decisionCriteriaId?: string | undefined;
>                     decisionFrameworkMetricOverrides?: {
>                         /** ID of the metric to override settings for. */
>                         id: string;
>                         /** The target relative MDE to use for the metric, expressed as proportions (e.g. use 0.1 for 10%). Must be greater than 0. */
>                         targetMDE?: number | undefined;
>                     }[] | undefined;
>                 } | undefined;
>                 /** Per-metric analysis overrides; also reflected in goals/secondaryMetrics/guardrails overrides when applicable. On create/update, this replaces the entire stored array (it does not patch individual entries). */
>                 metricOverrides?: {
>                     /** ID of the metric to override settings for. */
>                     id: string;
>                     windowType?: ("conversion" | "lookback" | "") | undefined;
>                     windowHours?: number | undefined;
>                     delayHours?: number | undefined;
>                     /** Must be true for the override to take effect. If true, the other proper prior settings in this object will be used if present. */
>                     properPriorOverride?: boolean | undefined;
>                     properPriorEnabled?: boolean | undefined;
>                     properPriorMean?: number | undefined;
>                     properPriorStdDev?: number | undefined;
>                     /** Must be true for the override to take effect. If true, the other regression adjustment settings in this object will be used if present. */
>                     regressionAdjustmentOverride?: boolean | undefined;
>                     regressionAdjustmentEnabled?: boolean | undefined;
>                     regressionAdjustmentDays?: number | undefined;
>                 }[] | undefined;
>                 goals: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 secondaryMetrics: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 guardrails: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 activationMetric?: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 } | undefined;
>             };
>             resultSummary?: {
>                 status: string;
>                 winner: string;
>                 conclusions: string;
>                 releasedVariationId: string;
>                 excludeFromPayload: boolean;
>             } | undefined;
>             shareLevel?: ("public" | "organization") | undefined;
>             publicUrl?: string | undefined;
>             banditScheduleValue?: number | undefined;
>             banditScheduleUnit?: ("days" | "hours") | undefined;
>             banditBurnInValue?: number | undefined;
>             banditBurnInUnit?: ("days" | "hours") | undefined;
>             banditConversionWindowValue?: number | undefined;
>             banditConversionWindowUnit?: ("days" | "hours") | undefined;
>             linkedFeatures?: string[] | undefined;
>             attributeScopeAllProjects?: boolean | undefined;
>             hasVisualChangesets?: boolean | undefined;
>             hasURLRedirects?: boolean | undefined;
>             customFields?: Record<string, any> | undefined;
>             /** Custom slices that apply to ALL applicable metrics in the experiment */
>             customMetricSlices?: {
>                 slices: {
>                     column: string;
>                     levels: string[];
>                 }[];
>             }[] | undefined;
>             precomputedUnitDimensionIds?: string[] | undefined;
>             /** ID of the default dashboard for this experiment. */
>             defaultDashboardId?: string | undefined;
>             templateId?: string | undefined;
>             statusUpdateSchedule?: ({
>                 startAt?: string | undefined;
>                 stopAt?: string | undefined;
>                 /** Relative end offset. Deferred: resolved to a concrete `stopAt` at the experiment's actual start (or off `dateStarted` when already running). */
>                 stopAfter?: {
>                     value: number;
>                     unit: "hours" | "days";
>                 } | undefined;
>                 /** What happens at the scheduled end date. `notify` keeps the experiment running and just notifies (soft). `auto-ship` (requires the Decision Framework) ships the winning variation and stops; multi-winner ties break on `tiebreakerMetricId` (higher lift); with no clear winner, `fallback` either keeps running (`notify`) or ships `fallbackVariationId`. `force-ship` stops and rolls out `fallbackVariationId`. `stop` is a hard deadline that stops with no rollout. For `force-ship` and `stop`, the Decision Framework verdict (won/lost/inconclusive) is recorded as metadata when available. */
>                 scheduledStopPlan?: {
>                     mode: "notify" | "auto-ship" | "force-ship" | "stop";
>                     tiebreakerMetricId?: string | undefined;
>                     /** What to do at the scheduled end when there is no clear winner. Required when `mode` is `"auto-ship"`; ignored for other modes. */
>                     fallback?: ("notify" | "force-ship") | undefined;
>                     fallbackVariationId?: string | undefined;
>                 } | undefined;
>             } | null) | undefined;
>             nextScheduledStatusUpdate?: ({
>                 type: "start" | "stop";
>                 date: string;
>             } | null) | undefined;
>         };
>         previous_attributes: {
>             id?: string | undefined;
>             trackingKey?: string | undefined;
>             dateCreated?: string | undefined;
>             dateUpdated?: string | undefined;
>             name?: string | undefined;
>             type?: ("standard" | "multi-armed-bandit" | "holdout") | undefined;
>             project?: string | undefined;
>             hypothesis?: string | undefined;
>             description?: string | undefined;
>             tags?: string[] | undefined;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             archived?: boolean | undefined;
>             status?: string | undefined;
>             autoRefresh?: boolean | undefined;
>             hashAttribute?: string | undefined;
>             fallbackAttribute?: string | undefined;
>             hashVersion?: (1 | 2) | undefined;
>             disableStickyBucketing?: boolean | undefined;
>             bucketVersion?: number | undefined;
>             minBucketVersion?: number | undefined;
>             variations?: {
>                 variationId: string;
>                 key: string;
>                 name: string;
>                 description: string;
>                 screenshots: string[];
>             }[] | undefined;
>             phases?: {
>                 name: string;
>                 dateStarted: string;
>                 dateEnded: string;
>                 reasonForStopping: string;
>                 seed: string;
>                 coverage: number;
>                 trafficSplit: {
>                     variationId: string;
>                     weight: number;
>                 }[];
>                 namespace?: {
>                     namespaceId: string;
>                     enabled?: boolean | undefined;
>                     range?: number[] | undefined;
>                     ranges?: [
>                         number,
>                         number
>                     ][] | undefined;
>                 } | undefined;
>                 targetingCondition: string;
>                 prerequisites?: {
>                     id: string;
>                     condition: string;
>                 }[] | undefined;
>                 savedGroupTargeting?: {
>                     matchType: "all" | "any" | "none";
>                     savedGroups: string[];
>                 }[] | undefined;
>             }[] | undefined;
>             settings?: {
>                 datasourceId: string;
>                 /** The assignment query, grouping its ID with the identifier type analyzed on. */
>                 assignmentQuery: {
>                     /** The ID of one of the data source's assignment queries. */
>                     id: string;
>                     /** The identifier type analyzed on. Null when none can be resolved: no assignment query is selected, or a record saved before identifier types were stored points at a query that no longer exists. */
>                     identifierType: string | null;
>                 };
>                 /** Deprecated: use `assignmentQuery`. */
>                 assignmentQueryId: string;
>                 experimentId: string;
>                 segmentId: string;
>                 queryFilter: string;
>                 inProgressConversions: "include" | "exclude";
>                 /** Setting attribution model to `"experimentDuration"` is the same as selecting "Ignore Conversion Windows" for the Conversion Window Override. Setting it to `"lookbackOverride"` requires a `lookbackOverride` object to be provided. */
>                 attributionModel: "firstExposure" | "experimentDuration" | "lookbackOverride";
>                 /** Controls the lookback override for the experiment. For type "window", value must be a non-negative number and valueUnit is required. */
>                 lookbackOverride?: {
>                     type: "date" | "window";
>                     /** For "window" type - non-negative numeric value (e.g. 7 for 7 days). For "date" type a date string. */
>                     value: number | string;
>                     /** Used when type is "window". Defaults to "days". */
>                     valueUnit?: ("minutes" | "hours" | "days" | "weeks") | undefined;
>                 } | undefined;
>                 statsEngine: "bayesian" | "frequentist";
>                 regressionAdjustmentEnabled?: boolean | undefined;
>                 sequentialTestingEnabled?: boolean | undefined;
>                 sequentialTestingTuningParameter?: number | undefined;
>                 /** When null, the organization default is used. */
>                 postStratificationEnabled?: (boolean | null) | undefined;
>                 /** Controls the decision framework and metric overrides for the experiment. Replaces the entire stored object on update (does not patch individual fields). */
>                 decisionFrameworkSettings?: {
>                     decisionCriteriaId?: string | undefined;
>                     decisionFrameworkMetricOverrides?: {
>                         /** ID of the metric to override settings for. */
>                         id: string;
>                         /** The target relative MDE to use for the metric, expressed as proportions (e.g. use 0.1 for 10%). Must be greater than 0. */
>                         targetMDE?: number | undefined;
>                     }[] | undefined;
>                 } | undefined;
>                 /** Per-metric analysis overrides; also reflected in goals/secondaryMetrics/guardrails overrides when applicable. On create/update, this replaces the entire stored array (it does not patch individual entries). */
>                 metricOverrides?: {
>                     /** ID of the metric to override settings for. */
>                     id: string;
>                     windowType?: ("conversion" | "lookback" | "") | undefined;
>                     windowHours?: number | undefined;
>                     delayHours?: number | undefined;
>                     /** Must be true for the override to take effect. If true, the other proper prior settings in this object will be used if present. */
>                     properPriorOverride?: boolean | undefined;
>                     properPriorEnabled?: boolean | undefined;
>                     properPriorMean?: number | undefined;
>                     properPriorStdDev?: number | undefined;
>                     /** Must be true for the override to take effect. If true, the other regression adjustment settings in this object will be used if present. */
>                     regressionAdjustmentOverride?: boolean | undefined;
>                     regressionAdjustmentEnabled?: boolean | undefined;
>                     regressionAdjustmentDays?: number | undefined;
>                 }[] | undefined;
>                 goals: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 secondaryMetrics: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 guardrails: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 activationMetric?: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 } | undefined;
>             } | undefined;
>             resultSummary?: {
>                 status: string;
>                 winner: string;
>                 conclusions: string;
>                 releasedVariationId: string;
>                 excludeFromPayload: boolean;
>             } | undefined;
>             shareLevel?: ("public" | "organization") | undefined;
>             publicUrl?: string | undefined;
>             banditScheduleValue?: number | undefined;
>             banditScheduleUnit?: ("days" | "hours") | undefined;
>             banditBurnInValue?: number | undefined;
>             banditBurnInUnit?: ("days" | "hours") | undefined;
>             banditConversionWindowValue?: number | undefined;
>             banditConversionWindowUnit?: ("days" | "hours") | undefined;
>             linkedFeatures?: string[] | undefined;
>             attributeScopeAllProjects?: boolean | undefined;
>             hasVisualChangesets?: boolean | undefined;
>             hasURLRedirects?: boolean | undefined;
>             customFields?: Record<string, any> | undefined;
>             /** Custom slices that apply to ALL applicable metrics in the experiment */
>             customMetricSlices?: {
>                 slices: {
>                     column: string;
>                     levels: string[];
>                 }[];
>             }[] | undefined;
>             precomputedUnitDimensionIds?: string[] | undefined;
>             /** ID of the default dashboard for this experiment. */
>             defaultDashboardId?: string | undefined;
>             templateId?: string | undefined;
>             statusUpdateSchedule?: ({
>                 startAt?: string | undefined;
>                 stopAt?: string | undefined;
>                 /** Relative end offset. Deferred: resolved to a concrete `stopAt` at the experiment's actual start (or off `dateStarted` when already running). */
>                 stopAfter?: {
>                     value: number;
>                     unit: "hours" | "days";
>                 } | undefined;
>                 /** What happens at the scheduled end date. `notify` keeps the experiment running and just notifies (soft). `auto-ship` (requires the Decision Framework) ships the winning variation and stops; multi-winner ties break on `tiebreakerMetricId` (higher lift); with no clear winner, `fallback` either keeps running (`notify`) or ships `fallbackVariationId`. `force-ship` stops and rolls out `fallbackVariationId`. `stop` is a hard deadline that stops with no rollout. For `force-ship` and `stop`, the Decision Framework verdict (won/lost/inconclusive) is recorded as metadata when available. */
>                 scheduledStopPlan?: {
>                     mode: "notify" | "auto-ship" | "force-ship" | "stop";
>                     tiebreakerMetricId?: string | undefined;
>                     /** What to do at the scheduled end when there is no clear winner. Required when `mode` is `"auto-ship"`; ignored for other modes. */
>                     fallback?: ("notify" | "force-ship") | undefined;
>                     fallbackVariationId?: string | undefined;
>                 } | undefined;
>             } | null) | undefined;
>             nextScheduledStatusUpdate?: ({
>                 type: "start" | "stop";
>                 date: string;
>             } | null) | undefined;
>         };
>         changes?: {
>             added: Record<string, unknown>;
>             removed: Record<string, unknown>;
>             modified: unknown[];
>         } | undefined;
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.deleted

Triggered when an experiment is deleted

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.deleted";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             trackingKey: string;
>             dateCreated: string;
>             dateUpdated: string;
>             name: string;
>             type: "standard" | "multi-armed-bandit" | "holdout";
>             project: string;
>             hypothesis: string;
>             description: string;
>             tags: string[];
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner: string;
>             ownerEmail?: string | undefined;
>             archived: boolean;
>             status: string;
>             autoRefresh: boolean;
>             hashAttribute: string;
>             fallbackAttribute?: string | undefined;
>             hashVersion: 1 | 2;
>             disableStickyBucketing?: boolean | undefined;
>             bucketVersion?: number | undefined;
>             minBucketVersion?: number | undefined;
>             variations: {
>                 variationId: string;
>                 key: string;
>                 name: string;
>                 description: string;
>                 screenshots: string[];
>             }[];
>             phases: {
>                 name: string;
>                 dateStarted: string;
>                 dateEnded: string;
>                 reasonForStopping: string;
>                 seed: string;
>                 coverage: number;
>                 trafficSplit: {
>                     variationId: string;
>                     weight: number;
>                 }[];
>                 namespace?: {
>                     namespaceId: string;
>                     enabled?: boolean | undefined;
>                     range?: number[] | undefined;
>                     ranges?: [
>                         number,
>                         number
>                     ][] | undefined;
>                 } | undefined;
>                 targetingCondition: string;
>                 prerequisites?: {
>                     id: string;
>                     condition: string;
>                 }[] | undefined;
>                 savedGroupTargeting?: {
>                     matchType: "all" | "any" | "none";
>                     savedGroups: string[];
>                 }[] | undefined;
>             }[];
>             settings: {
>                 datasourceId: string;
>                 /** The assignment query, grouping its ID with the identifier type analyzed on. */
>                 assignmentQuery: {
>                     /** The ID of one of the data source's assignment queries. */
>                     id: string;
>                     /** The identifier type analyzed on. Null when none can be resolved: no assignment query is selected, or a record saved before identifier types were stored points at a query that no longer exists. */
>                     identifierType: string | null;
>                 };
>                 /** Deprecated: use `assignmentQuery`. */
>                 assignmentQueryId: string;
>                 experimentId: string;
>                 segmentId: string;
>                 queryFilter: string;
>                 inProgressConversions: "include" | "exclude";
>                 /** Setting attribution model to `"experimentDuration"` is the same as selecting "Ignore Conversion Windows" for the Conversion Window Override. Setting it to `"lookbackOverride"` requires a `lookbackOverride` object to be provided. */
>                 attributionModel: "firstExposure" | "experimentDuration" | "lookbackOverride";
>                 /** Controls the lookback override for the experiment. For type "window", value must be a non-negative number and valueUnit is required. */
>                 lookbackOverride?: {
>                     type: "date" | "window";
>                     /** For "window" type - non-negative numeric value (e.g. 7 for 7 days). For "date" type a date string. */
>                     value: number | string;
>                     /** Used when type is "window". Defaults to "days". */
>                     valueUnit?: ("minutes" | "hours" | "days" | "weeks") | undefined;
>                 } | undefined;
>                 statsEngine: "bayesian" | "frequentist";
>                 regressionAdjustmentEnabled?: boolean | undefined;
>                 sequentialTestingEnabled?: boolean | undefined;
>                 sequentialTestingTuningParameter?: number | undefined;
>                 /** When null, the organization default is used. */
>                 postStratificationEnabled?: (boolean | null) | undefined;
>                 /** Controls the decision framework and metric overrides for the experiment. Replaces the entire stored object on update (does not patch individual fields). */
>                 decisionFrameworkSettings?: {
>                     decisionCriteriaId?: string | undefined;
>                     decisionFrameworkMetricOverrides?: {
>                         /** ID of the metric to override settings for. */
>                         id: string;
>                         /** The target relative MDE to use for the metric, expressed as proportions (e.g. use 0.1 for 10%). Must be greater than 0. */
>                         targetMDE?: number | undefined;
>                     }[] | undefined;
>                 } | undefined;
>                 /** Per-metric analysis overrides; also reflected in goals/secondaryMetrics/guardrails overrides when applicable. On create/update, this replaces the entire stored array (it does not patch individual entries). */
>                 metricOverrides?: {
>                     /** ID of the metric to override settings for. */
>                     id: string;
>                     windowType?: ("conversion" | "lookback" | "") | undefined;
>                     windowHours?: number | undefined;
>                     delayHours?: number | undefined;
>                     /** Must be true for the override to take effect. If true, the other proper prior settings in this object will be used if present. */
>                     properPriorOverride?: boolean | undefined;
>                     properPriorEnabled?: boolean | undefined;
>                     properPriorMean?: number | undefined;
>                     properPriorStdDev?: number | undefined;
>                     /** Must be true for the override to take effect. If true, the other regression adjustment settings in this object will be used if present. */
>                     regressionAdjustmentOverride?: boolean | undefined;
>                     regressionAdjustmentEnabled?: boolean | undefined;
>                     regressionAdjustmentDays?: number | undefined;
>                 }[] | undefined;
>                 goals: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 secondaryMetrics: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 guardrails: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 }[];
>                 activationMetric?: {
>                     metricId: string;
>                     overrides: {
>                         delayHours?: number | undefined;
>                         windowHours?: number | undefined;
>                         window?: ("conversion" | "lookback" | "") | undefined;
>                         winRiskThreshold?: number | undefined;
>                         loseRiskThreshold?: number | undefined;
>                         properPriorOverride?: boolean | undefined;
>                         properPriorEnabled?: boolean | undefined;
>                         properPriorMean?: number | undefined;
>                         properPriorStdDev?: number | undefined;
>                         regressionAdjustmentOverride?: boolean | undefined;
>                         regressionAdjustmentEnabled?: boolean | undefined;
>                         regressionAdjustmentDays?: number | undefined;
>                     };
>                 } | undefined;
>             };
>             resultSummary?: {
>                 status: string;
>                 winner: string;
>                 conclusions: string;
>                 releasedVariationId: string;
>                 excludeFromPayload: boolean;
>             } | undefined;
>             shareLevel?: ("public" | "organization") | undefined;
>             publicUrl?: string | undefined;
>             banditScheduleValue?: number | undefined;
>             banditScheduleUnit?: ("days" | "hours") | undefined;
>             banditBurnInValue?: number | undefined;
>             banditBurnInUnit?: ("days" | "hours") | undefined;
>             banditConversionWindowValue?: number | undefined;
>             banditConversionWindowUnit?: ("days" | "hours") | undefined;
>             linkedFeatures?: string[] | undefined;
>             attributeScopeAllProjects?: boolean | undefined;
>             hasVisualChangesets?: boolean | undefined;
>             hasURLRedirects?: boolean | undefined;
>             customFields?: Record<string, any> | undefined;
>             /** Custom slices that apply to ALL applicable metrics in the experiment */
>             customMetricSlices?: {
>                 slices: {
>                     column: string;
>                     levels: string[];
>                 }[];
>             }[] | undefined;
>             precomputedUnitDimensionIds?: string[] | undefined;
>             /** ID of the default dashboard for this experiment. */
>             defaultDashboardId?: string | undefined;
>             templateId?: string | undefined;
>             statusUpdateSchedule?: ({
>                 startAt?: string | undefined;
>                 stopAt?: string | undefined;
>                 /** Relative end offset. Deferred: resolved to a concrete `stopAt` at the experiment's actual start (or off `dateStarted` when already running). */
>                 stopAfter?: {
>                     value: number;
>                     unit: "hours" | "days";
>                 } | undefined;
>                 /** What happens at the scheduled end date. `notify` keeps the experiment running and just notifies (soft). `auto-ship` (requires the Decision Framework) ships the winning variation and stops; multi-winner ties break on `tiebreakerMetricId` (higher lift); with no clear winner, `fallback` either keeps running (`notify`) or ships `fallbackVariationId`. `force-ship` stops and rolls out `fallbackVariationId`. `stop` is a hard deadline that stops with no rollout. For `force-ship` and `stop`, the Decision Framework verdict (won/lost/inconclusive) is recorded as metadata when available. */
>                 scheduledStopPlan?: {
>                     mode: "notify" | "auto-ship" | "force-ship" | "stop";
>                     tiebreakerMetricId?: string | undefined;
>                     /** What to do at the scheduled end when there is no clear winner. Required when `mode` is `"auto-ship"`; ignored for other modes. */
>                     fallback?: ("notify" | "force-ship") | undefined;
>                     fallbackVariationId?: string | undefined;
>                 } | undefined;
>             } | null) | undefined;
>             nextScheduledStatusUpdate?: ({
>                 type: "start" | "stop";
>                 date: string;
>             } | null) | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.warning

Triggered when a warning condition is detected on an experiment, such as a sample ratio mismatch, multiple exposures, low power, no data, or a failed results update. The `type` field identifies the condition.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.warning";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             type: "auto-update";
>             success: boolean;
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             experimentId: string;
>         } | {
>             type: "update-failed";
>             experimentId: string;
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             cause: "query" | "analysis" | "no-queries" | "unknown";
>         } | {
>             type: "multiple-exposures";
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             experimentId: string;
>             usersCount: number;
>             percent: number;
>         } | {
>             type: "srm";
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             experimentId: string;
>             threshold: number;
>             pValue?: number | undefined;
>             variations?: {
>                 name: string;
>                 users: number;
>                 weight: number;
>             }[] | undefined;
>             durationDays?: number | undefined;
>         } | {
>             type: "no-data";
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             experimentId: string;
>         } | {
>             type: "scheduled-status-update-failed";
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             experimentId: string;
>             scheduledStatusUpdateType: "start" | "stop";
>             attempts: number;
>             maxAttempts: number;
>             willRetry: boolean;
>             reason: string;
>         } | {
>             type: "underpowered";
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             experimentId: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.status.started

Triggered when an experiment starts or resumes running.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.status.started";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             type: "started";
>             experimentId: string;
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             phaseName?: string | undefined;
>             goalMetricNames?: string[] | undefined;
>             linkedFeatureCount?: number | undefined;
>             visualChangesetCount?: number | undefined;
>             urlRedirectCount?: number | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.status.stopped

Triggered when an experiment stops, including its result and any temporary rollout.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.status.stopped";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             type: "stopped";
>             experimentId: string;
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             results?: ("dnf" | "won" | "lost" | "inconclusive") | undefined;
>             releasedVariationName?: string | undefined;
>             enableTemporaryRollout: boolean;
>             reason?: string | undefined;
>             winningVariationName?: string | undefined;
>             winningVariationIndex?: number | undefined;
>             totalUsers?: number | undefined;
>             durationDays?: number | undefined;
>             goalMetric?: {
>                 metricId: string;
>                 metricName: string;
>                 inverse?: boolean | undefined;
>                 snapshotId: string;
>                 statsEngine: "bayesian" | "frequentist";
>                 pValueThreshold?: number | undefined;
>                 differenceType: string;
>                 control: {
>                     variationId: string;
>                     variationName: string;
>                     users?: number | undefined;
>                     value: number;
>                 };
>                 variations: {
>                     variationId: string;
>                     variationName: string;
>                     variationIndex: number;
>                     users?: number | undefined;
>                     value: number;
>                     uplift?: number | undefined;
>                     upliftStddev?: number | undefined;
>                     ci?: [
>                         number,
>                         number
>                     ] | undefined;
>                     chanceToWin?: number | undefined;
>                     pValue?: number | undefined;
>                     significant?: boolean | undefined;
>                 }[];
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.status.endingSoon

Triggered when a running experiment is within 3 days of its scheduled end date.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.status.endingSoon";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             type: "ending-soon";
>             experimentId: string;
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             endsAt: string;
>             daysRemaining: number;
>             durationDays?: number | undefined;
>             totalUsers?: number | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.status.stale

Triggered when a running experiment has been active for a long time without a decision.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.status.stale";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             type: "stale";
>             experimentId: string;
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             daysRunning: number;
>             totalUsers?: number | undefined;
>             reason: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.guardrailFailed

Triggered when a running experiment has a failing guardrail metric.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.guardrailFailed";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             type: "guardrail-failed";
>             experimentId: string;
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             failedMetrics: {
>                 id: string;
>                 name: string;
>                 variationName: string;
>             }[];
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.bandit.weightsChanged

Triggered when a multi-armed bandit materially changes variation weights.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.bandit.weightsChanged";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             type: "bandit-weights-changed";
>             experimentId: string;
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             currentWeights: number[];
>             updatedWeights: number[];
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.info.significance

Triggered when a goal or guardrail metric reaches significance in an experiment (e.g. either above 95% or below 5% chance to win). Be careful using this without Sequential Testing as it can lead to peeking problems.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.info.significance";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             experimentId: string;
>             variationId: string;
>             variationName: string;
>             metricName: string;
>             metricId: string;
>             statsEngine: string;
>             criticalValue: number;
>             winning: boolean;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.info.scheduled-status-update

Triggered when a scheduled start or stop is automatically applied to an experiment, including the auto-ship outcome for a scheduled end.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.info.scheduled-status-update";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             experimentId: string;
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             action: "started" | "stopped" | "kept-running";
>             shipped?: boolean | undefined;
>             shippedVariationId?: string | undefined;
>             shippedVariationName?: string | undefined;
>             forced?: boolean | undefined;
>             recommendedVariationId?: string | undefined;
>             recommendedVariationName?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.decision.ship

Triggered when an experiment is ready to ship a variation.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.decision.ship";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             experimentId: string;
>             decisionDescription?: string | undefined;
>             source: "scheduled-end" | "analysis";
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.decision.rollback

Triggered when an experiment should be rolled back to the control.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.decision.rollback";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             experimentId: string;
>             decisionDescription?: string | undefined;
>             source: "scheduled-end" | "analysis";
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### experiment.decision.review

Triggered when an experiment has reached the desired power point, but the results may be ambiguous.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "experiment.decision.review";
>     object: "experiment";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             experimentName: string;
>             ownerEmail?: string | undefined;
>             experimentId: string;
>             decisionDescription?: string | undefined;
>             source: "scheduled-end" | "analysis";
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### holdout.created

Triggered when a holdout is created.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "holdout.created";
>     object: "holdout";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             holdoutId: string;
>             holdoutName: string;
>             ownerEmail?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### holdout.status.changed

Triggered when a holdout moves between its lifecycle stages, such as running or analysis.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "holdout.status.changed";
>     object: "holdout";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             holdoutId: string;
>             holdoutName: string;
>             ownerEmail?: string | undefined;
>             previousStatus: "draft" | "running" | "analysis-period" | "stopped";
>             currentStatus: "draft" | "running" | "analysis-period" | "stopped";
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### holdout.config.newLinkage

Triggered when feature flags or experiments are linked to a holdout.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "holdout.config.newLinkage";
>     object: "holdout";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             holdoutId: string;
>             holdoutName: string;
>             ownerEmail?: string | undefined;
>             featureIds: string[];
>             experimentIds: string[];
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### sdkConnection.payloadSize.warning

Triggered when an SDK Connection's payload grows past half, 80%, or all of the 16 MB its cache can store. The `level` field is `warning`, `danger`, or `over-limit`, and `recommendations` lists ways to shrink it. Fires once per level reached, not on every publish.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "sdkConnection.payloadSize.warning";
>     object: "sdkConnection";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             connectionId: string;
>             connectionName: string;
>             environment: string;
>             projects: string[];
>             level: "warning" | "danger" | "over-limit";
>             bytes: number;
>             limitBytes: number;
>             message: string;
>             recommendations: {
>                 type: string;
>                 message: string;
>             }[];
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.created

Triggered when a saved group is created

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.created";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             type: "condition" | "list";
>             dateCreated: string;
>             dateUpdated: string;
>             name: string;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** When type = 'condition', this is the JSON-encoded condition for the group */
>             condition?: string | undefined;
>             /** When type = 'list', this is the attribute key the group is based on */
>             attributeKey?: string | undefined;
>             /** When type = 'list', this is the list of values for the attribute key */
>             values?: string[] | undefined;
>             description?: string | undefined;
>             projects?: string[] | undefined;
>             archived?: boolean | undefined;
>             useEmptyListGroup?: boolean | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.updated

Triggered when a saved group is updated

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.updated";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             type: "condition" | "list";
>             dateCreated: string;
>             dateUpdated: string;
>             name: string;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** When type = 'condition', this is the JSON-encoded condition for the group */
>             condition?: string | undefined;
>             /** When type = 'list', this is the attribute key the group is based on */
>             attributeKey?: string | undefined;
>             /** When type = 'list', this is the list of values for the attribute key */
>             values?: string[] | undefined;
>             description?: string | undefined;
>             projects?: string[] | undefined;
>             archived?: boolean | undefined;
>             useEmptyListGroup?: boolean | undefined;
>         };
>         previous_attributes: {
>             id?: string | undefined;
>             type?: ("condition" | "list") | undefined;
>             dateCreated?: string | undefined;
>             dateUpdated?: string | undefined;
>             name?: string | undefined;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** When type = 'condition', this is the JSON-encoded condition for the group */
>             condition?: string | undefined;
>             /** When type = 'list', this is the attribute key the group is based on */
>             attributeKey?: string | undefined;
>             /** When type = 'list', this is the list of values for the attribute key */
>             values?: string[] | undefined;
>             description?: string | undefined;
>             projects?: string[] | undefined;
>             archived?: boolean | undefined;
>             useEmptyListGroup?: boolean | undefined;
>         };
>         changes?: {
>             added: Record<string, unknown>;
>             removed: Record<string, unknown>;
>             modified: unknown[];
>         } | undefined;
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.deleted

Triggered when a saved group is deleted

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.deleted";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             type: "condition" | "list";
>             dateCreated: string;
>             dateUpdated: string;
>             name: string;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** When type = 'condition', this is the JSON-encoded condition for the group */
>             condition?: string | undefined;
>             /** When type = 'list', this is the attribute key the group is based on */
>             attributeKey?: string | undefined;
>             /** When type = 'list', this is the list of values for the attribute key */
>             values?: string[] | undefined;
>             description?: string | undefined;
>             projects?: string[] | undefined;
>             archived?: boolean | undefined;
>             useEmptyListGroup?: boolean | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.created

Triggered when a new draft revision is created for a saved group

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.created";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.updated

Triggered when a draft revision's proposed changes are modified (values, condition, archive, or metadata). The `change` field indicates the kind of mutation.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.updated";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             change: "metadata" | "condition" | "values" | "archive";
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.reviewRequested

Triggered when a draft revision is submitted for review

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.reviewRequested";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.approved

Triggered when a draft revision is approved by a reviewer

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.approved";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string | null;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.changesRequested

Triggered when a reviewer requests changes on a draft revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.changesRequested";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string | null;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.commented

Triggered when a comment is added to a draft revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.commented";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.discarded

Triggered when a draft revision is discarded

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.discarded";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.rebased

Triggered when a draft revision is rebased onto the latest live state

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.rebased";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.published

Triggered when a draft revision is published. Overlaps with `savedGroup.updated` but provides revision-specific context.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.published";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             bulkPublishId?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.reverted

Triggered when a saved group is reverted to a previous published revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.reverted";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             revertedToVersion?: number | undefined;
>             bulkPublishId?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.reopened

Triggered when a discarded revision is reopened

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.reopened";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.recalled

Triggered when the author (or an editor) recalls a review request, returning the revision to `draft`. Distinct from `revision.reopened`, which restores a discarded revision.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.recalled";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.reviewRetracted

Triggered when a reviewer retracts their own verdict. The status is recomputed from the verdicts that remain, so the revision may end up `pending-review`, or stay `approved` or `changes-requested` when another reviewer's verdict still stands. Carries no content change — the revision's proposed changes are untouched.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.reviewRetracted";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.publishScheduleChanged

Triggered when a deferred publish is armed, re-armed, or cancelled on a revision. Carries no content change.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.publishScheduleChanged";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### savedGroup.revision.publishFailed

Triggered when a deferred publish (scheduled publish or auto-publish-on-approval) is given up on after failing — terminally, or after exhausting retries. The draft is left open for a human to resolve.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "savedGroup.revision.publishFailed";
>     object: "savedGroup";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             savedGroup: {
>                 id: string;
>                 name: string;
>             };
>             baseSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             proposedSavedGroup: {
>                 id: string;
>                 type: "condition" | "list";
>                 dateCreated: string;
>                 dateUpdated: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** When type = 'condition', this is the JSON-encoded condition for the group */
>                 condition?: string | undefined;
>                 /** When type = 'list', this is the attribute key the group is based on */
>                 attributeKey?: string | undefined;
>                 /** When type = 'list', this is the list of values for the attribute key */
>                 values?: string[] | undefined;
>                 description?: string | undefined;
>                 projects?: string[] | undefined;
>                 archived?: boolean | undefined;
>                 useEmptyListGroup?: boolean | undefined;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             bulkPublishId?: string | undefined;
>             failureReason: string;
>             terminal: boolean;
>             attempts: number;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.created

Triggered when a constant is created

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.created";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             /** Stable reference handle; used as `@const:key` in values */
>             key: string;
>             name: string;
>             type: "string" | "json";
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>             value?: string | undefined;
>             /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>             environmentValues?: Record<string, string> | undefined;
>             description?: string | undefined;
>             /** The project this constant belongs to (empty = all projects) */
>             project?: string | undefined;
>             archived?: boolean | undefined;
>             dateCreated: string;
>             dateUpdated: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.updated

Triggered when a constant is updated

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.updated";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             /** Stable reference handle; used as `@const:key` in values */
>             key: string;
>             name: string;
>             type: "string" | "json";
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>             value?: string | undefined;
>             /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>             environmentValues?: Record<string, string> | undefined;
>             description?: string | undefined;
>             /** The project this constant belongs to (empty = all projects) */
>             project?: string | undefined;
>             archived?: boolean | undefined;
>             dateCreated: string;
>             dateUpdated: string;
>         };
>         previous_attributes: {
>             id?: string | undefined;
>             /** Stable reference handle; used as `@const:key` in values */
>             key?: string | undefined;
>             name?: string | undefined;
>             type?: ("string" | "json") | undefined;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>             value?: string | undefined;
>             /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>             environmentValues?: Record<string, string> | undefined;
>             description?: string | undefined;
>             /** The project this constant belongs to (empty = all projects) */
>             project?: string | undefined;
>             archived?: boolean | undefined;
>             dateCreated?: string | undefined;
>             dateUpdated?: string | undefined;
>         };
>         changes?: {
>             added: Record<string, unknown>;
>             removed: Record<string, unknown>;
>             modified: unknown[];
>         } | undefined;
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.deleted

Triggered when a constant is deleted

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.deleted";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             /** Stable reference handle; used as `@const:key` in values */
>             key: string;
>             name: string;
>             type: "string" | "json";
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>             value?: string | undefined;
>             /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>             environmentValues?: Record<string, string> | undefined;
>             description?: string | undefined;
>             /** The project this constant belongs to (empty = all projects) */
>             project?: string | undefined;
>             archived?: boolean | undefined;
>             dateCreated: string;
>             dateUpdated: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.created

Triggered when a new draft revision is created for a constant

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.created";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.updated

Triggered when a draft revision's proposed changes are modified (value, archive, or metadata). The `change` field indicates the kind of mutation.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.updated";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             change: "metadata" | "value" | "archive";
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.reviewRequested

Triggered when a draft revision is submitted for review

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.reviewRequested";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.approved

Triggered when a draft revision is approved by a reviewer

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.approved";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string | null;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.changesRequested

Triggered when a reviewer requests changes on a draft revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.changesRequested";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string | null;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.commented

Triggered when a comment is added to a draft revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.commented";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.discarded

Triggered when a draft revision is discarded

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.discarded";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.rebased

Triggered when a draft revision is rebased onto the latest live state

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.rebased";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.published

Triggered when a draft revision is published. Overlaps with `constant.updated` but provides revision-specific context.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.published";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             bulkPublishId?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.reverted

Triggered when a constant is reverted to a previous published revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.reverted";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             revertedToVersion?: number | undefined;
>             bulkPublishId?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.reopened

Triggered when a discarded revision is reopened

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.reopened";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.recalled

Triggered when the author (or an editor) recalls a review request, returning the revision to `draft`. Distinct from `revision.reopened`, which restores a discarded revision.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.recalled";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.reviewRetracted

Triggered when a reviewer retracts their own verdict. The status is recomputed from the verdicts that remain, so the revision may end up `pending-review`, or stay `approved` or `changes-requested` when another reviewer's verdict still stands. Carries no content change — the revision's proposed changes are untouched.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.reviewRetracted";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.publishScheduleChanged

Triggered when a deferred publish is armed, re-armed, or cancelled on a revision. Carries no content change.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.publishScheduleChanged";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### constant.revision.publishFailed

Triggered when a deferred publish (scheduled publish or auto-publish-on-approval) is given up on after failing — terminally, or after exhausting retries. The draft is left open for a human to resolve.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "constant.revision.publishFailed";
>     object: "constant";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             constant: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConstant: {
>                 id: string;
>                 /** Stable reference handle; used as `@const:key` in values */
>                 key: string;
>                 name: string;
>                 type: "string" | "json";
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The default value (raw string for `string` constants, JSON-encoded for `json` constants) */
>                 value?: string | undefined;
>                 /** Per-environment value overrides (environment id → value). Falls back to `value` when an environment is absent. */
>                 environmentValues?: Record<string, string> | undefined;
>                 description?: string | undefined;
>                 /** The project this constant belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             bulkPublishId?: string | undefined;
>             failureReason: string;
>             terminal: boolean;
>             attempts: number;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.created

Triggered when a config is created

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.created";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             /** Stable reference handle; used as `@config:key` in values */
>             key: string;
>             name: string;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>             parent?: string | undefined;
>             /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>             extends?: string[] | undefined;
>             /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>             value?: Record<string, unknown> | undefined;
>             /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>             scopedOverrides?: {
>                 /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                 config: string;
>                 /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                 environments?: string[] | undefined;
>                 /** Project ids this entry applies to. Empty/omitted = any project. */
>                 projects?: string[] | undefined;
>             }[] | undefined;
>             /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>             scopedConfig?: {
>                 /** The base config this one is a scoped override of. */
>                 parent: string;
>                 /** Environments this override applies to (empty/absent = every environment). */
>                 environments?: string[] | undefined;
>                 /** Projects this override applies to (empty/absent = every project). */
>                 projects?: string[] | undefined;
>             } | undefined;
>             description?: string | undefined;
>             /** The project this config belongs to (empty = all projects) */
>             project?: string | undefined;
>             archived?: boolean | undefined;
>             /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>             schema?: {
>                 type: "json-schema";
>                 /** A JSON Schema document (an object). */
>                 value: Record<string, unknown>;
>             } | undefined;
>             /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>             extensible?: boolean | undefined;
>             /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>             invariants?: {
>                 /** Unique name for the rule. */
>                 name: string;
>                 /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                 rule: Record<string, unknown>;
>                 /** Human-readable error shown when the rule is violated. */
>                 message: string;
>             }[] | undefined;
>             /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>             locked?: boolean | undefined;
>             /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>             experimentGuard?: boolean | undefined;
>             /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>             lockedRevision?: {
>                 id: string;
>                 version: number;
>             } | undefined;
>             /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>             lockedBy?: string | undefined;
>             /** When the config was locked (when `locked`). */
>             dateLocked?: string | undefined;
>             dateCreated: string;
>             dateUpdated: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.updated

Triggered when a config is updated

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.updated";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             /** Stable reference handle; used as `@config:key` in values */
>             key: string;
>             name: string;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>             parent?: string | undefined;
>             /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>             extends?: string[] | undefined;
>             /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>             value?: Record<string, unknown> | undefined;
>             /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>             scopedOverrides?: {
>                 /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                 config: string;
>                 /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                 environments?: string[] | undefined;
>                 /** Project ids this entry applies to. Empty/omitted = any project. */
>                 projects?: string[] | undefined;
>             }[] | undefined;
>             /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>             scopedConfig?: {
>                 /** The base config this one is a scoped override of. */
>                 parent: string;
>                 /** Environments this override applies to (empty/absent = every environment). */
>                 environments?: string[] | undefined;
>                 /** Projects this override applies to (empty/absent = every project). */
>                 projects?: string[] | undefined;
>             } | undefined;
>             description?: string | undefined;
>             /** The project this config belongs to (empty = all projects) */
>             project?: string | undefined;
>             archived?: boolean | undefined;
>             /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>             schema?: {
>                 type: "json-schema";
>                 /** A JSON Schema document (an object). */
>                 value: Record<string, unknown>;
>             } | undefined;
>             /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>             extensible?: boolean | undefined;
>             /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>             invariants?: {
>                 /** Unique name for the rule. */
>                 name: string;
>                 /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                 rule: Record<string, unknown>;
>                 /** Human-readable error shown when the rule is violated. */
>                 message: string;
>             }[] | undefined;
>             /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>             locked?: boolean | undefined;
>             /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>             experimentGuard?: boolean | undefined;
>             /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>             lockedRevision?: {
>                 id: string;
>                 version: number;
>             } | undefined;
>             /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>             lockedBy?: string | undefined;
>             /** When the config was locked (when `locked`). */
>             dateLocked?: string | undefined;
>             dateCreated: string;
>             dateUpdated: string;
>         };
>         previous_attributes: {
>             id?: string | undefined;
>             /** Stable reference handle; used as `@config:key` in values */
>             key?: string | undefined;
>             name?: string | undefined;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>             parent?: string | undefined;
>             /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>             extends?: string[] | undefined;
>             /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>             value?: Record<string, unknown> | undefined;
>             /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>             scopedOverrides?: {
>                 /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                 config: string;
>                 /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                 environments?: string[] | undefined;
>                 /** Project ids this entry applies to. Empty/omitted = any project. */
>                 projects?: string[] | undefined;
>             }[] | undefined;
>             /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>             scopedConfig?: {
>                 /** The base config this one is a scoped override of. */
>                 parent: string;
>                 /** Environments this override applies to (empty/absent = every environment). */
>                 environments?: string[] | undefined;
>                 /** Projects this override applies to (empty/absent = every project). */
>                 projects?: string[] | undefined;
>             } | undefined;
>             description?: string | undefined;
>             /** The project this config belongs to (empty = all projects) */
>             project?: string | undefined;
>             archived?: boolean | undefined;
>             /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>             schema?: {
>                 type: "json-schema";
>                 /** A JSON Schema document (an object). */
>                 value: Record<string, unknown>;
>             } | undefined;
>             /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>             extensible?: boolean | undefined;
>             /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>             invariants?: {
>                 /** Unique name for the rule. */
>                 name: string;
>                 /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                 rule: Record<string, unknown>;
>                 /** Human-readable error shown when the rule is violated. */
>                 message: string;
>             }[] | undefined;
>             /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>             locked?: boolean | undefined;
>             /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>             experimentGuard?: boolean | undefined;
>             /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>             lockedRevision?: {
>                 id: string;
>                 version: number;
>             } | undefined;
>             /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>             lockedBy?: string | undefined;
>             /** When the config was locked (when `locked`). */
>             dateLocked?: string | undefined;
>             dateCreated?: string | undefined;
>             dateUpdated?: string | undefined;
>         };
>         changes?: {
>             added: Record<string, unknown>;
>             removed: Record<string, unknown>;
>             modified: unknown[];
>         } | undefined;
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.deleted

Triggered when a config is deleted

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.deleted";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             /** Stable reference handle; used as `@config:key` in values */
>             key: string;
>             name: string;
>             /** The userId of the owner (or raw owner name/email for legacy records) */
>             owner?: string | undefined;
>             ownerEmail?: string | undefined;
>             /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>             parent?: string | undefined;
>             /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>             extends?: string[] | undefined;
>             /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>             value?: Record<string, unknown> | undefined;
>             /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>             scopedOverrides?: {
>                 /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                 config: string;
>                 /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                 environments?: string[] | undefined;
>                 /** Project ids this entry applies to. Empty/omitted = any project. */
>                 projects?: string[] | undefined;
>             }[] | undefined;
>             /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>             scopedConfig?: {
>                 /** The base config this one is a scoped override of. */
>                 parent: string;
>                 /** Environments this override applies to (empty/absent = every environment). */
>                 environments?: string[] | undefined;
>                 /** Projects this override applies to (empty/absent = every project). */
>                 projects?: string[] | undefined;
>             } | undefined;
>             description?: string | undefined;
>             /** The project this config belongs to (empty = all projects) */
>             project?: string | undefined;
>             archived?: boolean | undefined;
>             /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>             schema?: {
>                 type: "json-schema";
>                 /** A JSON Schema document (an object). */
>                 value: Record<string, unknown>;
>             } | undefined;
>             /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>             extensible?: boolean | undefined;
>             /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>             invariants?: {
>                 /** Unique name for the rule. */
>                 name: string;
>                 /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                 rule: Record<string, unknown>;
>                 /** Human-readable error shown when the rule is violated. */
>                 message: string;
>             }[] | undefined;
>             /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>             locked?: boolean | undefined;
>             /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>             experimentGuard?: boolean | undefined;
>             /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>             lockedRevision?: {
>                 id: string;
>                 version: number;
>             } | undefined;
>             /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>             lockedBy?: string | undefined;
>             /** When the config was locked (when `locked`). */
>             dateLocked?: string | undefined;
>             dateCreated: string;
>             dateUpdated: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.created

Triggered when a new draft revision is created for a config

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.created";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.updated

Triggered when a draft revision's proposed changes are modified (value, schema, archive, or metadata). The `change` field indicates the kind of mutation.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.updated";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             change: "metadata" | "value" | "schema" | "archive";
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.reviewRequested

Triggered when a draft revision is submitted for review

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.reviewRequested";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.approved

Triggered when a draft revision is approved by a reviewer

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.approved";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string | null;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.changesRequested

Triggered when a reviewer requests changes on a draft revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.changesRequested";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string | null;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.commented

Triggered when a comment is added to a draft revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.commented";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             /** Who performed an action */
>             reviewer: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             };
>             reviewComment: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.discarded

Triggered when a draft revision is discarded

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.discarded";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.rebased

Triggered when a draft revision is rebased onto the latest live state

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.rebased";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.published

Triggered when a draft revision is published. Overlaps with `config.updated` but provides revision-specific context.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.published";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             bulkPublishId?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.reverted

Triggered when a config is reverted to a previous published revision

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.reverted";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             revertedToVersion?: number | undefined;
>             bulkPublishId?: string | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.reopened

Triggered when a discarded revision is reopened

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.reopened";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.recalled

Triggered when the author (or an editor) recalls a review request, returning the revision to `draft`. Distinct from `revision.reopened`, which restores a discarded revision.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.recalled";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.reviewRetracted

Triggered when a reviewer retracts their own verdict. The status is recomputed from the verdicts that remain, so the revision may end up `pending-review`, or stay `approved` or `changes-requested` when another reviewer's verdict still stands. Carries no content change — the revision's proposed changes are untouched.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.reviewRetracted";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.publishScheduleChanged

Triggered when a deferred publish is armed, re-armed, or cancelled on a revision. Carries no content change.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.publishScheduleChanged";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### config.revision.publishFailed

Triggered when a deferred publish (scheduled publish or auto-publish-on-approval) is given up on after failing — terminally, or after exhausting retries. The draft is left open for a human to resolve.

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "config.revision.publishFailed";
>     object: "config";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id?: string | undefined;
>             /** 0 for a revision saved before versions were recorded */
>             version: number;
>             /** The live version this revision is based on, or 0 if unknown */
>             baseVersion: number;
>             status: string;
>             title?: string | undefined;
>             /** The revision's description */
>             comment: string;
>             dateCreated: string;
>             dateUpdated: string;
>             /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>             authorId: string;
>             /** Who performed an action */
>             author?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             autoPublishOnApproval?: boolean | undefined;
>             autoPublishEnabledBy?: string | undefined;
>             /** Who performed an action */
>             autoPublishEnabledByUser?: {
>                 /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                 type: "dashboard" | "api_key" | "system";
>                 /** The member's user ID. Absent for an organization API key */
>                 id?: string | undefined;
>                 /** The API key's ID, when the action came through one */
>                 apiKey?: string | undefined;
>                 /** The member's name, or the organization API key's name */
>                 name?: string | undefined;
>                 /** The member's email. Absent for an organization API key */
>                 email?: string | undefined;
>                 /** The member named with `X-GrowthBook-Requested-By` */
>                 requestedBy?: {
>                     id: string;
>                     name: string;
>                     email: string;
>                 } | undefined;
>                 /** Whether the key assumed the named member's role */
>                 assumedRole?: boolean | undefined;
>             } | undefined;
>             scheduledPublishAt?: string | undefined;
>             scheduledPublishLockEdits?: boolean | undefined;
>             scheduledPublishLockOthers?: boolean | undefined;
>             scheduledPublishBypassApproval?: boolean | undefined;
>             scheduledPublishAttempts?: number | undefined;
>             scheduledPublishLastError?: string | undefined;
>             scheduledPublishGaveUpAt?: string | undefined;
>             config: {
>                 id: string;
>                 key: string;
>                 name: string;
>             };
>             baseConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             proposedConfig: {
>                 id: string;
>                 /** Stable reference handle; used as `@config:key` in values */
>                 key: string;
>                 name: string;
>                 /** The userId of the owner (or raw owner name/email for legacy records) */
>                 owner?: string | undefined;
>                 ownerEmail?: string | undefined;
>                 /** The `key` of the config this one inherits from (lineage parent — the primary spine). Synthesized into `$extends` at resolution time and never stored in `value`. */
>                 parent?: string | undefined;
>                 /** Additional composition bases (config `key`s) layered on top of `parent`, in precedence order (later overrides earlier; all override `parent`; this config's own keys win last). Like `parent`, set via this field — never via a `@config:` entry in `value`. */
>                 extends?: string[] | undefined;
>                 /** This config's own base value as a JSON object (its declared fields only — inherited fields are layered in at resolution time, not stored here). Per-environment/project variants are expressed via `scopedOverrides`, not here. */
>                 value?: Record<string, unknown> | undefined;
>                 /** Ordered, first-match-wins environment/project-scoped variant selection. Each entry points at a flavor config (a child config, by `key`) whose value is deep-merged onto this config's resolved value when the (environment, project) scope matches — resolved at build time, per layer. This is how you create an environment-scoped override (as opposed to a plain child config): make a child config for the override value, then add it here with its scope. Send the complete list to replace it; an empty array clears all overrides. Entries must reference existing configs, may not reference this config itself, and may not be unreachable (fully subsumed by an earlier entry). */
>                 scopedOverrides?: {
>                     /** The `key` of the flavor config (a child config) whose value patches this config when the scope matches. */
>                     config: string;
>                     /** Environment ids this entry applies to. Empty/omitted = any environment. */
>                     environments?: string[] | undefined;
>                     /** Project ids this entry applies to. Empty/omitted = any project. */
>                     projects?: string[] | undefined;
>                 }[] | undefined;
>                 /** Present ONLY when this config is an environment/project-scoped override (a "flavor") of another config. Its value is a patch that applies solely within the listed environments/projects, layered onto `parent` at resolution — it is NOT a standalone config. A plain config (including an ordinary child that just inherits from a `parent`) omits this field entirely. Read-only: create/change the relationship via the parent config's `scopedOverrides`, never by setting this directly. */
>                 scopedConfig?: {
>                     /** The base config this one is a scoped override of. */
>                     parent: string;
>                     /** Environments this override applies to (empty/absent = every environment). */
>                     environments?: string[] | undefined;
>                     /** Projects this override applies to (empty/absent = every project). */
>                     projects?: string[] | undefined;
>                 } | undefined;
>                 description?: string | undefined;
>                 /** The project this config belongs to (empty = all projects) */
>                 project?: string | undefined;
>                 archived?: boolean | undefined;
>                 /** This config's own field definitions as a JSON Schema document (its contribution to the family's effective schema). Inherited fields are owned by ancestors and are not repeated here. */
>                 schema?: {
>                     type: "json-schema";
>                     /** A JSON Schema document (an object). */
>                     value: Record<string, unknown>;
>                 } | undefined;
>                 /** Whether this config family permits extra keys beyond the declared fields (child configs, feature rules, ad-hoc overrides). Only the root config's flag applies. Absent = inherit the org default. */
>                 extensible?: boolean | undefined;
>                 /** Cross-field validation rules (relational checks JSON Schema can't express, e.g. implications or comparing two fields), evaluated against the resolved value at publish. */
>                 invariants?: {
>                     /** Unique name for the rule. */
>                     name: string;
>                     /** A mongo condition (mongrule) boolean expression over the config's fields. */
>                     rule: Record<string, unknown>;
>                     /** Human-readable error shown when the rule is violated. */
>                     message: string;
>                 }[] | undefined;
>                 /** Whether this Config is locked to a published revision. Drafts can still be created and edited while locked, but no change can be published until a user with Bypass draft approvals access unlocks it. */
>                 locked?: boolean | undefined;
>                 /** Whether the experiment guard is enabled. When enabled, publishing a value used by a running experiment returns a warning that must be acknowledged with `ignoreWarnings: true`. Disabling the guard requires Bypass draft approvals access. */
>                 experimentGuard?: boolean | undefined;
>                 /** The pinned published revision (present only when `locked`). Fetch it via `GET /configs-revisions/:key/:version` for a value guaranteed not to disappear or mutate — use it to pin reproducible builds. */
>                 lockedRevision?: {
>                     id: string;
>                     version: number;
>                 } | undefined;
>                 /** Who locked the config: a member's user ID, or an API key's ID when it acted as itself */
>                 lockedBy?: string | undefined;
>                 /** When the config was locked (when `locked`). */
>                 dateLocked?: string | undefined;
>                 dateCreated: string;
>                 dateUpdated: string;
>             };
>             /** The JSON Patch the draft applies, with each change's value */
>             proposedChanges: {
>                 op: string;
>                 path: string;
>             }[];
>             contributors?: string[] | undefined;
>             revertedFrom?: string | undefined;
>             reviews: {
>                 id: string;
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 decision: "approve" | "request-changes" | "comment";
>                 comment?: string | undefined;
>                 stale?: boolean | undefined;
>                 dateCreated: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>             }[];
>             resolution?: {
>                 action: "merged" | "discarded";
>                 /** Who acted: a member's user ID, or an API key's ID when it acted as itself */
>                 userId: string;
>                 /** Who performed an action */
>                 user?: {
>                     /** `dashboard` (signed-in member), `api_key` (API key or personal access token) or `system` */
>                     type: "dashboard" | "api_key" | "system";
>                     /** The member's user ID. Absent for an organization API key */
>                     id?: string | undefined;
>                     /** The API key's ID, when the action came through one */
>                     apiKey?: string | undefined;
>                     /** The member's name, or the organization API key's name */
>                     name?: string | undefined;
>                     /** The member's email. Absent for an organization API key */
>                     email?: string | undefined;
>                     /** The member named with `X-GrowthBook-Requested-By` */
>                     requestedBy?: {
>                         id: string;
>                         name: string;
>                         email: string;
>                     } | undefined;
>                     /** Whether the key assumed the named member's role */
>                     assumedRole?: boolean | undefined;
>                 } | undefined;
>                 dateCreated: string;
>             } | undefined;
>             bulkPublishId?: string | undefined;
>             failureReason: string;
>             terminal: boolean;
>             attempts: number;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### user.login

Triggered when a user logs in

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "user.login";
>     object: "user";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             email: string;
>             id: string;
>             name: string;
>             ip: string;
>             userAgent: string;
>             os: string;
>             device: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### apiKey.expiring

Triggered once when a secret API key is within a week of expiring

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "apiKey.expiring";
>     object: "apiKey";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             description?: string | undefined;
>             expiresAt: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```

### apiKey.expired

Triggered once when a secret API key passes its expiration date

> **Payload**
>
> ```typescript theme={null}
> {
>     event: "apiKey.expired";
>     object: "apiKey";
>     api_version: string;
>     created: number;
>     data: {
>         object: {
>             id: string;
>             description?: string | undefined;
>             expiresAt: string;
>         };
>     };
>     user: {
>         type: "dashboard";
>         id: string;
>         email: string;
>         name: string;
>     } | {
>         type: "api_key";
>         apiKey: string;
>         id?: string | undefined;
>         name?: string | undefined;
>         email?: string | undefined;
>         /** The member named with `X-GrowthBook-Requested-By` */
>         requestedBy?: {
>             id: string;
>             name: string;
>             email: string;
>         } | undefined;
>         /** Whether the key assumed the named member's role */
>         assumedRole?: boolean | undefined;
>     } | {
>         type: "system";
>         subtype?: string | undefined;
>         id?: string | undefined;
>     } | null;
>     tags: string[];
>     /** The environments affected by the change described by this event. For live-state events (e.g. `feature.updated`) these are the environments whose effective configuration actually changed; for draft lifecycle events (`*.revision.*`) they are the environments the proposed changes would affect. Webhook environment filters match against this field. An empty array means the event has no environment-scoped impact (it will only be delivered to subscriptions without an environment filter). */
>     environments: string[];
>     containsSecrets: boolean;
> }
> ```
