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

# AppSignal alert integration

> Send AppSignal exception incidents, performance incidents, and anomaly detection alerts to Flashduty On-call through a webhook notifier.

Use the AppSignal Webhook notifier to send exception incidents, performance incidents, and anomaly detection alerts to Flashduty On-call. The three payload types behave differently:

* **Anomaly detection alerts**: the alert triggers when it opens and recovers when it is resolved.
* **Exception and performance incidents**: AppSignal sends them when an incident is created, reopened, or occurs again, and sends no recovery, so these alerts do not recover on their own. Turn on the auto-resolve timeout in the channel, as described in [Incidents do not recover](#incidents-do-not-recover).
* **Deploy markers**: not alerts. Flashduty acknowledges them and creates nothing.

<div className="hide">
  ## In Flashduty On-call

  ***

  You can obtain an integration push URL in either of the following ways.

  ### Use a dedicated integration

  1. In the Flashduty console, select **Channel** and open a channel
  2. Select **Configuration** → **Integrations** → **Private integration**, then click **Add an integration**
  3. Select **AppSignal**, then click **Save**
  4. Open the generated integration card and copy the **Push URL**

  ### Use a shared integration

  1. In the Flashduty console, select **Integration Center → Alert Events**
  2. Select **AppSignal** and enter an integration name
  3. Configure the default route and select a channel; after creation, add more rules under **Route** if needed
  4. Click **Save** and copy the generated **Push URL**
</div>

## In AppSignal

***

<Steps>
  <Step title="Add a Webhook notifier">
    1. Sign in to AppSignal and open **Organization settings** → **Notifications** (managing notifiers requires organization admin permission)
    2. Click **Add new notifier** and choose **Webhook**
    3. Enter a **Name** and paste the full Flashduty push URL, including `integration_key`, as **Webhook URL**
    4. Under **Scope notifier to the following apps**, select the apps to notify for. A notifier with no app selected sends nothing
    5. Under **Send notifications for the following events**, tick **Errors** (exception incidents) and **Performance** (performance incidents). Deploy markers create no alerts, so you can leave **Deploys** unticked. Anomaly detection alerts are chosen per trigger, see the next step

    AppSignal adds an `X-Appsignal-Signature` header to every request. Flashduty does not verify it and authenticates with the `integration_key` in the push URL.
  </Step>

  <Step title="Select the notifier where it should fire">
    Creating the notifier is not enough. AppSignal sends notifications only to notifiers selected in these places:

    * **Anomaly detection alerts**: tick the notifier under **Notify me through** when you save the trigger. AppSignal sends an alert only to the notifiers selected on its trigger
    * **Exception and performance incidents**: the notifier's app scope and the **Errors** and **Performance** boxes set this. Adjust the notification frequency (Every Occurrence, First in Deploy, First After Close, and so on) as needed
  </Step>

  <Step title="Verify">
    1. Put a trigger into the alert state in AppSignal, or raise a new exception in your app, and confirm Flashduty receives an active alert
    2. After the anomaly detection alert is resolved, confirm the Flashduty alert recovers

    The AppSignal documentation does not describe a test button for the Webhook notifier, so verify with a real event.
  </Step>
</Steps>

## Events and recovery

***

| AppSignal payload | When it is sent | Effect in Flashduty |
| :- | :- | :- |
| Anomaly detection alert, `state` is `open` | The trigger's threshold condition holds and warm-up has passed | Triggers an alert |
| Anomaly detection alert, `state` is `resolved`, `closed`, or `ended`, or `resolved_at` or `closed_at` is set | The alert is resolved | Recovers the alert |
| Exception incident (`exception`) | A new exception, a closed exception that occurs again, or another occurrence per the notification frequency | Triggers or updates the incident's alert |
| Performance incident (`performance`) | A new slow-request incident, or another occurrence | Triggers or updates the incident's alert |
| Deploy marker (`marker`) | A new deploy | Ignored |

AppSignal notifies webhooks only on two anomaly detection transitions, opened and resolved. The warming up and cooldown phases send nothing.

## Alert Key

***

Flashduty builds the Alert Key from the object the event is about, so every delivery for one object shares one Alert Key:

| Object | Fields used |
| :- | :- |
| Anomaly detection alert | `alert_id` |
| Exception and performance incidents | `site`, `environment`, and `number` (the incident number) |

Exception and performance incidents share one incident numbering. The Alert Key is computed from the object type and the fields above, so changes to the trigger name, current value, time, exception message, or revision do not change it. A delivery missing one of these fields is rejected, and the error names the field.

## Severity

***

AppSignal payloads carry no severity, so every alert is Warning in Flashduty, and a recovery moves it to recovered. To distinguish severity, use labels in the integration's routing or alert processing rules.

## Incidents do not recover

***

AppSignal sends no recovery for exception and performance incidents. In the channel that receives this integration, turn on the [auto-resolve timeout](/en/on-call/channel/create-edit). 24 hours is a reasonable start; adjust it to how quickly your team handles exceptions. A repeat occurrence of the same incident updates the same alert; once the alert is closed, the next occurrence creates a new one.

## Labels

***

| Label | Source |
| :- | :- |
| `source` | Always `appsignal` |
| `resource` / `env` | App name (`site`) and environment |
| `check` | The alert title: trigger name, exception class and message, or the slow request's action |
| `alert_id` / `state` | ID and state of the anomaly detection alert |
| `metric_name` | Metric the trigger watches |
| `tags` | Tags scoping the alert, comma separated |
| `last_value` / `threshold` | Current value and threshold, such as `12 %` and `> 5 %` |
| `incident_number` | Incident number |
| `error_class` | Exception class |
| `namespace` / `action` / `path` / `host` | Namespace, action, request path, and host of the incident |
| `duration_ms` | Duration of a performance incident, in milliseconds |
| `revision` | Deployed revision |
| `url` | Link to the alert or incident in AppSignal |

## Troubleshooting

***

* **Flashduty returns an invalid parameter error**: confirm the URL is complete and includes `integration_key`
* **Nothing arrives**: confirm the Webhook notifier is selected on the trigger (alerts) or in the app's notification settings (incidents), and that the payload types are selected
* **An exception is not sent again**: AppSignal follows the incident's notification frequency. An incident set to Never Notify sends nothing and is not reopened
* **An alert never recovers**: exception and performance incidents have no recovery, see the auto-resolve timeout above. An anomaly detection alert recovers only after AppSignal resolves it. AppSignal sends the resolution with `state` `closed` and both `resolved_at` and `closed_at` set. A trigger on a count metric that stops reporting keeps its alert open unless **Treat missing datapoint as 0** is ticked on the trigger, and changing a trigger archives its open alerts without sending a webhook

For field details, see [AppSignal webhooks](https://docs.appsignal.com/application/integrations/webhooks) and [anomaly detection](https://docs.appsignal.com/anomaly-detection).
