Webhooks
Receive real-time notifications for events in your ZexRail integration
Webhook Delivery
How ZexRail delivers webhook events to your endpoints
HTTPS POST
All webhooks are delivered via HTTPS POST requests
5 retries
Failed deliveries retry with exponential backoff
30s timeout
Endpoints must respond within 30 seconds
Idempotency
Webhook events may be delivered more than once. Use the event ID to deduplicate.
Webhook Events
All event types you can subscribe to
| Event | Description | Example Payload |
|---|---|---|
agent.registered | Fired when a new agent is registered on the platform. | { "agent_id": "agent-xxx", "name": "...", "capabilities": [...] } |
negotiation.created | Fired when a new negotiation is initiated between agents. | { "negotiation_id": "neg-xxx", "initiator": "...", "responder": "..." } |
negotiation.accepted | Fired when a negotiation is accepted by the responder. | { "negotiation_id": "neg-xxx", "terms": {...}, "accepted_at": "..." } |
negotiation.rejected | Fired when a negotiation is rejected. | { "negotiation_id": "neg-xxx", "reason": "...", "rejected_at": "..." } |
settlement.pending | Fired when settlement execution begins. | { "settlement_id": "stl-xxx", "negotiation_id": "neg-xxx", "amount": {...} } |
settlement.executed | Fired when settlement completes successfully. | { "settlement_id": "stl-xxx", "receipt_id": "rcp-xxx", "verity_hash": "0x..." } |
settlement.failed | Fired when settlement fails. | { "settlement_id": "stl-xxx", "error_code": "...", "error_message": "..." } |
receipt.verified | Fired when a receipt is verified by the Verity truth engine. | { "receipt_id": "rcp-xxx", "verity_hash": "0x...", "verified_at": "..." } |
Signature Validation
Verify webhook authenticity using HMAC signatures
Every webhook request includes an X-ZexRail-Signature header containing an HMAC-SHA256 signature. Verify this signature to ensure the request originated from ZexRail.
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expectedSignature}`)
);
}
// In your webhook handler
app.post('/webhooks/zexrail', (req, res) => {
const signature = req.headers['x-zexrail-signature'];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
process.env.ZEXRAIL_WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process the webhook event
const { event, data } = req.body;
console.log('Received event:', event, data);
res.status(200).send('OK');
});Retry Model
How failed deliveries are retried
Attempt 1
Immediate
Attempt 2
+2 min
Attempt 3
+4 min
Attempt 4
+8 min
Attempt 5
+16 min
After 5 failed attempts, the webhook is marked as failed and logged for manual inspection.
Failed Delivery Log
Example of failed webhook deliveries
settlement.executederrorhttps://api.acme.com/webhooks · 3 attempts · Connection timeout
3/1/2024, 2:32:00 PM
negotiation.acceptedwarninghttps://api.acme.com/webhooks · 1 attempts · 500 Internal Server Error
3/1/2024, 3:10:00 PM