Subscribe to webhooks

Webhooks let Northstake push vault events to users' HTTPS endpoint rather than you polling for state. This guide covers the event types, the subscription lifecycle (registering, verifying deliveries, listing, updating filters, and deleting), and handler best practices.

For full payload shapes, see Webhook event catalog.

Event types

EventWhen it firesTypical reaction
funding_receivedThe vault receives an ETH funding depositUpdate accounting; trigger validator-creation flow if planned
validator_activatedA validator transitions to active on the beacon chainStart reward-tracking; update validator inventory
validator_exitedA validator exitsAnticipate inbound withdrawal liquidity
validator_withdrawal_completedA validator's withdrawal sweep completesWithdrawal queue has new liquidity; finalize pending requests
withdrawal_claimedA queued withdrawal is claimed by the recipientNotify depositor; reconcile in accounting
report_update_availableA new vault-hub report is availableSettle Lido protocol fees if outstanding

funding_received

Fires when ETH lands in the vault. For pool vaults this is per-depositor; for dedicated vaults it's per-fund call by the owner. Use it to trigger downstream allocation logic: e.g. spinning up a new validator once enough principal has been deposited.

validator_activated

Beacon-chain activation, not Lido-level PDG promotion. This is the point where the validator starts earning rewards. Useful for kicking off performance monitoring on the validator's public key.

validator_exited

The validator is no longer earning. Principal and accumulated rewards become available for withdrawal once the beacon chain finishes its exit sweep, which can take days. Pair with validator_withdrawal_completed to know when the funds actually land.

validator_withdrawal_completed

The beacon-chain sweep has moved this validator's balance into the vault's withdrawal queue. The queue now has additional liquidity. If you have pending withdrawal requests sized for this, you can finalize them.

withdrawal_claimed

A queued withdrawal has been claimed. The recipient now holds the ETH. Use it to close out user notifications and accounting entries for that request.

report_update_available

The Lido vault hub has published a new report for one of your vaults. Reports update obligations.feesToSettle (Lido protocol fees) and validate the vault's reserve ratio. The most common downstream action is settling outstanding Lido fees: see Fee model.

Scoping

Each subscription includes:

  • eventTypes: string[] | null: which of the six event types to receive (or all, if null)
  • stakingVaultIds: string[] | null: restrict to specific vaults (or all, if null)

Both default to null. Narrowing both dimensions reduces noise and is generally what you want at scale.

Before you start

  • Admin role on your Northstake account. Webhook mutations are admin-only.
  • MFA step-up capability. Creating, updating, and deleting webhooks each require re-authentication (the API marks these with x-mfaApiScope).
  • An HTTPS endpoint under your control that can receive POST requests. The URL must use https://: HTTP is rejected.
  • A plan for storing the signing secret before you register. The secret is returned exactly once at creation; if you lose it, you'll need to delete and re-register the webhook.
  • A handler that's idempotent. Delivery is at-least-once; the same event can land twice.

Create a subscription

🖱️

to register a webhook in the UI: from Settings → Webhooks click Add Webhook, fill in the URL, optionally restrict by Event types and Staking vault IDs (leave empty for all), confirm the MFA step-up, and on success copy the signing secret immediately: it's shown only on this screen.

</> to register a webhook via the API: see createWebhook. Body: { url, eventTypes?, stakingVaultIds? }. The response includes a one-time secretToken: persist it before the response is closed.

Verify

  • GET /account/webhooks returns the new entry with active: true.
  • A test event delivery lands at your URL within seconds (depending on traffic).
  • The X-Northstake-Signature header on the delivery is present and verifies (see next section).

Verify the delivery signature

Every webhook POST carries an X-Northstake-Signature header: a hex-encoded HMAC-SHA256 of the raw request body, signed with your secret. Verify it before trusting the payload, otherwise an attacker who learns your URL can spoof events.

The recipe:

  1. Read the raw request body as bytes (don't parse, don't re-serialize: JSON re-serialization changes the signature).
  2. Compute HMAC_SHA256(secret, raw_body).
  3. Hex-encode the result.
  4. Compare to X-Northstake-Signature using a constant-time comparison.

If the signatures don't match, reject the request with 401. If they do, parse the JSON and dispatch on event_type per the event types table above.

List your subscriptions

🖱️

to view your subscriptions in the UI: Settings → Webhooks lists every registered endpoint with its URL, filter scope, and active status.

</> to list subscriptions via the API: see listWebhooks. Returns an array of Webhook objects. The secretToken is not included: it's only ever returned at creation.

Update a subscription

Update changes the filter set on an existing webhook. The URL itself isn't updatable: if you need a new URL, delete the existing webhook and create a new one.

🖱️

to update filters in the UI: from Settings → Webhooks, click Edit on a webhook row, adjust Event types and/or Staking vault IDs, confirm the MFA step-up, and save. Leaving a filter empty clears it (receive all).

</> to update a subscription via the API: see updateWebhook. Pass the fields to change; pass null for eventTypes or stakingVaultIds to clear the filter (receive all). Requires MFA step-up.

Delete a subscription

🖱️

to delete a subscription in the UI: from Settings → Webhooks, click Delete on a webhook row, confirm in the dialog, and complete the MFA step-up.

</> to delete a subscription via the API: see deleteWebhook. Returns 204 on success. Requires MFA step-up. The signing secret is unrecoverable after deletion: don't delete unless you also intend to re-register.

Handler best practices

  • Be idempotent: dedupe on the event id field. Delivery is at-least-once; the same event can land twice, especially after retries.
  • Don't depend on ordering: events arrive as they're processed. A validator_exited may land before its preceding validator_activated if the activation delivery was delayed.
  • Return 2xx fast: acknowledge with a 200 (or 202) the moment you've persisted the event for later processing. Long-running work belongs in a queue your handler writes to, not in the request path.
  • Handle retries: failed deliveries are retried with backoff. A consistently-failing endpoint may be auto-disabled (active: false); check listWebhooks periodically to make sure none have gone dormant.
  • Log raw bodies: log the raw body for at least a few days so you can replay missed events and reproduce signature failures.

Common pitfalls

  • Losing the signing secret. It's returned once at creation. If your client doesn't persist it before the response is consumed, you'll have to delete and re-register the webhook.
  • Verifying against the parsed JSON instead of the raw body. JSON re-serialization changes whitespace and field ordering, which changes the HMAC. Always verify against the raw bytes.
  • Forgetting that active: false is silent. Northstake doesn't push notifications about disabled webhooks. If you stop seeing events, check the active field via listWebhooks.
  • Using http:// URLs. The endpoint must be https://. The create call rejects http:// URLs.
  • Skipping MFA setup before scaling. Every mutation needs MFA step-up. If you're automating webhook lifecycle in CI or scripts, plan for the step-up upfront: the API will reject otherwise.

Related