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

# Webhooks

> Real-time event notifications with ZKScore webhooks

## Overview

Webhooks allow you to receive real-time notifications when events occur in the ZKScore system.

## Supported Events

### Score Events

* `score.updated`: User score changed
* `score.calculated`: New score calculated
* `score.breakdown.updated`: Score breakdown changed

### Achievement Events

* `achievement.claimed`: User claimed an achievement
* `achievement.progress.updated`: Achievement progress changed
* `achievement.created`: New achievement created

### Identity Events

* `identity.minted`: New identity minted
* `identity.activated`: Identity activated
* `identity.updated`: Identity information updated

### Attestation Events

* `attestation.created`: New attestation created
* `attestation.revoked`: Attestation revoked
* `attestation.verified`: Attestation verified

## Webhook Payload

All webhook payloads follow this structure:

```json theme={null}
{
  "id": "evt_123456789",
  "type": "score.updated",
  "created": "2024-01-15T10:30:00Z",
  "data": {
    "user": "alice.zks",
    "old_score": 750,
    "new_score": 800,
    "category": "defi"
  }
}
```

## Setting Up Webhooks

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Create webhook endpoint
  app.post('/webhooks/zkscore', (req, res) => {
    const { type, data } = req.body;
    
    switch (type) {
      case 'score.updated':
        handleScoreUpdate(data);
        break;
      case 'achievement.claimed':
        handleAchievementClaim(data);
        break;
    }
    
    res.status(200).send('OK');
  });

  function handleScoreUpdate(data) {
    console.log(`Score updated for ${data.user}: ${data.old_score} → ${data.new_score}`);
    // Update your application state
  }
  ```

  ```python Python theme={null}
  from flask import Flask, request, jsonify

  app = Flask(__name__)

  @app.route('/webhooks/zkscore', methods=['POST'])
  def handle_webhook():
      data = request.get_json()
      event_type = data.get('type')
      event_data = data.get('data')
      
      if event_type == 'score.updated':
          handle_score_update(event_data)
      elif event_type == 'achievement.claimed':
          handle_achievement_claim(event_data)
      
      return jsonify({'status': 'success'}), 200

  def handle_score_update(data):
      print(f"Score updated for {data['user']}: {data['old_score']} → {data['new_score']}")
      # Update your application state
  ```
</CodeGroup>

## Webhook Security

### Signature Verification

<CodeGroup>
  ```javascript JavaScript theme={null}
  const crypto = require('crypto');

  function verifyWebhookSignature(payload, signature, secret) {
    const expectedSignature = crypto
      .createHmac('sha256', secret)
      .update(payload)
      .digest('hex');
    
    return signature === `sha256=${expectedSignature}`;
  }

  // In your webhook handler
  app.post('/webhooks/zkscore', (req, res) => {
    const signature = req.headers['x-zkscore-signature'];
    const payload = JSON.stringify(req.body);
    
    if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
      return res.status(401).send('Invalid signature');
    }
    
    // Process webhook
  });
  ```
</CodeGroup>

## Best Practices

1. **Verify Signatures**: Always verify webhook authenticity
2. **Handle Duplicates**: Implement idempotency
3. **Process Asynchronously**: Use queues for heavy processing
4. **Log Events**: Keep audit trails
5. **Test Thoroughly**: Use webhook testing tools

## Related Documentation

* [Webhooks Guide](/guides/webhooks)
* [Advanced Webhooks](/advanced/webhooks-advanced)
