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

# Webhook Alerts: real-time depeg and risk event delivery

> Subscribe to Webacy webhooks for DEPEG_TIER_CHANGE stablecoin and RWA alerts with HMAC-signed delivery, tier and chain filters, and automatic retries.

## Overview

Webacy Webhooks push risk events to your endpoint in real time. Instead of polling our API, you receive a signed HTTP `POST` the moment something happens.

| Pull Model (API)           | Push Model (Webhooks)         |
| -------------------------- | ----------------------------- |
| You poll for updates       | We notify you instantly       |
| Higher latency             | Sub-second delivery           |
| More API calls             | Efficient, event-driven       |
| Good for on-demand queries | Ideal for monitoring & alerts |

## Common use cases

Webhooks fit any workflow that needs to react the moment a token's risk changes. Pick the filters that match your job and you only receive the events you care about.

| Use case                           | What you build                                                       | Filters to set                                              |
| ---------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------- |
| Treasury / desk alerting           | Slack or PagerDuty alert when a held stablecoin starts to depeg      | `tiers: ["warning", "critical"]`, `tokens: [your holdings]` |
| Automated de-risking / hedging     | A trading system that unwinds or hedges exposure when risk escalates | `tiers: ["critical"]`, `minDeviationPct`                    |
| Compliance & monitoring dashboards | A live risk board that refreshes on every tier change                | none (receive all events)                                   |
| Portfolio / fund monitoring        | A per-chain watch on the assets you manage                           | `chains`, `tokens`                                          |
| Incident response / audit trail    | A log of every transition, replayable via `GET /webhooks/deliveries` | `eventTypes: ["DEPEG_TIER_CHANGE"]`                         |

For a full build-along, see the [Webhook integration tutorial](/essentials/webhooks-tutorial). The [Example workflow](#example-workflow) below wires one of these use cases end to end.

## Available events

### DEPEG\_TIER\_CHANGE

Fires when a stablecoin or RWA token's **depeg risk tier** changes (for example `ok → warning` or `warning → critical`). Tiers follow the [Depeg Monitor ratings](/api-reference/depeg-monitor): `ok`, `watch`, `warning`, and `critical`, plus `premium` for tokens trading above peg.

<Accordion title="Example delivered payload">
  ```json theme={null}
  {
    "event": {
      "event_type": "DEPEG_TIER_CHANGE",
      "event_id": "1a0d2b92-7142-44de-8a7c-7faa57c96df3",
      "timestamp": "2026-06-19T18:01:30.702Z",
      "data": {
        "token_address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
        "chain": "eth",
        "symbol": "USDT",
        "old_tier": "ok",
        "new_tier": "warning",
        "risk_score": 65.0,
        "deviation_pct": 2.5,
        "price_usd": "0.975",
        "peg_usd": "1.000"
      }
    },
    "signature": "cb5b82afcc3e18a064057adbd47718ee719fd1658765cbe407a7e84770b8afd7",
    "delivered_at": "2026-06-19T18:01:30.702Z"
  }
  ```
</Accordion>

## Subscribe (self-serve)

Webhook subscriptions are managed with your standard API key (the `x-api-key` header). Create a subscription, pick your filters, and we start delivering.

```bash theme={null}
curl -X POST https://api.webacy.com/webhooks/subscriptions \
  -H "x-api-key: $WEBACY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "webhookUrl": "https://yourapp.com/webhooks/webacy",
    "eventTypes": ["DEPEG_TIER_CHANGE"],
    "filters": {
      "tiers": ["warning", "critical"],
      "chains": ["eth", "polygon"],
      "minDeviationPct": 1.0
    }
  }'
```

The `201` response returns the subscription, including a **`secret_key`** used to verify signatures:

```json theme={null}
{
  "id": "42",
  "webhook_url": "https://yourapp.com/webhooks/webacy",
  "event_types": ["DEPEG_TIER_CHANGE"],
  "filters": { "tiers": ["warning", "critical"], "chains": ["eth", "polygon"], "minDeviationPct": 1.0 },
  "secret_key": "store-this-now-it-is-never-shown-again",
  "is_active": true,
  "created_at": "2026-06-19T18:00:00.000Z"
}
```

<Warning>
  The `secret_key` is returned **only** on creation (and on `rotate-secret`). Store it securely — it is never shown again.
</Warning>

**Filters** (all optional, ANDed together):

| Field             | Meaning                                                                                     |
| ----------------- | ------------------------------------------------------------------------------------------- |
| `tiers`           | Only notify when the new tier is one of `ok` / `watch` / `warning` / `critical` / `premium` |
| `chains`          | Only notify for these chains (e.g. `eth`, `polygon`)                                        |
| `tokens`          | Only notify for these token contract addresses (case-insensitive)                           |
| `minDeviationPct` | Only notify when deviation from peg (percent) is at least this value                        |

See the [API reference](/api-reference/introduction) for the full subscription and delivery endpoints (`GET/PATCH/DELETE /webhooks/subscriptions/{id}`, `POST /webhooks/subscriptions/{id}/test`, `rotate-secret`, and `GET /webhooks/deliveries`).

## What you receive

Each delivery is an HTTP `POST` to your `webhookUrl` with this body:

```json theme={null}
{ "event": { ... }, "signature": "<hmac-sha256-hex>", "delivered_at": "<iso-8601>" }
```

and these headers:

| Header                | Value                                        |
| --------------------- | -------------------------------------------- |
| `X-Event-Type`        | `DEPEG_TIER_CHANGE`                          |
| `X-Webhook-Signature` | HMAC-SHA256 hex digest of the `event` object |
| `X-Event-ID`          | Unique event id (for idempotency)            |

## Verify the signature

The signature is `HMAC-SHA256` of the **JSON-serialized `event` object** (compact, no spaces), keyed by your subscription's `secret_key`, hex-encoded. It is sent both as `X-Webhook-Signature` and as `signature` in the body. Always verify before trusting a payload.

<Warning>
  Hash the `event` object exactly as received — don't re-order keys or reformat numbers before serializing, or the digest won't match.
</Warning>

<CodeGroup>
  ```javascript Node.js theme={null}
  const crypto = require("crypto");

  // secret = the subscription's secret_key (from creation/rotate-secret)
  function isValid(body, secret) {
    // reject missing/malformed signatures before any buffer work
    if (typeof body?.signature !== "string" || !/^[a-f0-9]{64}$/i.test(body.signature)) {
      return false;
    }
    const expected = crypto
      .createHmac("sha256", secret)
      .update(JSON.stringify(body.event)) // compact JSON of the event object
      .digest("hex");
    // decode as hex (32-byte digests), not UTF-8; timingSafeEqual needs equal lengths
    const expectedBuf = Buffer.from(expected, "hex");
    const providedBuf = Buffer.from(body.signature, "hex");
    return expectedBuf.length === providedBuf.length &&
      crypto.timingSafeEqual(expectedBuf, providedBuf);
  }

  // Express example
  app.post("/webhooks/webacy", express.json(), (req, res) => {
    if (!isValid(req.body, process.env.WEBACY_WEBHOOK_SECRET)) {
      return res.status(401).end();
    }
    // ...handle req.body.event...
    res.status(200).end(); // any 2xx acknowledges and stops retries
  });
  ```

  ```python Python theme={null}
  import hmac, hashlib, json

  def is_valid(body: dict, secret: str) -> bool:
      expected = hmac.new(
          secret.encode(),
          # compact JSON of the event object; ensure_ascii=False matches our serializer
          json.dumps(body["event"], separators=(",", ":"), ensure_ascii=False).encode(),
          hashlib.sha256,
      ).hexdigest()
      return hmac.compare_digest(expected, body["signature"])

  # Flask example
  @app.post("/webhooks/webacy")
  def webacy_webhook():
      body = request.get_json()
      if not is_valid(body, os.environ["WEBACY_WEBHOOK_SECRET"]):
          return "", 401
      # ...handle body["event"]...
      return "", 200  # any 2xx acknowledges and stops retries
  ```
</CodeGroup>

<Tip>
  Test your integration without waiting for a real event: `POST /webhooks/subscriptions/{id}/test` delivers a synthetic `DEPEG_TIER_CHANGE` to your endpoint.
</Tip>

## Example workflow

A worked end-to-end scenario: **auto-hedge when a holding hits `critical`**. It ties together the subscription, signature check, and your reaction logic.

<Steps>
  <Step title="Subscribe to critical tier changes">
    Create a subscription scoped to the tokens you hold and the `critical` tier, so you're only paged on the events that require action. Save the `secret_key` from the response.

    ```bash theme={null}
    curl -X POST https://api.webacy.com/webhooks/subscriptions \
      -H "x-api-key: $WEBACY_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "webhookUrl": "https://yourapp.com/webhooks/webacy",
        "eventTypes": ["DEPEG_TIER_CHANGE"],
        "filters": {
          "tiers": ["critical"],
          "tokens": ["0xdac17f958d2ee523a2206206994597c13d831ec7"]
        }
      }'
    ```
  </Step>

  <Step title="Verify, then act on the event">
    In your receiver, verify the signature (see [Verify the signature](#verify-the-signature)), then branch on `new_tier`. Return any `2xx` to acknowledge so the delivery isn't retried.

    ```javascript theme={null}
    app.post("/webhooks/webacy", express.json(), (req, res) => {
      if (!isValid(req.body, process.env.WEBACY_WEBHOOK_SECRET)) {
        return res.status(401).end();
      }

      const { data } = req.body.event;
      if (data.new_tier === "critical") {
        // 3. Trigger your de-risking / hedging action
        hedgeExposure(data.token_address, data.chain);
      }

      res.status(200).end(); // ack; any 2xx stops retries
    });
    ```
  </Step>

  <Step title="Dry-run before going live">
    Fire a synthetic delivery so you can confirm the full path — signature check plus your hedging logic — without waiting for a real depeg:

    ```bash theme={null}
    curl -X POST https://api.webacy.com/webhooks/subscriptions/{id}/test \
      -H "x-api-key: $WEBACY_API_KEY"
    ```
  </Step>
</Steps>

## Delivery & retries

* Respond with any **2xx** to acknowledge. A non-2xx response or timeout is retried with backoff, up to **5 attempts**.
* Inspect delivery history with `GET /webhooks/deliveries` (filter by `status` / `eventType`, paginated). Statuses include `pending`, `success`, `failed`, and `max_retries_exceeded`.
* Re-send a failed delivery with `POST /webhooks/deliveries/{id}/retry` (rate-limited to once per delivery per 5 minutes).
* `webhookUrl` must be a public **HTTPS** endpoint; private/loopback hosts are rejected.
* Each subscription API call and each delivery consumes **1 CU**.

## Additional event types (in development)

The following Solana real-time events are **not yet generally available** — contact us if your use case needs them:

* `TOKEN_LAUNCH_ANALYSIS` — risk analysis at token launch
* `TOKEN_TRANSACTION` — per-transaction buy/sell alerts on monitored tokens
* `HOLDER_ANALYSIS_UPDATE` — holder-distribution snapshots at post-launch checkpoints

## Related resources

<CardGroup cols={2}>
  <Card title="Webhook integration tutorial" icon="list-check" href="/essentials/webhooks-tutorial">
    Stand up a receiver, verify signatures, and subscribe — step by step
  </Card>

  <Card title="Depeg Monitor API" icon="magnifying-glass-chart" href="/api-reference/depeg-monitor">
    The tiers and risk ratings that drive `DEPEG_TIER_CHANGE` events
  </Card>

  <Card title="Stablecoin depeg monitoring" icon="chart-line-down" href="/guides/stablecoin-depeg-monitoring">
    Use-case guide for tracking stablecoin and RWA peg health
  </Card>

  <Card title="Trading bot risk engine" icon="robot" href="/guides/trading-bot-risk-engine">
    Wire real-time risk signals into automated trading decisions
  </Card>
</CardGroup>

## Getting access

`DEPEG_TIER_CHANGE` webhooks work with your existing API key. Don't have one yet? Sign up at [developers.webacy.co](https://developers.webacy.co/). For help sizing volume, email [info@webacy.com](mailto:info@webacy.com).
