Overview
When you anchor a record with Anchora, it takes 30-60 seconds to be confirmed on the Polygon blockchain. Instead of polling for status, configure webhooks to receive instant notifications when:
- anchor.confirmed - Record successfully anchored to blockchain
- anchor.failed - Anchoring failed (rare, usually network issues)
- record.updated - Mutable fields were updated
- record.deleted - Record was soft or hard deleted
Configuring Webhooks
You can configure webhooks in two ways: globally via your dashboard, or per-request using the webhookUrl parameter.
Per-Request Webhook
curl -X POST https://api.anchora.io/v1/anchor/encrypted \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "data": { "name": "Alice Smith", "certificateId": "CERT-2024-001" }, "encryptionKey": "your-32-character-encryption-key!!", "webhookUrl": "https://your-app.com/webhooks/anchora" }'
Webhook Payload
When an event occurs, Anchora sends a POST request to your webhook URL with the following payload:
{
"event": "anchor.confirmed",
"timestamp": "2024-01-31T10:30:00Z",
"data": {
"recordId": "rec_abc123xyz789",
"hash": "0x7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa...",
"txHash": "0x3f8a9c2e1b4d7f6a...",
"blockNumber": 45678901,
"status": "CONFIRMED"
},
"signature": "sha256=abc123..."
}
Verifying Webhook Signatures
All webhook requests include a signature header to verify authenticity. Always verify signatures before processing webhooks.
const crypto = require('crypto'); function verifyWebhook(payload, signature, secret) { const expectedSignature = 'sha256=' + crypto.createHmac('sha256', secret) .update(payload) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) ); } // In your webhook handler app.post('/webhooks/anchora', (req, res) => { const signature = req.headers['x-anchora-signature']; const isValid = verifyWebhook( JSON.stringify(req.body), signature, process.env.WEBHOOK_SECRET ); if (!isValid) { return res.status(401).json({ error: 'Invalid signature' }); } // Process the webhook console.log('Received event:', req.body.event); res.status(200).json({ received: true }); });
Retry Policy
If your endpoint returns a non-2xx response, Anchora will retry the webhook with exponential backoff:
| Attempt | Delay | Total Time |
|---|---|---|
| 1st retry | 1 minute | 1 minute |
| 2nd retry | 5 minutes | 6 minutes |
| 3rd retry | 30 minutes | 36 minutes |
| 4th retry | 2 hours | ~2.5 hours |
| 5th retry (final) | 24 hours | ~26.5 hours |
Best Practices
- Respond quickly: Return a 200 response immediately, then process async
- Handle duplicates: Use the
recordIdto deduplicate events - Verify signatures: Always validate the
x-anchora-signatureheader - Use HTTPS: Webhook URLs must use HTTPS in production
- Log everything: Keep logs of received webhooks for debugging