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

# Notifications and Event Streams

> Use notification channels, audit logs, and polling to stream SuperVault operational events.

Curate exposes two event surfaces for operators:

1. **Notification channels** for routed operational alerts.
2. **Audit logs and polling** for integration-grade event reconstruction.

Use notification channels for humans and incident destinations. Use audit logs / state polling for deterministic integrations.

## Notification Channels

Create a channel, then bind it to the vaults that should send alerts.

```bash theme={null}
# List or create channels
GET /api/v1/notification-channels
POST /api/v1/notification-channels

# List or bind channels for one vault
GET /api/v1/vaults/{chain_id}/{vault_address}/notification-channels
POST /api/v1/vaults/{chain_id}/{vault_address}/notification-channels/{channel_id}

# Unbind a channel
DELETE /api/v1/vaults/{chain_id}/{vault_address}/notification-channels/{channel_id}
```

Recommended alert categories:

* Upkeep shortfall or activation loss.
* PPS staleness.
* Failed keeper runs.
* Session-key readiness changes.
* Emergency pause / unpause.
* Emergency liquidity exit arm / stop.
* Merkle generation or publish failure.
* Repeated OMS execution failure.

See [Alerts](/curate/ui/alerts) for the operator flow.

## Audit Logs as an Event Stream

The audit log endpoint records vault operations and manager actions:

```bash theme={null}
GET /api/v1/audit/logs
Authorization: Bearer <jwt>

# Query params:
# ?vault_address={addr}&chain_id={id}
# &limit=100&offset=0
# &action_type={type}
# &from_timestamp={iso}&to_timestamp={iso}
```

```json theme={null}
{
  "logs": [
    {
      "id": "uuid",
      "timestamp": "2026-05-09T10:00:00Z",
      "action_type": "yield_source_add",
      "vault_address": "0x...",
      "chain_id": 8453,
      "actor_wallet": "0xManager...",
      "details": {
        "yield_source": "0xMorphoVault...",
        "oracle": "0xOracle..."
      }
    }
  ],
  "total": 48,
  "has_more": false
}
```

Export when you need a point-in-time compliance artifact:

```bash theme={null}
GET /api/v1/audit/export
Authorization: Bearer <jwt>
```

## Polling Pattern

```python theme={null}
import requests
import time
from datetime import datetime, timezone

EREBOR_URL = "https://erebor.superform.xyz"
headers = {"Authorization": "Bearer <jwt>"}
CHAIN_ID = 8453
VAULT = "0xYourVault..."

def poll_audit_logs(since: datetime):
    resp = requests.get(
        f"{EREBOR_URL}/api/v1/audit/logs",
        headers=headers,
        params={
            "vault_address": VAULT,
            "chain_id": CHAIN_ID,
            "from_timestamp": since.isoformat(),
            "limit": 100,
        },
        timeout=15,
    )
    resp.raise_for_status()
    return resp.json().get("logs", [])

last_check = datetime.now(timezone.utc)

while True:
    new_events = poll_audit_logs(since=last_check)
    for event in new_events:
        print(f"New event: {event['action_type']} by {event['actor_wallet']}")
        # Process event...

    if new_events:
        last_check = datetime.now(timezone.utc)

    time.sleep(60)
```

## State Polling Map

| Need                | Source                                              |
| ------------------- | --------------------------------------------------- |
| Vault state changes | `GET /api/v1/vaults/{chain_id}/{address}`           |
| Service degradation | `GET /api/v1/vaults/{chain_id}/{vault}/services`    |
| Operation events    | `GET /api/v1/audit/logs`                            |
| PPS staleness       | Vault detail PPS timestamps and remaining staleness |
| Intent execution    | `GET /api/v1/intents` and OMS event/fill endpoints  |
| Emergency locks     | `GET /api/v1/engine/shards/{vault_id}/state`        |

See [Monitoring Vault State](/curate/automation/monitoring) for production-ready polling examples.
