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
EventDescriptionExample Payload
agent.registeredFired when a new agent is registered on the platform.{ "agent_id": "agent-xxx", "name": "...", "capabilities": [...] }
negotiation.createdFired when a new negotiation is initiated between agents.{ "negotiation_id": "neg-xxx", "initiator": "...", "responder": "..." }
negotiation.acceptedFired when a negotiation is accepted by the responder.{ "negotiation_id": "neg-xxx", "terms": {...}, "accepted_at": "..." }
negotiation.rejectedFired when a negotiation is rejected.{ "negotiation_id": "neg-xxx", "reason": "...", "rejected_at": "..." }
settlement.pendingFired when settlement execution begins.{ "settlement_id": "stl-xxx", "negotiation_id": "neg-xxx", "amount": {...} }
settlement.executedFired when settlement completes successfully.{ "settlement_id": "stl-xxx", "receipt_id": "rcp-xxx", "verity_hash": "0x..." }
settlement.failedFired when settlement fails.{ "settlement_id": "stl-xxx", "error_code": "...", "error_message": "..." }
receipt.verifiedFired 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.executederror

https://api.acme.com/webhooks · 3 attempts · Connection timeout

3/1/2024, 2:32:00 PM
negotiation.acceptedwarning

https://api.acme.com/webhooks · 1 attempts · 500 Internal Server Error

3/1/2024, 3:10:00 PM