Webhook event catalog
Per-event payload shapes for the six Northstake webhook event types, plus the subscription API and delivery semantics.
For event semantics and subscription setup, see Subscribe to webhooks.
Common envelope
Every event delivered to a webhook URL has the following top-level shape:
{
"id": "<event_type>_<azure_id>_<event-scoped suffix>",
"azure_id": "<account ID>",
"staking_vault_id": "<vault ID>",
"event_type": "<one of the six event types>",
"severity": "info" | "warning" | "error",
"title": "<short human title>",
"message": "<one-line human message>",
"payload": { /* event-specific fields, documented per event below */ },
"created_at": <unix epoch milliseconds>
}| Field | Type | Notes |
|---|---|---|
id | string | Stable per logical event; use this as your dedupe key |
azure_id | string | The Northstake account that owns the vault |
staking_vault_id | string | The vault the event pertains to |
event_type | string | One of the six values below |
severity | string | Currently always info for all six event types |
title | string | Human-readable label, suitable for notification headers |
message | string | One-line human description |
payload | object | Event-specific; documented per type |
created_at | number | Unix epoch in milliseconds |
Event catalogue
funding_received
funding_receivedFires when the vault's Staking Vault contract emits an EtherFunded event (any ETH lands in the vault).
| Field | Notes |
|---|---|
| Source | Staking Vault contract event (on-chain) |
| Frequency | Per funding transaction |
| Vault types | All |
id format | funding_received_<azure_id>_<TX_HASH_UPPERCASE> |
Payload:
{
"tx_hash": "0x…",
"amount_wei": "1000000000000000000",
"staking_vault_address": "0x…"
}validator_activated
validator_activatedFires when a validator transitions to active on the beacon chain (Ethereum-level activation, not Lido PDG promotion).
| Field | Notes |
|---|---|
| Source | Beacon-chain monitor; keyed by activation_epoch |
| Frequency | Once per validator |
| Vault types | All |
id format | validator_activated_<azure_id>_<validator_index> |
Payload:
{
"validator_index": 1234567,
"validator_pubkey": "0x…",
"epoch": 245678
}validator_exited
validator_exitedFires when a validator exits the beacon chain.
| Field | Notes |
|---|---|
| Source | Beacon-chain monitor; keyed by exit_epoch |
| Frequency | Once per validator |
| Vault types | All |
id format | validator_exited_<azure_id>_<validator_index> |
Payload:
{
"validator_index": 1234567,
"validator_pubkey": "0x…",
"epoch": 256789
}validator_withdrawal_completed
validator_withdrawal_completedFires when a validator's beacon-chain withdrawal sweep completes. Funds have moved from the validator into the vault's withdrawal queue.
| Field | Notes |
|---|---|
| Source | Beacon-chain withdrawals data |
| Frequency | Once per withdrawal (a validator may have multiple sweeps) |
| Vault types | All |
id format | validator_withdrawal_completed_<azure_id>_<validator_index>_<epoch> |
Payload:
{
"validator_index": 1234567,
"validator_pubkey": "0x…",
"epoch": 256800,
"amount_eth": "32.045"
}withdrawal_claimed
withdrawal_claimedFires when a queued withdrawal is claimed by the recipient (Withdrawal Queue WithdrawalClaimed event).
| Field | Notes |
|---|---|
| Source | Withdrawal Queue contract event (on-chain) |
| Frequency | Per claim |
| Vault types | All (where withdrawal queue exists, i.e. all Lido v3 vaults) |
id format | withdrawal_claimed_<azure_id>_<withdrawal_queue_address>_<request_id> |
Payload:
{
"tx_hash": "0x…",
"request_id": "42",
"recipient": "0x…",
"owner": "0x…",
"amount_eth": "32.0",
"withdrawal_queue_address": "0x…"
}report_update_available
report_update_availableFires when the Lido vault hub (LazyOracle) publishes a new report timestamp for one of your vaults. Reports update obligations.feesToSettle and validate reserve ratios: see Fee model.
| Field | Notes |
|---|---|
| Source | Lido LazyOracle (on-chain) |
| Frequency | Per report (typically once per vault per reporting window) |
| Vault types | All |
id format | report_update_available_<azure_id>_<vault_id>_<report_timestamp> |
Payload:
{
"calldata": "0x…",
"report_timestamp": "1716115200"
}The calldata is the constructed lazy-oracle calldata for this vault's update, ready to be submitted on-chain.
Subscription API
Webhook configuration uses standard CRUD endpoints under /v1/account/webhooks. See Subscribe to webhooks for end-to-end usage.
GET /v1/account/webhooks # list
POST /v1/account/webhooks # create (step-up MFA required)
PATCH /v1/account/webhooks/{id} # update (step-up MFA required)
DELETE /v1/account/webhooks/{id} # delete (step-up MFA required)WebhookEntry
WebhookEntry| Field | Type | Notes |
|---|---|---|
id | string | Server-assigned |
url | string | HTTPS-only |
eventTypes | string[] | null | One or more of the six event types; null = all |
stakingVaultIds | string[] | null | One or more vault IDs; null = all your vaults |
active | boolean | Whether deliveries are currently active |
createdAt | string | ISO 8601 timestamp |
secretToken | string | Returned only on POST create; persist for signature verification |
Delivery semantics
- At-least-once delivery: your handler must be idempotent (dedupe by
id) - Retries with backoff: failed deliveries are retried automatically
- Auto-disable: webhooks that fail consistently for an extended period may flip to
active: false - Ordering not guaranteed: events may arrive out of chronological order; use
created_atfor sequencing in your handler
Related
- Subscribe to webhooks: event semantics and subscription setup
Updated about 1 month ago
