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

# Webhooks

> Use webhooks to integrate AppSignal with other 3rd parties or your own system.

AppSignal can send notifications of new incidents to several services, see our full list on the [integrations](/application/integrations). We also offer webhooks for these notifications so you handle new incidents in your own system.

To receive a webhook, go to the "Notifications" tab the site's sidebar, click the "Add integration" and fill out the URL where you'd like to receive your webhook data.

<img src="https://mintcdn.com/appsignal-715f5a51/nF8c1Rwq1cS7b5hg/assets/images/screenshots/app_webhook.png?fit=max&auto=format&n=nF8c1Rwq1cS7b5hg&q=85&s=7d0bfa4afbbcf93a4e3241b53fdc06c3" alt="Webhook" width="1400" height="934" data-path="assets/images/screenshots/app_webhook.png" />

There are multiple webhooks available. Which payloads the webhook receives can be configured in the configuration form for the webhook as seen in the screenshot above.

## Verifying AppSignal webhook requests

To ensure the security of your application, you can verify that incoming webhook requests are genuinely from AppSignal. Verification is done by using a Webhook verification token to validate the request's signature.

### Locating your Webhook Verification Token

1. Navigate to **App settings > Integrations** in your AppSignal dashboard.
2. Configure the webhook integration you want to verify.
3. Here you'll find the integration's **Webhook verification token**.

This token is used to validate that the webhook request is from AppSignal.

### Verifying a request

When AppSignal sends a webhook request, it includes a signature in the `X-Appsignal-Signature` header. You can validate the request as follows:

1. Concatenate the AppSignal Webhook verification token with the raw request body.
2. Generate a SHA256 hash of the concatenated string.
3. Compare the generated hash to the value in the `X-Appsignal-Signature` header.

If the hashes match, the request can be verified as coming from AppSignal.

### Example implementations

Below are some examples of how you can verify a request is coming from AppSignal in Ruby, Elixir, Node.js and Python.

**Note:** The examples below are illustrative, you may need to adapt them depending on the frameworks, integrations and dependencies your app uses.

<CodeGroup>
  ```ruby Ruby theme={null}
      token = Rails.application.credentials.appsignal_webhook_token
      request_signature = request.headers["X-Appsignal-Signature"]

      message = request.raw_post
      signature = OpenSSL::Digest::SHA256.hexdigest(token + message.to_s)

      if signature == request_signature
        # logic here
      end
  ```

  ```elixir Elixir theme={null}
    token = Application.get_env(:my_app, :appsignal_webhook_token)
    request_signature = List.first(get_req_header(conn, "x-appsignal-signature"))

    {:ok, raw_body} = read_body(conn)

    message = token <> raw_body
    signature = Base.encode16(:crypto.hash(:sha256, message), case: :lower)

    if signature == request_signature do
      # logic here
    end
  ```

  ```js JavaScript theme={null}
  const crypto = require("crypto");

  const token = process.env.APPSIGNAL_WEBHOOK_TOKEN;
  const requestSignature = req.headers["x-appsignal-signature"];

  let rawBody = req.rawBody;

  const message = token + rawBody;

  const signature = crypto.createHash("sha256").update(message).digest("hex");

  if (signature === requestSignature) {
    // logic here
  }
  ```

  ```python Python theme={null}
    import hashlib
    import os

    token = os.getenv('APPSIGNAL_WEBHOOK_TOKEN')
    request_signature = request.headers['X-Appsignal-Signature']

    raw_body = request.get_data(as_text=True)

    message = token + raw_body

    signature = hashlib.sha256(message.encode()).hexdigest()

    if signature == request_signature:
      # logic here
  ```
</CodeGroup>

## Deploy markers

<CodeGroup>
  ```json JSON theme={null}
  {
    "marker": {
      "time": "2019-01-10 10:45:41 +0100",
      "marker_id": "5c3714455ac13f7df09437f0",
      "site": "My test app",
      "environment": "development",
      "revision": "abc123",
      "user": "tom",
      "repository": "https://github.com/my_org/my_repo",
      "url": "https://appsignal.com/test/sites/5bd867fa2213937f3666ae7b/dashboard"
    }
  }
  ```
</CodeGroup>

### Fields

| Field    | Type                | Description                                     |
| -------- | ------------------- | ----------------------------------------------- |
| `marker` | `Hash<String, Any>` | The webhook payload concerns a marker incident. |

#### Deploy marker sub-fields

| Field         | Type     | Description                                                                                    |
| ------------- | -------- | ---------------------------------------------------------------------------------------------- |
| `time`        | `String` | Timestamp at which the deploy marker was created.                                              |
| `marker_id`   | `String` | Internal AppSignal marker id for the deploy marker.                                            |
| `site`        | `String` | App name as seen on AppSignal.com. Using the `site` field instead of `app` for legacy reasons. |
| `environment` | `String` | App environment of the app as seen on AppSignal.com.                                           |
| `revision`    | `String` | The [deploy marker](/application/markers/deploy-markers){" "} revision name.                   |
| `user`        | `String` | The user that created the marker.                                                              |
| `repository`  | `String` | Url to the repository as configured for the app on AppSignal.com.                              |
| `url`         | `String` | Url to the app on AppSignal.com that triggered the webhook.                                    |

## Exception incidents

<CodeGroup>
  ```json JSON theme={null}
  {
    "exception": {
      "time": "2019-01-09 09:03:57 UTC",
      "number": 3,
      "site": "My test app",
      "environment": "development",
      "app_url": "https://appsignal.com/test/sites/5bd867fa2213937f3666ae7b",
      "url": "https://appsignal.com/test/sites/5bd867fa2213937f3666ae7b/incidents/3?timestamp=2019-01-09T09%3A03%3A57Z",
      "revision": "abc123",
      "user": "tom",
      "namespace": "web",
      "exception": "Appsignal::Demo::TestError",
      "message": "Hello world! This is an error used for demonstration purposes.",
      "app_backtrace": [
        "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/lib/appsignal/demo.rb:49:in `create_example_error_request'",
        "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/lib/appsignal/demo.rb:35:in `transmit'",
        "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/lib/appsignal/cli/demo.rb:53:in `run'",
        "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/lib/appsignal/cli.rb:31:in `run'",
        "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/bin/appsignal:7:in `<top (required)>'",
        "/Users/tombruijn/.gem/ruby/2.5.3/bin/appsignal:23:in `load'",
        "/Users/tombruijn/.gem/ruby/2.5.3/bin/appsignal:23:in `<top (required)>'",
        "/Users/tombruijn/.gem/ruby/2.5.3/bin/bundle:23:in `<main>'"
      ],
      "first_backtrace_line": "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/lib/appsignal/demo.rb:49:in `create_example_error_request'",
      "action": "DemoController#hello",
      "path": "/hello",
      "hostname": "Toms-MacBook-Pro.local",
      "action_label": "request",
      "metadata": {
        "demo_sample": "true",
        "method": "GET",
        "path": "/hello"
      }
    }
  }
  ```
</CodeGroup>

### Fields

| Field       | Type                | Description                                        |
| ----------- | ------------------- | -------------------------------------------------- |
| `exception` | `Hash<String, Any>` | The webhook payload concerns a exception incident. |

#### Exception sub-fields

| Field                  | Type                   | Description                                                                                                                                                                                        |
| ---------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `time`                 | `String`               | Timestamp at which the exception occurred.                                                                                                                                                         |
| `number`               | `Integer`              | Incident id as shown on AppSignal.com.                                                                                                                                                             |
| `site`                 | `String`               | App name as seen on AppSignal.com. Using the `site` field instead of `app` for legacy reasons.                                                                                                     |
| `environment`          | `String`               | App environment of the app as seen on AppSignal.com.                                                                                                                                               |
| `app_url`              | `String`               | Url to the app on AppSignal.com that triggered the webhook.                                                                                                                                        |
| `url`                  | `String`               | Url to the specific sample for the incident on AppSignal.com that triggered this webhook.                                                                                                          |
| `revision`             | `String`               | The [deploy marker](/application/markers/deploy-markers) revision name.                                                                                                                            |
| `user`                 | `String`               | The user that created the marker. The user value can also be{" "} `null` if not set for a deploy marker revision.                                                                                  |
| `namespace`            | `String`               | The namespace in which this exception occurred.                                                                                                                                                    |
| `exception`            | `String`               | The exception type that was recorded by AppSignal.                                                                                                                                                 |
| `message`              | `String`               | The exception message with more details about the exception.                                                                                                                                       |
| `app_backtrace`        | `Array<String>`        | The lines of the backtrace concerning the app from which they originated. This excludes any backtrace lines from libraries that are included in the app.                                           |
| `first_backtrace_line` | `String`               | The first backtrace line from the `app_backtrace` field.                                                                                                                                           |
| `action`               | `String`               | The action in which this exception occurred. Either a controller action, background worker or a manually set action.                                                                               |
| `path`                 | `String`               | The request path on which the exception occurred. This is only set for web requests. This is metadata set by the AppSignal integration by default and is also included in the `metadata` field.    |
| `hostname`             | `String`               | The hostname of the host that this exception occurred on.                                                                                                                                          |
| `action_label`         | `String`               | A human friendly label for the type of action this exception occurred on. Uses `request` for the `web` namespace and{" "} `job` for the `background` namespace. All other namespaces use `action`. |
| `metadata`             | `Hash<String, String>` | This includes user set metadata (see [Tagging feature](/guides/tagging)).                                                                                                                          |

#### Metadata fields {/* id: exception-metadata-fields */}

You can add your own metadata by [tagging samples](/guides/tagging).

| Field         | Type     | Description                                                                                                                                                                                          |
| ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `demo_sample` | `String` | Set by the AppSignal integration for demo samples send using our demo command line tool ([Ruby](/ruby/command-line/demo) /{" "} [Elixir](/elixir/command-line/demo)). Not set for all other samples. |
| `method`      | `String` | The request method used to perform a request. Only available for (web) requests.                                                                                                                     |
| `path`        | `String` | The request path on which the exception occurred. This is only set for web requests. Contains the same value as the `path` field.                                                                    |

## Performance incidents

<CodeGroup>
  ```json JSON theme={null}
  {
    "performance": {
      "time": "2019-01-10 09:38:08 UTC",
      "number": 1,
      "site": "My test app",
      "environment": "development",
      "app_url": "https://appsignal.com/test/sites/5bd867fa2213937f3666ae7b",
      "url": "https://appsignal.com/test/sites/5bd867fa2213937f3666ae7b/incidents/1?timestamp=2019-01-10T09%3A38%3A08Z",
      "revision": "abc123",
      "user": "tom",
      "namespace": "web",
      "duration": 2004.904052734375,
      "action": "DemoController#hello",
      "path": "/hello",
      "hostname": "Toms-MacBook-Pro.local",
      "action_label": "request",
      "metadata": {
        "demo_sample": "true",
        "method": "GET",
        "path": "/hello"
      }
    }
  }
  ```
</CodeGroup>

### Fields

| Field         | Type                | Description                                          |
| ------------- | ------------------- | ---------------------------------------------------- |
| `performance` | `Hash<String, Any>` | The webhook payload concerns a performance incident. |

#### Performance sub-fields

| Field          | Type                   | Description                                                                                                                                                                                                        |
| -------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `time`         | `String`               | Timestamp at which the performance incident occurred.                                                                                                                                                              |
| `number`       | `Integer`              | Incident id as shown on AppSignal.com.                                                                                                                                                                             |
| `site`         | `String`               | App name as seen on AppSignal.com. Using the `site` field instead of `app` for legacy reasons.                                                                                                                     |
| `environment`  | `String`               | App environment of the app as seen on AppSignal.com.                                                                                                                                                               |
| `app_url`      | `String`               | Url to the app on AppSignal.com that triggered the webhook.                                                                                                                                                        |
| `url`          | `String`               | Url to the specific sample for the incident on AppSignal.com that triggered this webhook.                                                                                                                          |
| `revision`     | `String`               | The [deploy marker](/application/markers/deploy-markers) revision name.                                                                                                                                            |
| `user`         | `String`               | The user that created the marker. The user value can also be{" "} `null` if not set for a deploy marker revision.                                                                                                  |
| `namespace`    | `String`               | The namespace in which this performance incident occurred.                                                                                                                                                         |
| `duration`     | `Float`                | The time in milliseconds measured which the request/job/action took to complete.                                                                                                                                   |
| `action`       | `String`               | The action in which this performance incident occurred. Either a controller action, background worker or a manually set action.                                                                                    |
| `path`         | `String`               | The request path on which the performance incident occurred. This is only set for web requests. This is metadata set by the AppSignal integration by default and is also included in the `metadata`{" "} field.    |
| `hostname`     | `String`               | The hostname of the host that this performance incident occurred on.                                                                                                                                               |
| `action_label` | `String`               | A human friendly label for the type of action this performance incident occurred on. Uses `request` for the `web`{" "} namespace and `job` for the `background`{" "} namespace. All other namespaces use `action`. |
| `metadata`     | `Hash<String, String>` | This includes user set metadata see{" "} [metadata](/guides/tagging).                                                                                                                                              |

#### Metadata fields {/* id: performance-metadata-fields */}

You can add your own metadata by [tagging samples](/guides/tagging).

| Field         | Type     | Description                                                                                                                                                                                          |
| ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `demo_sample` | `String` | Set by the AppSignal integration for demo samples send using our demo command line tool ([Ruby](/ruby/command-line/demo) /{" "} [Elixir](/elixir/command-line/demo)). Not set for all other samples. |
| `method`      | `String` | The request method used to perform a request. Only available for (web) requests.                                                                                                                     |
| `path`        | `String` | The request path on which the performance incident occurred. This is only set for web requests. Contains the same value as the{" "} `path` field.                                                    |

## Anomaly detection

<CodeGroup>
  ```json JSON theme={null}
  {
    "alert_id": "5bdb1fb301925b0c4b6c7017",
    "state": "closed",
    "site": "google",
    "environment": "production",
    "tags": {
      "namespace": "web"
    },
    "human_tags": ["namespace: web"],
    "metric_name": "transaction_exception_rate",
    "field": "gauge",
    "trigger_label": "Exception rate",
    "trigger_description": "This is a description",
    "last_value": 12.0,
    "peak_value": 20.0,
    "mean_value": 11.0,
    "comparison_operator": "<",
    "comparison_value": 21.0,
    "human_last_value": "12 %",
    "human_peak_value": "20 %",
    "human_mean_value": "11 %",
    "human_comparison_value": "21 %",
    "created_at": "2017-08-01T10:00:00Z",
    "opened_at": "2017-08-01T10:05:00Z",
    "resolved_at": "2017-08-01T12:00:00Z",
    "closed_at": "2017-08-01T13:43:00Z",
    "warmup_duration": 10,
    "cooldown_duration": 20,
    "alert_url": "http://example.com/#{site.account.slug}/sites/#{site.id}/alerts/#{alert.id}",
    "edit_trigger_url": "http://example.com/#{site.account.slug}/sites/#{site.id}/triggers?overlay=triggerForm&triggerId=#{alert.trigger.id}"
  }
  ```
</CodeGroup>

| Field                    | Type     | Description                                                                                                            |
| ------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| `alert_id`               | `String` | Internal AppSignal alert id for the alert.                                                                             |
| `state`                  | `String` | [State](/anomaly-detection/#alert-states) of the alert.                                                                |
| `site`                   | `String` | The application name alert belongs to.                                                                                 |
| `environment`            | `String` | The application environment name alert belongs to.                                                                     |
| `tags`                   | `Array`  | Namespace associated with the alert.                                                                                   |
| `human_tags`             | `Array`  | Custom namespace associated with the alert.                                                                            |
| `metric_name`            | `String` | Name of the metric alert was created for.                                                                              |
| `field`                  | `String` | Field name of the alert.                                                                                               |
| `trigger_label`          | `String` | Name of the trigger.                                                                                                   |
| `trigger_description`    | `String` | Description of the trigger.                                                                                            |
| `last_value`             | `String` | Last value recorded for the alert.                                                                                     |
| `peak_value`             | `String` | Highest value recorded for the alert                                                                                   |
| `mean_value`             | `String` | Mean of all values for the alert.                                                                                      |
| `comparison_operator`    | `String` | Comparison operator set by the user based on which the alert will be triggered.                                        |
| `comparison_value`       | `String` | Comparison value of the metric set by the user based on which the alert will be triggered.                             |
| `human_last_value`       | `String` | Last metric value that recorded for the alert since it was opened in a more readable format.                           |
| `human_peak_value`       | `String` | Highest value of the metric value that was recorded for the alert while it was open.                                   |
| `human_mean_value`       | `String` | Mean value of the metric value for the alert while it was open in a more readable format.                              |
| `human_comparison_value` | `String` | Comparison value for the alert metric set by the user based on which the alert will be triggered in a readable format. |
| `created_at`             | `String` | Timestamp at which the alert was created.                                                                              |
| `opened_at`              | `String` | Timestamp (ISO8601) at which the alert was opened.                                                                     |
| `resolved_at`            | `String` | Timestamp (ISO8601) at which the alert was resolved.                                                                   |
| `closed_at`              | `String` | Timestamp (ISO8601) at which the alert was closed.                                                                     |
| `warmup_duration`        | `String` | Time in minutes AppSignal waits before opening a alert.                                                                |
| `cooldown_duration`      | `String` | Time in minutes AppSignal waits before closing a alert.                                                                |
| `alert_url`              | `String` | URl of the alert so user can view it on AppSignal.                                                                     |
| `edit_trigger_url`       | `String` | URl of the alert so user can edit it on AppSignal.                                                                     |

<hr />

### Integrations list

* [Asana](/application/integrations/asana)
* [Discord](/application/integrations/discord)
* [Geckoboard](/application/integrations/geckoboard)
* [GitLab](/application/integrations/gitlab)
* [Google Hangouts Chat](/application/integrations/hangouts)
* [Jira](/application/integrations/jira)
* [Linear](/application/integrations/linear)
* [Microsoft Teams](/application/integrations/teams)
* [OpsGenie](/application/integrations/opsgenie)
* [PagerDuty](/application/integrations/pagerduty)
* [Shortcut](/application/integrations/shortcut)
* [Slack](/application/integrations/slack)
* [Squadcast](/application/integrations/squadcast)
* [Trello](/application/integrations/trello)
* [Webhooks](/application/integrations/webhooks)
