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

# Webhook automations

> File an issue for each signed alert from Sentry, PagerDuty or another service, and read the run log.

A webhook automation files one issue for each alert that arrives at its URL with a valid signature. The issue goes in a repository, Linear team or Jira project of your factory. It shows on the Work page as **Not started** until a member chooses **Build** on the item's page. See [Build an item that is not started](https://docs-stg.outerlayer.ai/the-work-page.md#build-an-item-that-is-not-started).

A webhook automation works for Sentry, for PagerDuty, and for any service that signs its requests in the [Standard Webhooks](https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md) format. A service that cannot sign does not work, such as one that sends only a static token.

## Why an alert's issue waits

An alert carries text from production traffic, such as an error message or a request path. Anyone can send a request that makes your app throw an error with a message they choose. That holds even when a service you trust sends the alert.

So no automation builds an alert's issue. A member reads the issue first and then chooses **Build** on the item's page. See [Why an issue from outside the team waits](https://docs-stg.outerlayer.ai/automations.md#why-an-issue-from-outside-the-team-waits) and [Build an item that is not started](https://docs-stg.outerlayer.ai/the-work-page.md#build-an-item-that-is-not-started).

The text of an alert goes into the issue as plain text. A mention in it notifies no person or team in GitHub, Linear or Jira. A link, an image or a hidden comment in it shows as text.

## Add a webhook automation

You need the **Edit factory settings** permission. The factory needs a connected repository, Linear team or Jira project. See [Connect a repository](https://docs-stg.outerlayer.ai/connect-repository.md) and [Connect an issue tracker](https://docs-stg.outerlayer.ai/connect-a-tracker.md).

For Sentry or PagerDuty, start at [Set up Sentry](#set-up-sentry) or [Set up PagerDuty](#set-up-pagerduty). Each one says when to do these steps.

1. Open **Settings**, then **Automations**.
2. Choose **New automation**, then choose **Webhook**.
3. Enter a name.
4. Under **Sender**, choose **Sentry**, **PagerDuty** or **Any JSON**. You cannot change the sender after you save.
5. Under **File the issue in**, choose a repository, Linear team or Jira project.
6. Check **Issue title**, **Issue body** and **One open issue for each**. Change them if you want.
7. For **Sentry** or **PagerDuty**, paste the sender's secret in **Signing secret**.
8. Set the **Daily limit**: the most issues the automation files in 24 hours. The default is 5, and you can set 1 to 100.
9. Choose **Save**.

The automation is on as soon as you save it. It shows in the **Webhooks** group. Choose its name to open its page, which shows its **URL**. Choose **Copy** and give the URL to the sender.

### The issue title, body and alert key

Put a field of the alert in double braces, such as `{{ data.event.title }}`. Put a dot between the names of nested fields. A field that the alert does not hold is empty.

When you choose **Sentry** or **PagerDuty**, the form fills in all three fields. You can change them. The title is cut to one line of 255 characters. OuterLayer adds a last line to the body that names the automation and the alert key.

**One open issue for each** holds the alert key: the alert field that names one alert. While an issue that the automation filed for a key is open, a new alert with the same key files nothing. When the issue closes, the next alert with that key files a new issue.

| Sender | Default alert key | Can it be empty? |
| - | - | - |
| **Sentry** | `{{ data.event.issue_id }}` | No |
| **PagerDuty** | `{{ event.data.id }}` | No |
| **Any JSON** | None | Yes. Each alert then files its own issue. |

## Set up Sentry

1. In Sentry, create an internal integration.
2. Copy the **Client Secret** of the integration.
3. In OuterLayer, [add the automation](#add-a-webhook-automation) with the sender **Sentry**. Paste the **Client Secret** in **Signing secret**.
4. Copy the automation's URL.
5. In Sentry, set the webhook URL of the integration to that URL.
6. Turn on **Alert Rule Action** for the integration.
7. Create an alert rule in Sentry. Add an action that sends a notification through your integration.

Only a notification from an alert rule files an issue. That request has the header `Sentry-Hook-Resource: event_alert` and the action `triggered`. The automation ignores every other request from Sentry.

## Set up PagerDuty

PagerDuty needs the automation's URL before it shows a signing secret, and the automation needs a secret before it has a URL. So add the automation with a temporary secret, and replace it.

1. In OuterLayer, [add the automation](#add-a-webhook-automation) with the sender **PagerDuty**. Enter a long random text in **Signing secret** for now.
2. Copy the automation's URL.
3. In PagerDuty, create a V3 webhook subscription with that URL.
4. Choose the event `incident.triggered`.
5. Copy the signing secret of the subscription.
6. In OuterLayer, choose **Edit** on the automation. Paste the secret in **Signing secret** and choose **Save**.
7. Send a test from PagerDuty. The run log shows "Received a test from PagerDuty".

Only the event `incident.triggered` files an issue. The automation ignores every other event.

> [!WARNING]
>
> PagerDuty turns a subscription off for 24 hours after three dropped deliveries in a row. OuterLayer answers 401 to a request it refuses, and PagerDuty counts that as a dropped delivery.

When the run log shows **Refused** for PagerDuty, fix the cause before PagerDuty sends two more requests. A wrong signing secret is the usual cause. If PagerDuty turned the subscription off, turn it on again in PagerDuty.

## Set up any other service

Choose **Any JSON** for a service that signs in the Standard Webhooks format.

OuterLayer makes the signing secret when you save the automation. The secret starts with `whsec_`. The page that opens after the save shows it once. Copy it then, and give it to the service with the URL.

> [!WARNING]
>
> OuterLayer shows the secret of an **Any JSON** automation once and cannot make a new one. If you lose the secret, delete the automation and add a new one.

The service must sign each request this way:

* It sends the headers `webhook-id`, `webhook-timestamp` and `webhook-signature`. The names `svix-id`, `svix-timestamp` and `svix-signature` also work.
* It signs the text `<id>.<timestamp>.<body>` with HMAC-SHA256. The key is the base64-decoded bytes after `whsec_`.
* The signature header holds `v1,` and the base64 digest. It can hold several signatures with spaces between them.

OuterLayer refuses a request whose timestamp is more than 5 minutes from the time it arrives. Every request with a valid signature files an issue.

## Replace a signing secret

You can replace the secret of a **Sentry** or **PagerDuty** automation.

1. Open the automation and choose **Edit**.
2. Paste the new secret in **Signing secret**. An empty field keeps the stored secret.
3. Choose **Save**.

After the change, a request that is signed with the old secret files nothing. The run log shows it as **Refused**.

## When an alert files no issue

A request files nothing in these cases. The run log names the reason for most of them.

* **The signature is not valid, or the request is not JSON.** A request can hold at most 256 KB.
* **The sender sent the same delivery again.** One delivery files at most one issue, and the copy writes no row.
* **An issue for the same alert key is still open.**
* **The automation reached its daily limit** of issues in the last 24 hours.
* **The automation is off.** It writes no row.
* **The tracker refused the issue.** The run log shows the tracker's answer.

If OuterLayer cannot reach the tracker, it tries again for 24 hours. Then the run log shows **Failed**.

Sentry and PagerDuty sign no timestamp, so someone who captured a request can send it again. While the issue for its alert key is open, the copy files nothing. After the issue closes, the copy files a new issue, within the daily limit.

## Read the run log

Open **Settings**, then **Automations**, then choose the automation. Its page shows the run log, newest first. Each row has the time, the alert key, the result and the reason. OuterLayer keeps each row for 90 days.

| Result | What it means | What you do |
| - | - | - |
| **Filed** | The automation filed the issue. The row links to it. | Read the issue. Then choose **Build** on the item's page. See [Build an item that is not started](https://docs-stg.outerlayer.ai/the-work-page.md#build-an-item-that-is-not-started). |
| **Skipped** | An issue for the alert key is still open, the automation reached its daily limit, or PagerDuty sent a test. | Nothing. Raise the daily limit if you need more issues. |
| **Refused** | The signature does not match, the request is not JSON, it is larger than 256 KB, or its timestamp is more than 5 minutes old. | Check the signing secret on both sides. |
| **Failed** | The tracker refused the issue, or OuterLayer could not file it. | Read the tracker's answer in the row and fix what it names. |

A request that the automation ignores writes no row. A request to an automation that is off writes none. OuterLayer logs at most 20 **Refused** rows for each automation in one hour.

## Change, switch off or delete an automation

You need the **Edit factory settings** permission. Without it, you can read the automation and its run log.

1. Choose the automation to open its page.
2. Use the switch to turn the automation on or off.
3. To change the automation, choose **Edit**.
4. To delete the automation and its run log, choose **Delete** and confirm.

Issues that the automation already filed stay in your tracker and on the Work page.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.