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

# Setting up alert destinations

> Connect PagerDuty, Slack, Microsoft Teams, Opsgenie, or a custom webhook to receive HASP platform alerts.

Alert destinations let your team receive HASP platform events — API key revocations, spend threshold breaches, deployment failures, and more — in the tools your on-call rotation already uses.

Navigate to **Account → Notifications → Alerts** to add destinations and configure which event categories each route delivers.

<Note>
  HASP delivers event metadata to the destination you configure. Like webhooks, you're responsible for what happens at your end — including your account and plan terms with the vendor. Our payloads never contain PHI.
</Note>

***

## PagerDuty

PagerDuty receives alerts via the [Events API v2](https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTgx-send-an-alert-event). Each delivery creates or resolves an alert on your PagerDuty service.

### Getting the routing key

1. In PagerDuty, go to **Services → Service Directory** and open (or create) the service you want HASP to alert.
2. Open the **Integrations** tab and click **Add an integration**.
3. Search for **Events API V2** and click **Add**.
4. Copy the **Integration Key** shown on the integrations list — this is your routing key.

### Fields

| Field           | Value                                       |
| --------------- | ------------------------------------------- |
| **Routing key** | 32-character integration key from PagerDuty |

### Deduplication

HASP computes a stable dedup key per event as `sha256("{org_id}:{event_type}:{resource_id}")`. PagerDuty uses this key to collapse repeated alerts for the same event into a single incident rather than filing duplicates.

### Common pitfalls

* **Wrong service type.** Use a service with the **Events API V2** integration. The older Prometheus or Generic API integrations use a different key format.
* **Stale key.** If you cycle the integration key in PagerDuty, update the destination in HASP and send a test alert to confirm.

***

## Slack

HASP posts alerts as formatted messages to a Slack channel via an incoming webhook URL.

### Getting the webhook URL

1. In Slack, go to **Apps → Incoming Webhooks** (or create a new Slack app at [api.slack.com/apps](https://api.slack.com/apps)).
2. Enable **Incoming Webhooks** and click **Add New Webhook to Workspace**.
3. Select the channel you want HASP to post to and click **Allow**.
4. Copy the webhook URL — it starts with `https://hooks.slack.com/services/...`.

### Fields

| Field           | Value                                                   |
| --------------- | ------------------------------------------------------- |
| **Webhook URL** | Full Slack webhook URL from the Slack app configuration |

### Deduplication

Slack does not deduplicate natively. HASP uses an app-side cache (60 s TTL) keyed on `org_id + event_type + resource_id` to suppress duplicate deliveries within that window.

### Common pitfalls

* **Webhook URL tied to a deactivated Slack app.** If the Slack app is deleted or its webhook is revoked, deliveries will fail and the destination will auto-deactivate after 10 consecutive failures. Recreate the webhook and update the destination.
* **Private channels.** The Slack app must be invited to private channels before it can post. Run `/invite @YourApp` in the channel.

***

## Microsoft Teams

HASP posts alert cards to a Teams channel via an incoming webhook connector.

### Getting the webhook URL

1. In Teams, right-click the channel you want HASP to post to and select **Manage channel → Connectors**.
2. Search for **Incoming Webhook** and click **Configure**.
3. Give the webhook a name (e.g. "HASP Alerts"), optionally upload a logo, and click **Create**.
4. Copy the webhook URL — it ends with `.webhook.office.com/...`.

### Fields

| Field           | Value                           |
| --------------- | ------------------------------- |
| **Webhook URL** | Full Teams incoming webhook URL |

### Deduplication

Same app-side 60 s dedup as Slack. Microsoft Teams connectors have no native dedup.

### Common pitfalls

* **Connector retirement.** Microsoft is deprecating Office 365 Connectors. If your webhook URL stops working, your Teams admin may need to re-enable connectors or migrate to a Power Automate flow that exposes its own webhook URL. Use the **Test** button after any change.
* **Message size limits.** Teams rejects messages over \~28 KB. HASP's alert cards are well within this limit, but very long error messages in metadata are truncated to 2,048 characters before delivery.

***

## Opsgenie

HASP creates and closes Opsgenie alerts via the [Alerts API](https://docs.opsgenie.com/docs/alert-api).

### Getting the API key

1. In Opsgenie, go to **Settings → API key management**.
2. Click **Add new API key**.
3. Give it a name and assign the **Create and Close Alerts** access right.
4. Copy the key and store it securely — Opsgenie only shows it once.

Alternatively, use a [team-scoped integration key](https://docs.opsgenie.com/docs/api-integration): navigate to the team → **Integrations** tab → **Add integration → API**.

### Fields

| Field       | Value                                    |
| ----------- | ---------------------------------------- |
| **API key** | Opsgenie API key or team integration key |

### Deduplication

Opsgenie uses the `alias` field as its native dedup key. HASP sets `alias` to the same `sha256("{org_id}:{event_type}:{resource_id}")` used for PagerDuty, so repeated alerts for the same event update the existing Opsgenie alert rather than creating duplicates.

### Common pitfalls

* **Wrong API region.** If your Opsgenie instance is in the EU region (`app.eu.opsgenie.com`), the HASP delivery endpoint is `https://api.eu.opsgenie.com/v2/alerts`. Contact support if you need EU-region delivery — the standard destination type posts to the US endpoint.
* **Rate limits.** Opsgenie's free tier allows 60 calls/minute per API key. High-frequency events (e.g., a spend threshold hit repeatedly) are already deduplicated; if you see 429 responses, reduce the alert frequency upstream.

***

## Raw webhook

Send a JSON payload to any HTTPS endpoint you control. Use this to connect services not listed above, or to fan out alerts to a custom aggregator.

### Fields

| Field   | Value                                                   |
| ------- | ------------------------------------------------------- |
| **URL** | HTTPS URL of the endpoint (HTTP allowed in development) |

### Payload format

```json theme={null}
{
  "event_id": "01JQW000000000000000000",
  "event_type": "spend.threshold_breached",
  "category": "console",
  "severity": "warning",
  "summary": "Spend threshold breached at 80%",
  "occurred_at": "2026-05-19T07:00:00+00:00",
  "org_id": "01JQORG0000000000000000",
  "resource": {
    "type": "ai_gateway",
    "id": "01JQORG0000000000000000"
  },
  "metadata": {
    "threshold_percentage": 80,
    "current_spend_credits": 80000,
    "cap_amount_credits": 100000
  }
}
```

Headers included on every delivery:

| Header                    | Value                 |
| ------------------------- | --------------------- |
| `Content-Type`            | `application/json`    |
| `X-Hasp-Alert-Event-Id`   | The event ULID        |
| `X-Hasp-Alert-Event-Type` | The event type string |
| `User-Agent`              | `Hasp-Alert/1.0`      |

### Deduplication

App-side 60 s cache keyed on `org_id + event_type + resource_id`. Duplicate deliveries within that window write a `deduplicated` delivery record instead of posting.

### Retry behavior

Failed deliveries are retried up to 5 times with exponential back-off: 10 s → 60 s → 5 min → 30 min → 2 hr. After 10 consecutive failures across all deliveries to a destination, HASP auto-deactivates it and emits an `alerting.destination_deactivated` audit event. Re-activate it from the **Alerts** page once the issue is resolved.

### Common pitfalls

* **Private IP or localhost URLs.** HASP blocks deliveries to RFC 1918 addresses and loopback to prevent SSRF. Use a publicly reachable URL.
* **Non-2xx responses.** Any non-2xx status code is treated as a failure and triggers a retry. Return `200 OK` (or any 2xx) even if you process the payload asynchronously.
* **Slow endpoints.** The delivery timeout is 10 seconds. If your endpoint takes longer, return `200 OK` immediately and process the payload in the background.

***

## Testing a destination

After adding a destination, click **Test** on the destination card to send a synthetic `alerting.test_delivery` event. The test fires one attempt (no retries) and reports success or failure inline. Use this to confirm credential and URL validity before routing live events.
