Webhook Event Configuration
Set up webhook endpoints to receive real-time notifications for staking events. Configure your webhook URL and specify which events to receive.
{
"webhook_url": "https://yourapi.com/webhooks/staking",
"events": [
"stake.submitted",
"stake.canceled",
"stake.broadcasted",
"stake.confirmed",
"stake.staked",
"stake.failed",
"staking_reward.received",
"unstake.submitted",
"unstake.canceled",
"unstake.broadcasted",
"unstake.confirmed",
"unstake.unstaked",
"unstake.failed"
]
}Webhook Event Reference
stake.submitted
stake.submittedSent immediately after stake request is accepted and queued for processing.
{
"event_type": "stake.submitted",
"timestamp": "2026-05-21T16:00:00.123Z",
"occurred_at": "2026-05-21T16:00:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"stake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06754e",
"asset": "ETH",
"amount": "10.5",
"status": "submitted",
"activation_period_days": 30,
"estimated_active_at": "2026-06-20T16:00:00.123Z"
}stake.queued
stake.queuedSent when the stake enters the batch queue awaiting the next submission window.
{
"event_type": "stake.queued",
"timestamp": "2026-05-21T16:01:00.123Z",
"occurred_at": "2026-05-21T16:01:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"stake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06754e",
"asset": "ETH",
"status": "queued"
}stake.canceled
stake.canceledSent immediately after stake request is canceled.
{
"event_type": "stake.canceled",
"timestamp": "2026-05-21T16:02:00.123Z",
"occurred_at": "2026-05-21T16:02:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"stake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06754e",
"asset": "ETH",
"amount": "10.5",
"status": "canceled",
"reason": "user_initiated"
}stake.broadcasted
stake.broadcastedSent when the stake transaction is signed and broadcast to the network.
{
"event_type": "stake.broadcasted",
"timestamp": "2026-05-21T16:05:00.123Z",
"occurred_at": "2026-05-21T16:05:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"stake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06754e",
"asset": "ETH",
"status": "broadcasted"
}stake.confirmed
stake.confirmedSent when the stake enters the consensus activation queue and pool allocation begins. On-chain broadcast confirmation is stake.broadcasted.
{
"event_type": "stake.confirmed",
"timestamp": "2026-05-21T16:15:00.123Z",
"occurred_at": "2026-05-21T16:15:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"stake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06754e",
"asset": "ETH",
"amount": "10.5",
"status": "confirmed",
"tx_hash": "0xabc...",
"activation_period_days": 30,
"estimated_active_at": "2026-06-20T16:00:00.123Z"
}stake.staked
stake.stakedSent when the stake completes activation and begins earning rewards.
{
"event_type": "stake.staked",
"timestamp": "2026-05-28T12:00:00.123Z",
"occurred_at": "2026-05-28T12:00:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"stake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06754e",
"asset": "ETH",
"amount": "10.5",
"status": "staked",
"tx_hash": "0xabc..."
}stake.failed
stake.failedSent when the stake request fails. Includes a reason field for diagnostics.
{
"event_type": "stake.failed",
"timestamp": "2026-05-21T16:10:00.123Z",
"occurred_at": "2026-05-21T16:10:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"stake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06754e",
"asset": "ETH",
"amount": "10.5",
"status": "failed",
"reason": "pool_capacity_exceeded"
}staking_reward.received
staking_reward.receivedSent when staking rewards are distributed and credited to the participant's account.
{
"event_type": "staking_reward.received",
"timestamp": "2026-05-22T12:00:00.123Z",
"credited_at": "2026-05-22T12:00:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"distribution_id": "dist_abc123",
"asset": "ETH",
"status": "credited",
"reward_amount": "0.025",
"cumulative_rewards_amount": "0.125"
}unstake.submitted
unstake.submitted{
"event_type": "unstake.submitted",
"timestamp": "2026-05-30T10:00:00.123Z",
"occurred_at": "2026-05-30T10:00:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"unstake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06757d",
"asset": "ETH",
"amount": "10.5",
"status": "submitted",
"cooldown_period_days": 7,
"estimated_available_at": "2026-06-06T10:00:00.123Z"
}unstake.queued
unstake.queuedSent when the unstake enters the batch queue awaiting the next submission window.
{
"event_type": "unstake.queued",
"timestamp": "2026-05-30T10:02:00.123Z",
"occurred_at": "2026-05-30T10:02:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"unstake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06757d",
"asset": "ETH",
"status": "queued"
}unstake.canceled
unstake.canceled{
"event_type": "unstake.canceled",
"timestamp": "2026-05-30T10:01:00.123Z",
"occurred_at": "2026-05-30T10:01:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"unstake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06757d",
"asset": "ETH",
"amount": "10.5",
"status": "canceled",
"reason": "user_initiated"
}unstake.broadcasted
unstake.broadcasted{
"event_type": "unstake.broadcasted",
"timestamp": "2026-05-30T10:05:00.123Z",
"occurred_at": "2026-05-30T10:05:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"unstake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06757d",
"asset": "ETH",
"status": "broadcasted"
}unstake.confirmed
unstake.confirmedSent when the unstake enters the exit queue (cooling-down).
{
"event_type": "unstake.confirmed",
"timestamp": "2026-05-30T10:15:00.123Z",
"occurred_at": "2026-05-30T10:15:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"unstake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06757d",
"asset": "ETH",
"amount": "10.5",
"status": "confirmed",
"tx_hash": "0xdef...",
"cooldown_period_days": 7,
"estimated_available_at": "2026-06-06T10:00:00.123Z"
}unstake.unstaked
unstake.unstakedSent when unstake period completes and funds are returned to the available account.
{
"event_type": "unstake.unstaked",
"timestamp": "2026-06-03T08:00:00.123Z",
"occurred_at": "2026-06-03T08:00:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"unstake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06757d",
"asset": "ETH",
"amount": "10.5",
"status": "unstaked"
}unstake.failed
unstake.failedSent when the unstake request fails. Includes a reason field for diagnostics.
{
"event_type": "unstake.failed",
"timestamp": "2026-05-30T10:10:00.123Z",
"occurred_at": "2026-05-30T10:10:00.123Z",
"participant_code": "CUST01",
"account_label": "general",
"unstake_id": "c761fc96-5c44-40d4-8eb2-3fcd5d06757d",
"asset": "ETH",
"amount": "10.5",
"status": "failed",
"reason": "exit_queue_full"
}Implementation Best Practices
- Acknowledge immediately: Always return
200 OKto acknowledge webhook receipt - Process asynchronously: Handle webhook processing outside the request/response cycle to avoid timeouts
- Store payloads: Maintain webhook event logs for debugging and audit trails
- Handle duplicates: Implement idempotency. For reward events, use
distribution_id. For stake and unstake events, usestake_id/unstake_idcombined withstatus. - Fallback strategy: Implement polling as a backup if webhook delivery fails
- Verify authenticity: Validate webhook signatures to ensure requests come from zerohash
- Monitor failures: Track webhook delivery failures and alert on persistent issues