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

# Outgoing Webhooks

> Receive real-time events when users interact with your Chameleon Experiences. Configure endpoints to receive Tour, Survey, Embed, Demo, HelpBar, and Alert webhooks.

<a id="outgoing-webhooks" />

## Data out of Chameleon

A webhook is an agreed-upon method of data exchange across a **secure channel**. Since you will be adding a new endpoint to your backend servers to handle this webhook, is it **strongly recommended** that you [verify the signature](#verification) of any webhook requests before processing any included data.

When sending a webhook to your backend Chameleon will:

* Send a `POST` request to your `https` [configured endpoints](https://app.chameleon.io/integrations/webhooks).
* Attempt delivery right away from `aws us-east`, use a request timeout of 7 seconds and include a `User-Agent` header specific to the [API version](/concepts/authentication#version) the webhook is being sent from.
* Generate a SHA256-HMAC signature of the request body and include the signature in the `X-Chameleon-Signature` header
* In case of non-200 status code, will retry a total of 9 times over 43 hours (giving you a chance to fix errors without losing track of these webhooks)

When receiving a webhook from Chameleon you should:

* Only accept requests from [Chameleon IP Addresses](/concepts/authentication#ip-addresses)
* [Verify](#verification) the Webhook request signature; respond with a status `400` if the signature does not match
* Drop the request if the webhook is too old (to prevent replay attacks); respond with a status `400`
* Respond quickly with a `200` status code (or any `2xx` status code)
* Optional: Request any related data with the [other APIs](/apis/overview)

<a id="topics" />

#### Webhook topics

| Topic                   | Example Payload                         | Included models                                                                                                       | Description                                                                                                                                                                                                                                       |
| ----------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ping`                  | [example](#example-ping)                | Account                                                                                                               | Sent as a simple check to make sure the endpoint is working                                                                                                                                                                                       |
| `response.finished`     | [example](#example-response-finished)   | [Response](/apis/survey-responses), [Microsurvey](/apis/surveys), [User Profile](/apis/profiles)                      | Sent when the Microsurvey is finished (all Steps completed; including text comment if configured)                                                                                                                                                 |
| `alert.triggered`       | [example](#example-alert-triggered)     | [Alert Group](/apis/alert-groups), [Experiences](/concepts/experiences)                                               | Sent when an Alert is triggered by a violation of the alerting conditions                                                                                                                                                                         |
| `helpbar.answer`        | [example](#example-helpbar-answer)      | [Action](#schema-actions-helpbar-answer), [User Profile](/apis/profiles)                                              | Sent when a Search query generates an AI Answer in HelpBar                                                                                                                                                                                        |
| `helpbar.search`        | [example](#example-helpbar-search)      | [Action](#schema-actions-helpbar-search), [User Profile](/apis/profiles)                                              | Sent when a Search query displays its results in the HelpBar                                                                                                                                                                                      |
| `helpbar.item.action`   | [example](#example-helpbar-item-action) | [Action](#schema-actions-helpbar-item-action), [User Profile](/apis/profiles)                                         | Sent when an item in the HelpBar is clicked/actioned                                                                                                                                                                                              |
| `helpbar.item.error`    | [example](#example-helpbar-item-error)  | [Action](#schema-actions-helpbar-item-error), [User Profile](/apis/profiles)                                          | Sent when an action from an item in the HelpBar throws an error when running                                                                                                                                                                      |
| `tour.started`          | [example](#example-tour-all)            | [Action](#schema-actions-campaign), [Tour](/apis/tours), [Step](/apis/steps), [User Profile](/apis/profiles)          | Sent when the Tour is started; includes the first Step in the payload                                                                                                                                                                             |
| `tour.completed`        | [example](#example-tour-all)            | [Action](#schema-actions-campaign), [Tour](/apis/tours), [Step](/apis/steps), [User Profile](/apis/profiles)          | Sent when the Tour is completed; includes the Step the user completed                                                                                                                                                                             |
| `tour.exited`           | [example](#example-tour-all)            | [Action](#schema-actions-campaign), [Tour](/apis/tours), [Step](/apis/steps), [User Profile](/apis/profiles)          | Sent when the Tour is exited; includes the Step the user exited                                                                                                                                                                                   |
| `tour.snoozed`          | [example](#example-tour-snooze)         | [Action](#schema-actions-snooze), [Tour](/apis/tours), [Step](/apis/steps), [User Profile](/apis/profiles)            | Sent when the Tour is exited on Step configured to snooze (re-display the Step at a later time).                                                                                                                                                  |
| `tour.button.clicked`   | [example](#example-tour-button-clicked) | [Tour](/apis/tours), [Step](/apis/steps), [Button](/apis/buttons), [User Profile](/apis/profiles)                     | Sent when the Tour is exited with the Step the user exited                                                                                                                                                                                        |
| `survey.started`        | [example](#example-survey-all)          | [Action](#schema-actions-campaign), [Microsurvey](/apis/surveys), [Step](/apis/steps), [User Profile](/apis/profiles) | Sent when the Microsurvey is started with the first Step                                                                                                                                                                                          |
| `survey.completed`      | [example](#example-survey-all)          | [Action](#schema-actions-campaign), [Microsurvey](/apis/surveys), [Step](/apis/steps), [User Profile](/apis/profiles) | Sent when the Microsurvey is completed with the Step the user completed                                                                                                                                                                           |
| `survey.exited`         | [example](#example-survey-all)          | [Action](#schema-actions-campaign), [Microsurvey](/apis/surveys), [Step](/apis/steps), [User Profile](/apis/profiles) | Sent when the Microsurvey is exited with the Step the user exited                                                                                                                                                                                 |
| `survey.snoozed`        | [example](#example-survey-snooze)       | [Action](#schema-actions-snooze), [Microsurvey](/apis/surveys), [Step](/apis/steps), [User Profile](/apis/profiles)   | Sent when the Tour is exited on Step configured to snooze (re-display the Step at a later time).                                                                                                                                                  |
| `survey.button.clicked` | [example](#example-tour-button-clicked) | [Microsurvey](/apis/surveys), [Step](/apis/steps), [Button](/apis/buttons), [User Profile](/apis/profiles)            | Sent when the Tour is exited with the Step the user exited                                                                                                                                                                                        |
| `embed.started`         | [example](#example-embed-all)           | [Action](#schema-actions-campaign), [Embed](/apis/tours), [Step](/apis/steps), [User Profile](/apis/profiles)         | Sent when the Embed is started; includes the first Step in the payload                                                                                                                                                                            |
| `embed.completed`       | [example](#example-embed-all)           | [Action](#schema-actions-campaign), [Embed](/apis/tours), [Step](/apis/steps), [User Profile](/apis/profiles)         | Sent when the Embed is completed; includes the Step the user completed                                                                                                                                                                            |
| `embed.exited`          | [example](#example-embed-all)           | [Action](#schema-actions-campaign), [Embed](/apis/tours), [Step](/apis/steps), [User Profile](/apis/profiles)         | Sent when the Embed is exited; includes the Step the user exited                                                                                                                                                                                  |
| `embed.snoozed`         | [example](#example-embed-snooze)        | [Action](#schema-actions-snooze), [Embed](/apis/tours), [Step](/apis/steps), [User Profile](/apis/profiles)           | Sent when the Embed is exited on Step configured to snooze (re-display the Step at a later time).                                                                                                                                                 |
| `embed.button.clicked`  | [example](#example-tour-button-clicked) | [Embed](/apis/tours), [Step](/apis/steps), [Button](/apis/buttons), [User Profile](/apis/profiles)                    | Sent when the Embed is exited with the Step the user exited                                                                                                                                                                                       |
| `demo.started`          | [example](#example-demo-started)        | [Demo](/apis/demos), [DemoRun](/apis/demos#schema-demo-run), [User Profile](/apis/profiles)                           | Sent when the Demo is started                                                                                                                                                                                                                     |
| `demo.reveal`           | [example](#example-demo-reveal)         | [Demo](/apis/demos), [DemoRun](/apis/demos#schema-demo-run), [User Profile](/apis/profiles)                           | Sent after the Demo is started *and* [Clearbit reveal](https://app.chameleon.io/integrations/clearbit) is enabled *and* a match is found. The `demo_run` will have `reveal_domain` and `reveal_name` keys for the Company domain and Company name |
| `demo.finished`         | [example](#example-demo-finished)       | [Demo](/apis/demos), [DemoRun](/apis/demos#schema-demo-run), [User Profile](/apis/profiles)                           | Sent when the Demo is finished; Either the last step is reached **OR** when approximately 30 minutes has passed and the user likely bounced. The `demo_run` will have `finished_kind` of either `"last_step"` or `"timeout_30m"`.                 |
| `demo.form.submitted`   | [example](#example-demo-form-submitted) | [Demo](/apis/demos), [DemoRun](/apis/demos#schema-demo-run), [User Profile](/apis/profiles)                           | Sent when a Demo form is submitted. The `action` will have the `submission` as a [DemoSubmission](/apis/demos#schema-demo-submission) object. The final demo.finished webhook will contain all of the `actions` and `submissions`                 |

> **Looking for a different topic? We're excited to chat about your use case! [Contact us](https://app.chameleon.io/help)**

<a id="schema" />

#### Schema (request body)

| Property  | Type      | Description                                                                                   |
| --------- | --------- | --------------------------------------------------------------------------------------------- |
| `id`      | ID        | The Chameleon ID                                                                              |
| `sent_at` | timestamp | The current server time when this webhook was sent (used in [verification](#verification))    |
| `kind`    | enum      | The [topic identifier](#topics)                                                               |
| `data`    | object    | Contains the webhook payload data. This can be any models included by singular or plural name |

<a id="headers" />

#### Request headers

| Header                  | Example value                                    | Description                                                     |
| ----------------------- | ------------------------------------------------ | --------------------------------------------------------------- |
| `X-Chameleon-Id`        | `5f3c4232c712de665632a2a3`                       | The Chameleon ID of this webhook                                |
| `X-Chameleon-Signature` | 5a17b....                                        | The SHA256-HMAC of the raw request body                         |
| `User-Agent`            | `Chameleon Webhooks/v3 (chameleon.io; integral)` | The request is from the Chameleon v3 API (integral environment) |
| `Content-Type`          | `application/json`                               | Signifying that the request body is JSON                        |
| `Accept`                | `application/json`                               | Signifying that the response should be JSON (or nothing)        |

<a id="verification" />

### Verifying the Webhook

The signature is the SHA256-HMAC of your [Webhook Secret](https://app.chameleon.io/integrations/webhooks) and the request body.
As a second step, reject the message if it was sent outside of a few minutes (in the examples below 5 minutes is used; to prevent replay attacks)

### Verification Examples

<a id="rails" />

###### Rails

```ruby theme={null}
# Assumes this code runs in a Controller to access the `request` object
# Could easily be run in a background task or elsewhere by passing the `X-Chameleon-Signature` and `request.raw_post` exactly as-is

secret = ENV['CHAMELEON_VERIFICATION_SECRET']
received = request.headers['X-Chameleon-Signature']
expected = OpenSSL::HMAC.hexdigest('SHA256', secret, request.raw_post)

verified = ActiveSupport::SecurityUtils.secure_compare(received, expected) &&
 (sent_at = Time.zone.parse(params[:sent_at])) &&
 (sent_at > 5.minutes.ago && sent_at < 5.minutes.from_now)
```

**Have an example from your production app to add? Submit a [PR to this file](https://github.com/chamaeleonidae/api/blob/main/mintlify-docs/webhooks/outgoing.mdx) and we'll give you \$25 Amazon credit via our Docs Bounty program!**

<a id="schema-actions" />

### Action

Each Webhook can contain an `action` key in the payload. It will contain contextual information about the webhook, the source of the webhook, the state of a user, etc.

| Property | Type | Description                     |
| -------- | ---- | ------------------------------- |
| `id`     | ID   | The Chameleon ID of this Action |

<a id="schema-actions-campaign" />

### Action

> Applies to `tour.started`, `tour.completed`, `tour.exited`, `survey.started`, `survey.completed`, `survey.exited`, `embed.started`, `embed.completed`, `embed.exited`

| Property     | Type   | Description                                                                                                                         |
| ------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `id`         | ID     | The Chameleon ID of this Action                                                                                                     |
| `group_kind` | string | Type of group association. One of `null`, `link`, `api_js`, `launcher`, `experiment`, `campaign`, `delivery`, `helpbar`, or `agent` |
| `group_id`   | ID     | The ID of associated group, this can be a Launcher ID, another Tour ID, or `null` if no associated ID                               |

<a id="schema-actions-snooze" />

### Action

> Applies to `tour.snoozed`, `survey.snoozed`, `embed.snoozed`

| Property         | Type      | Description                                        |
| ---------------- | --------- | -------------------------------------------------- |
| `id`             | ID        | The Chameleon ID of this Action                    |
| `deferred_until` | timestamp | The ending time of the snooze                      |
| `deferred_hours` | integer   | The number of hours that this was snoozed for      |
| `deferred_count` | integer   | The number of times in a row this has been snoozed |

<a id="schema-actions-helpbar-search" />

### Action (`helpbar.search`)

| Property        | Type    | Description                                            |
| --------------- | ------- | ------------------------------------------------------ |
| `id`            | ID      | The Chameleon ID of this Action                        |
| `query`         | string  | The search query text that was submitted by the user   |
| `results_count` | integer | Total number of search results returned for this query |

<a id="schema-actions-helpbar-item-error" />

### Action (`helpbar.item.error`)

| Property       | Type           | Description                                                            |
| -------------- | -------------- | ---------------------------------------------------------------------- |
| `id`           | ID             | The Chameleon ID of this Action                                        |
| `query`        | string         | The search query text that was submitted by the user                   |
| `item_uid`     | string         | Unique identifier for the search result item that encountered an error |
| `title`        | string         | The title or display name of the search result item                    |
| `action_info`  | string         | Additional action information or metadata related to the error         |
| `url`          | string         | The URL or link associated with the search result item                 |
| `action_kinds` | array\<string> | Array of action types or categories that describe the error context    |

<a id="schema-actions-helpbar-item-action" />

### Action (`helpbar.item.action`)

| Property   | Type           | Description                                                                  |
| ---------- | -------------- | ---------------------------------------------------------------------------- |
| `id`       | ID             | The Chameleon ID of this Action                                              |
| `query`    | string         | The search query text that was submitted by the user                         |
| `item_uid` | string         | Unique identifier for the search result item that was acted upon             |
| `title`    | string         | The title or display name of the search result item                          |
| `href`     | string         | The URL or link that the user can interact with for this search result       |
| `kinds`    | array\<string> | Array of action types or categories that describe what actions are available |

<a id="schema-actions-helpbar-answer" />

### Action (`helpbar.answer`)

| Property        | Type           | Description                                                               |
| --------------- | -------------- | ------------------------------------------------------------------------- |
| `id`            | ID             | The Chameleon ID of this Action                                           |
| `query`         | string         | The search query text that was submitted by the user                      |
| `answer`        | string         | The generated or retrieved answer content in response to the search query |
| `url`           | string         | The page that the user was on when the answer was generated               |
| `results_count` | integer        | Number of source results that were used to generate this answer           |
| `references`    | array\<string> | Array of reference URLs or sources that support the provided answer       |

### Payload Examples

<a id="example-ping" />

##### Example ping

Typically do process Verification for this topic but nothing really to be done when topic is received. It's simply part of how Chameleon determines active/inactive/performance of webhook endpoints.

```json theme={null}
{
  "id": "5fb70dcbc39330000325a817",
  "kind": "ping",
  "sent_at": "2029-12-11T00:28:59.650Z",
  "data": {
    "account": {
      "id": "58918bc07de121000432e9c0",
      "domain": "acme.co",
      "name": "Acme Corp"
    }
  }
}
```

<a id="example-response-finished" />

##### Example response-finished

Every Microsurvey that is finished will send a webhook to this topic.

```json theme={null}
{
  "id": "5fb70dcbc39330000325a81a",
  "kind": "response.finished",
  "sent_at": "2029-12-11T00:28:59.651Z",
  "data": {
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 83,
      ...
    },
    "response": {
      "id": "5fb7afb5ea19724169374269",
      "survey_id": "5fb7936edee1f70011bfc4c9",
      "profile_id": "5f884e1e03d9f4000ebcbb59",
      "href": "https://app.acme.co/setup/tough-thing-to-do",
      "button_text": "Very Easy",
      "button_order": 0,
      "input_text": "I was able to figure it out quickly.",
      "finished_at": "2029-12-11T00:28:59.641Z"
    },
    "survey": {
      "id": "5fb7936edee1f70011bfc4c9",
      "name": "2029-11 Role question",
      "segment_id": "5f885a88e7daf3000e3eb4f7",
      "published_at": "2029-11-11T00:12:59.002Z",
      ...
      "steps": [
        {
          "id": "5fb7936d566535d75a87507c",
          "body": "How was that?",
          "preset": "survey_five",
          "dropdown_items": [
          ]
        },
        {
          "id": "5fb7936d566535d75a87507e",
          "body": "Thanks so much for your feedback!",
          "preset": "thank_you"
        }
      ],
      "user": {
        "id": "5490e42d65353700020030fa",
        "email": "jim@acme.co",
        "name": "Jim B"
      }
    }
  }
}
```

<a id="example-helpbar-answer" />

##### Example helpbar-answer

This is the most important HelpBar webhook; it can directly inform your roadmap for additional updated/documentation.

* Chameleon AI Answering operates best when:
* A headline (h2/h3) in the Help center article is relevant to the question being asked
* Multiple inputs corroborate from different angles
* Seeing a `results_count` less than 3 is an important metric to track
* Use `references` to know where to make improvements

```json theme={null}
{
  "id": "5eb7c393300000dcb381a25a",
  "kind": "helpbar.answer",
  "sent_at": "2029-12-11T00:28:59.651Z",
  "data": {
    "action": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "query": "What is a widget?",
      "answer": "A widget is the generic name for the work product of a production run. One might use this term to describe something generic as an example in place of an unimportant specific item.",
      "results_count": 7,
      "references": ["https://help.your-product.com/hc/articles/925844-widgets-galore", "https://help.your-product.com/hc/articles/559284-widgets-n-more"],
      "url": "https://app.your-product.com/widgets/start"
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 83,
      ...
    }
  }
}
```

<a id="example-helpbar-search" />

##### Example helpbar-search

When a User searches for `"data importing"` only 0 results were found. This indicates a gap in your Help center.

```json theme={null}
{
  "id": "5eb7c393300000dcb381a25a",
  "kind": "helpbar.search",
  "sent_at": "2029-12-11T00:29:59.651Z",
  "data": {
    "action": {
      "id": "5f885a88e7daf3000e3eb4f7",
      "query": "data importing",
      "results_count": 2
    },
    "profile": {
      "id": "5f885a88f30e7da00e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 85,
      ...
    }
  }
}
```

When a User searches for `"widget categories"` only 7 results were found.

```json theme={null}
{
  "id": "5eb7c393300000dcb381a25a",
  "kind": "helpbar.search",
  "sent_at": "2029-12-11T00:28:30.651Z",
  "data": {
    "action": {
      "id": "5f885a8af30008e7de3eb4f9",
      "query": "widget categories",
      "results_count": 7
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 93,
      ...
    }
  }
}
```

<a id="example-helpbar-item-action" />

##### Example helpbar-item-action

When a helpbar search result item is clicked (or actioned)

```json theme={null}
{
  "id": "5eb7c393300000dcb381a25a",
  "kind": "helpbar.item.action",
  "sent_at": "2029-12-11T00:28:18.651Z",
  "data": {
    "action": {
      "id": "5f885a8af30008e7de3eb4f9",
      "item_uid": "data-onboarding",
      "href": "https://help.your-product.com/hc/articles/559284-data-onboarding",
      "kinds": ["url"]
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 93,
      ...
    }
  }
}
```

<a id="example-helpbar-item-error" />

##### Example helpbar-item-error

When a helpbar search result item is clicked (or actioned) and then encounters an error processing the actions.

In the example below, the `script` item is not working properly and should be checked

```json theme={null}
{
  "id": "5eb7c393300000dcb381a25a",
  "kind": "helpbar.item.error",
  "sent_at": "2029-12-11T00:28:18.651Z",
  "data": {
    "action": {
      "id": "5f885a8af30008e7de3eb4f9",
      "item_uid": "demo-upgrade",
      "href": "https://calendly.com/your-product/demo-upgrade-chat",
      "kinds": ["script", "calendly"]
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 93,
      ...
    }
  }
}
```

<a id="example-tour-all" />

##### Example tour-all

A Tour is started, runs through a sequence of 1 or more Steps and finishes by being Exited or Completed. Tours by default show once to any one User but can, depending on their settings, show multiple times.

```json theme={null}
{
  "id": "5fb70dcbc39330000325a818",
  "kind": "tour.started",
  "sent_at": "2029-12-11T00:28:59.652Z",
  "data": {
    "action": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "group_kind": "api_js",
      "group_id": null
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 83,
      ...
    },
    "tour": {
      "id": "5fb6e4ab8af58a00073f0d98",
      "name": "Usage upsell banner - A",
      "segment_id": "5f885a88e7daf3000e3eb4f7",
      "published_at": "2029-11-11T00:12:59.002Z",
      ...
    },
    "step": {
      "id": "5fb6e4ab8af58a00073f0d99",
       "body": "You've grown beyond your current plan by {{mau_blocks fallback='a lot'}}! -- Next billing cycle, you will be charged for the additional users or pre-pay to save",
       ...
    }
  }
}
```

<a id="example-tour-snooze" />

##### Example tour-snooze

When a Tour is snoozed it is set to come back after a certain amount of time has passed (i.e. 1 day, 2 weeks, 2 hours etc.).

> **Look for `data.action` to be an object with the information on when this snooze ends, how many hours, and how many snoozes this totals.**

```json theme={null}
{
  "id": "5fb70dcbc39330000325a818",
  "kind": "tour.snoozed",
  "sent_at": "2029-12-11T00:28:59.652Z",
  "data": {
    "action": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "deferred_until": "2029-12-14T00:28:58.622Z",
      "deferred_hours": 72,
      "deferred_count": 2
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 83,
      ...
    },
    "tour": {
      "id": "5fb6e4ab8af58a00073f0d98",
      "name": "Usage upsell banner - A",
      "segment_id": "5f885a88e7daf3000e3eb4f7",
      "published_at": "2029-11-11T00:12:59.002Z",
      ...
    },
    "step": {
      "id": "5fb6e4ab8af58a00073f0d99",
       "body": "You've grown beyond your current plan by {{mau_blocks fallback='a lot'}}! -- Next billing cycle, you will be charged for the additional users or pre-pay to save",
       ...
    }
  }
}
```

<a id="example-tour-button-clicked" />

##### Example tour-button-clicked

Every Button that is clicked in a Tour / Microsurvey will send a webhook to this topic. It includes the Step and the Button configuration.

> The key will be "tour", "survey", or "embed" depending on the Experience type.

```json theme={null}
{
  "id": "5fb70dcbc39330000325a819",
  "kind": "tour.button.clicked",
  "sent_at": "2029-12-11T00:28:59.653Z",
  "data": {
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 83,
      ...
    },
    "tour": {
      "id": "5fb6e4ab8af58a00073f0d98",
      "name": "Usage upsell banner - A",
      "segment_id": "5f885a88e7daf3000e3eb4f7",
      "published_at": "2029-11-11T00:12:59.002Z",
      ...
    },
    "step": {
      "id": "5fb6e4ab8af58a00073f0d99",
       "body": "You've grown beyond your current plan by {{mau_blocks fallback='a lot'}}! -- Next billing cycle, you will be charged for the additional users or pre-pay to save",
       ...
    },
    "button": {
      "id": "5fb6e4ab8af58a00073f0d9a",
       "text": "Check pricing",
       "tour_action": "next",
       "position": "bottom_right",
       ...
    },
    "action": {
      "id": "5f885a88e7daf3000e3eb4f6"
    }
  }
}
```

<a id="example-embed-all" />

##### Example embed-all

An Embed is started, runs through a sequence of 1 or more Steps and finishes by being Exited or Completed. Embeds by default show once to any one User but can, depending on their settings, show multiple times.

```json theme={null}
{
  "id": "5fb70dcbc39330000325a818",
  "kind": "embed.started",
  "sent_at": "2029-12-11T00:28:59.652Z",
  "data": {
    "action": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "group_kind": "api_js",
      "group_id": null
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 83,
      ...
    },
    "embed": {
      "id": "5fb6e4ab8af58a00073f0d98",
      "name": "Usage upsell banner - A",
      "segment_id": "5f885a88e7daf3000e3eb4f7",
      "published_at": "2029-11-11T00:12:59.002Z",
      ...
    },
    "step": {
      "id": "5fb6e4ab8af58a00073f0d99",
       "body": "You've grown beyond your current plan by {{mau_blocks fallback='a lot'}}! -- Next billing cycle, you will be charged for the additional users or pre-pay to save",
       ...
    }
  }
}
```

<a id="example-embed-snooze" />

##### Example embed-snooze

When an Embed is snoozed it is set to come back after a certain amount of time has passed (i.e. 1 day, 2 weeks, 2 hours etc.).

> **Look for `data.action` to be an object with the information on when this snooze ends, how many hours, and how many snoozes this totals.**

```json theme={null}
{
  "id": "5fb70dcbc39330000325a818",
  "kind": "embed.snoozed",
  "sent_at": "2029-12-11T00:28:59.652Z",
  "data": {
    "action": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "deferred_until": "2029-12-14T00:28:58.622Z",
      "deferred_hours": 72,
      "deferred_count": 2
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 83,
      ...
    },
    "embed": {
      "id": "5fb6e4ab8af58a00073f0d98",
      "name": "Usage upsell banner - A",
      "segment_id": "5f885a88e7daf3000e3eb4f7",
      "published_at": "2029-11-11T00:12:59.002Z",
      ...
    },
    "step": {
      "id": "5fb6e4ab8af58a00073f0d99",
       "body": "You've grown beyond your current plan by {{mau_blocks fallback='a lot'}}! -- Next billing cycle, you will be charged for the additional users or pre-pay to save",
       ...
    }
  }
}
```

<a id="example-alert-triggered" />

##### Example alert-triggered

When Experiences are in violation of the Alert conditions.
The primary use case for this is to notify the person in charge of the Experience when X days have passed without activity (on something that is otherwise expected to have activity).

> [Experiences](/concepts/experiences) are either `kind=tour` for a [Tour](/apis/tours) or `kind=survey` for a [Microsurvey](/apis/surveys)

> For Tags and Environments see the `"tags"` and `"url_groups"` keys below and see [Experience](/concepts/experiences) page.

```json theme={null}
{
  "id": "6fd85a88e7daf3000e3eb4f7",
  "kind": "alert.triggered",
  "sent_at": "2029-12-12T01:28:59.654Z",
  "data": {
    "alert_group": {
      "id": "6de85a88e7daf3000e3eb4f6",
      "name": "Tour + Microsurvey 5-day dropoff",
      "summary": "Checks for Experiences that are not Seen in the past 5 days.",
      "interval": 5,
      "kind": "all",
      "style": "unseen",
      "created_user": {
        "id": "63165266260fe8000781b161",
        "email": "jon@example.com",
        ...
      },
      "urls": {
        "dashboard": "https://app.chameleon.io/alerts/6de85a88e7daf3000e3eb4f6"
      },
      ...
    },
    "experiences": [
      {
        "id": "6fd85a88e7daf3000e3eb4f8",
        "name": "Usage upsell banner - A",
        "kind": "tour",
        "segment_id": "6d885a88e7daf3000e3eb4f9",
        "published_at": "2029-11-06T00:12:59.002Z",
        ...
      },
      {
        "id": "6fd85a88e7daf3000e3eb4e8",
        "name": "Usage upsell banner - C",
        "kind": "tour",
        "segment_id": "6d885a88e7daf3000e3eb4f8",
        "published_at": "2029-11-11T00:12:59.002Z",
        "tags": [
          {
            "id": "6a885a880e3e4b8fe7daf300",
            "uid": "announcement",
            "name": "Feature announcement",
            "urls": {
              "dashboard": "https://app.chameleon.io/data/tags/6a885a880e3e4b8fe7daf300"
            },
            ...
          },
          ...
        ],
        "url_groups": [
          {
            "id": "6f885a88e7daf3000e3e4b8f",
            "name": "Production",
            "urls": {
              "dashboard": "https://app.chameleon.io/domains/6f885a88e7daf3000e3e4b8f"
            },
            ...
          }
        ],
        ...
      },
      {
        "id": "6fd85a88e7daf3000e3eb4e8",
        "name": "Request for research participants - 2029-11",
        "kind": "survey",
        "segment_id": "6d885a88e7daf3000e3eb4f8",
        "published_at": "2029-11-01T00:12:59.002Z",
        ...
      }
    ],
    "action": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "summary": "3 Experiences went 5 days without being Seen."
    }
  }
}
```

<a id="example-survey-all" />

##### Example survey-all

These three topics are considered lifecycle events and occur when the user is presented with or interacts with a Chameleon
Microsurvey. The `response.finished` Webhook is only sent when we consider the user **done** with the Microsurvey and will
no longer interact with it. A [Microsurvey Response](/apis/survey-responses) is generated when the Microsurvey Step + associated
Response Step are finished; it sends a `response.finished` Webhook.

A Microsurvey is started on the *Survey* Step and either `completed` or `exited` when the first step is "actioned". It then automatically
branches through a sequence of optional *Response* Steps and finishes with an optional *Thank You* Step.

> The Steps corresponding to a *Response* Step have `preset=response`; The *Thank You* Steps have  `preset=thank_you`

```json theme={null}
{
  "id": "5fb70dcbc39330000325a818",
  "kind": "survey.completed",
  "sent_at": "2029-12-11T00:28:59.652Z",
  "data": {
    "action": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "group_kind": "api_js",
      "group_id": null
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 83,
      ...
    },
    "survey": {
      "id": "5fb7936edee1f70011bfc4c9",
      "name": "2029-11 Role question",
      "segment_id": "5f885a88e7daf3000e3eb4f7",
      "published_at": "2029-11-11T00:12:59.002Z",
      "steps": [
        {
          "id": "5fb7936d566535d75a87507c",
          "body": "How was that?",
          "preset": "survey_five",
          ...
        },
        {
          "id": "5fb7936d566535d75a87507d",
          "body": "Why specifically did you struggle?",
          "preset": "response",
          ...
        }
        ...
      ],
      ...
    },
    "step": {
      "id": "5fb7936d566535d75a87507c",
      "body": "How was that?",
      "preset": "survey_five",
       ...
    }
  }
}
```

<a id="example-survey-snooze" />

##### Example survey-snooze

When a Microsurvey is snoozed it is set to come back after a certain amount of time has passed (i.e. 1 day, 2 weeks, 2 hours etc.).

> **Look for `data.action` to be an object with the information on when this snooze ends, how many hours, and how many snoozes this totals.**

```json theme={null}
{
  "id": "5fb70dcbc39330000325a818",
  "kind": "survey.snoozed",
  "sent_at": "2029-12-11T00:28:59.652Z",
  "data": {
    "action": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "deferred_until": "2029-11-15T00:02:19.002Z",
      "deferred_hours": 48,
      "deferred_count": 2
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 83,
      ...
    },
    "survey": {
      "id": "5fb7936edee1f70011bfc4c9",
      "name": "2029-11 Role question",
      "segment_id": "5f885a88e7daf3000e3eb4f7",
      "published_at": "2029-11-11T00:12:59.002Z",
      "steps": [
        {
          "id": "5fb7936d566535d75a87507c",
          "body": "How was that?",
          "preset": "survey_five",
          ...
        },
        {
          "id": "5fb7936d566535d75a87507d",
          "body": "Why specifically did you struggle?",
          "preset": "response",
          ...
        }
        ...
      ],
      ...
    },
    "step": {
      "id": "5fb7936d566535d75a87507d",
      "body": "Why specifically did you struggle?",
      "preset": "response",
      ...
    }
  }
}
```

<a id="example-demo-started" />

##### Example demo-started

Right when the Demo is first started in this session. Chameleon calls this a Demo "run".

Demos can also [sync Contact data](/apis/demos#demos-in-the-crm) into the CRM

> For an anonymous user (e.g. on your marketing website) the `data.profile` will be `null` and `demo_run.anonymous_id` will be stable until local cache is cleared

```json theme={null}
{
  "id": "6fb70330dcbc39000325a94a",
  "kind": "demo.started",
  "sent_at": "2029-12-11T00:28:59.331Z",
  "data": {
    "action" : {
      "id": "6f885a88e7daf34f6000e3eb"
    },
    "profile": {
      "id": "5f885a88e7daf3000e3eb4f6",
      "email": "jane@example.com",
      "uid": "92340834",
      "name": "Jane E",
      "last_seen_at": "2029-12-11T00:21:59.109Z",
      "last_seen_session_count": 83,
      ...
    },
    "demo_run": {
      "id": "5fb7afb5ea19724169374269",
      "referrer":  "https://www.acme.co/products/analytics",
      "created_what":  "Chrome 191.0 (Mac)",
      "created_where": "Oakland CA, US",
      "anonymous_id": "5fb7afb5ea19724169374269",
      "consent_mode": "granted",
      ...
    },
    "demo": {
      "id": "5fb7936edee1f70011bfc4c9",
      "name": "Demo of Analysis quickstart",
      "description": "Our analysis goes deeper than you'd typically see in a trial",
      "href": "https://app.acme.co/setup/tough-thing-to-do",
      "page_title": "Analytics",
      ...
      "user": {
        "id": "5490e42d65353700020030fa",
        "email": "jim@acme.co",
        "name": "Jim B"
      }
    }
  }
}
```

<a id="example-demo-finished" />

##### Example demo-finished

This webhook topic only differs from `demo.started` by the addition of the following keys in the `demo_run`.

1. In the `demo_run`, an `actions` array of [DemoAction](/apis/demos#schema-demo-run)s
2. In the `demo_run`, a `submissions` array of [DemoSubmission](/apis/demos#schema-demo-submission)s with a `data` key of [DemoSubmissionData](/apis/demos#schema-demo-submission-data)
3. `finished_kind` in the `demo_run` as either `"last_step"` or `"timeout_30m"` to give an indication of how this Demo was finished

It will be sent when the last step of the Demo is reached with `finished_kind=last_step` *OR* approximately
30 minutes after the last activity in the Demo and `finished_kind=timeout_30m`.

```json theme={null}
{
  "id": "6fb70330dcbc39000325a94b",
  "kind": "demo.finished",
  "sent_at": "2029-12-11T00:28:59.331Z",
  "data": {
    "action" : {
      "id": "6f885a88e7daf34f6000e3eb"
    },
    "demo_run": {
      ...,
      "finished_kind": "last_step",
      "actions": [
        {
          "id": "",
          "name": "Demo Started",
          ...
        },
        {
          "id": "",
          "name": "Demo Step Started",
          ...
        },
        ...
      ],
      "submissions": [
        {
          "id": "6f885a84f600b0e38e7daf3e",
          "step_id": "5fb7936edee1f70011bfc4c9",
          "data": [
            {
              "field": {
                "id": "6fa88e7daf34f6000e3eb885",
                "type": "email",
                "name": "Email address",
                "description": ""
              },
              "value": "jane@example.io"
            },
            {
              "field": {
                "id": "6fa88e7daf34f6000e3eb885",
                "type": "select",
                "name": "Urgency",
                "description": "Knowing how quickly you want to evaluate Acme helps us mirror your urgency"
              },
              "value": "this week"
            },
            ...
          ]
        }
      ]
    },
    "demo": {
      "id": "5fb7936edee1f70011bfc4c9",
      ...
    }
  }
}
```

<a id="example-demo-reveal" />

##### Example demo-reveal

This webhook topic only differs by the addition of `reveal_domain`, `reveal_name`, and `clearbit_uid` in the `demo_run`.
It will be sent when the following conditions are met

1. [Clearbit Reveal](https://clearbit.com/) is configured in [your dashboard](https://app.chameleon.io/integrations/clearbit)
2. The `consent_mode` of the Demo was set to `granted` (e.g. `data-consent-mode="granted"` on the iframe element for the embed)
3. A match is found to the IP address of anonymous traffic

```json theme={null}
{
  "id": "6fb70330dcbc39000325a94b",
  "kind": "demo.reveal",
  "sent_at": "2029-12-11T00:28:59.331Z",
  "data": {
    "action" : {
      "id": "6f885a88e7daf34f6000e3eb"
    },
    "demo_run": {
      ...,
      "reveal_domain": "zenflex.io",
      "reveal_name": "Zen Flexing Aura Ltd.",
      "clearbit_uid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "consent_mode": "granted"
    },
    "demo": {
      "id": "5fb7936edee1f70011bfc4c9",
      ...
    }
  }
}
```

<a id="example-demo-form-submitted" />

##### Example demo-form-submitted

This webhook topic is meant to sync any form data to an external system; typically involving adding a new contact to your CRM. The
`action.submission` is a [DemoSubmission](/apis/demos#schema-demo-submission)s with a `data` key of [DemoSubmissionData](/apis/demos#schema-demo-submission-data) and
each data item has a `field` as [DemoFormField](/apis/demos#schema-demo-form-field) and `value`.

```json theme={null}
{
  "id": "6fb70330dcbc39000325a94b",
  "kind": "demo.form.submitted",
  "sent_at": "2029-12-11T00:28:59.331Z",
  "data": {
    "action" : {
      "id": "6f885a88e7daf34f6000e3eb",
      "submission": {
        "id": "6f885a84f600b0e38e7daf3e",
        "step_id": "5fb7936edee1f70011bfc4c9",
        "data": [
          {
            "field": {
              "id": "6fa88e7daf34f6000e3eb885",
              "type": "email",
              "name": "Email address",
              "description": ""
            },
            "value": "jane@example.io"
          },
          {
            "field": {
              "id": "6fa88e7daf34f6000e3eb885",
              "type": "select",
              "name": "Urgency",
              "description": "Knowing how quickly you want to evaluate Acme helps us mirror your urgency"
            },
            "value": "this week"
          },
          ...
        ]
      }
    },
    "demo_run": {
      ...,
    },
    "demo": {
      "id": "5fb7936edee1f70011bfc4c9",
      ...
    }
  }
}
```

<a id="example-demo-email-added" />

##### Example demo-email-added

This webhook topic is meant to capture the moment when previously taken anonymous Demos receive an email address.
The flow can be arbitrarily complex but typically follows one of these paths:

1. **Demos taken => Submits interest form**
   1. User takes 1 or more Demos on the marketing site, help documentation, etc.
   2. In one of the Demos, the User submits a form with their email
   3. Chameleon will then update all the previous [DemoRun](/apis/demos#schema-demo-run)s from \[1i] (e.g. those connected with the `anonymous_id`)
   4. Chameleon sends one `demo.email.added` webhook per updated [DemoRun](/apis/demos#schema-demo-run)

2. **Demos taken => Product signup**
   1. User takes 1 or more Demos on the marketing site, help documentation, etc.
   2. User sign up for the product and is [identified](/js/overview#examples) with their email address
   3. Chameleon will then update all the previous [DemoRun](/apis/demos#schema-demo-run)s from \[2i] (e.g. those connected with the `anonymous_id`)
   4. Chameleon sends one `demo.email.added` webhook per updated [DemoRun](/apis/demos#schema-demo-run)

`action.email` will have email address as a copy of the email address now found in `demo_run.email`.

```json theme={null}
{
  "id": "6fb70330dcbc39000325a94b",
  "kind": "demo.email.added",
  "sent_at": "2029-12-11T00:28:59.331Z",
  "data": {
    "action" : {
      "id": "6f885a88e7daf34f6000e3eb",
      "email": "jane@acme.co"
    },
    "demo_run": {
      ...,
    },
    "demo": {
      "id": "5fb7936edee1f70011bfc4c9",
      ...
    }
  }
}
```
