Skip to main content

Why Use Webhooks?

ApproachLatencyComplexityUse Case
PollingSeconds to minutesSimpleLow-volume, non-critical
WebhooksSub-secondModerateReal-time updates, high-volume

Configure Webhooks

Configure in Hub: WebhooksAdd Webhook Endpoint URL: e.g., https://api.yourgame.com/webhooks/immutable Events: Mints, transfers, orders, trades

Webhook Payload

{
  "event_name": "imtbl_zkevm_mint_request_updated",
  "event_id": "evt_123abc",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "contract_address": "0x...",
    "token_id": "123",
    "status": "succeeded"
  }
}

Verify Webhook Signatures

import crypto from 'crypto';

function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// In your webhook handler
app.post('/webhooks/immutable', (req, res) => {
  const signature = req.headers['x-immutable-signature'];
  const isValid = verifyWebhookSignature(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET
  );
  
  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the webhook
  handleWebhookEvent(req.body);
  res.status(200).send('OK');
});

Retry Policy

Exponential backoff on errors:
AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours
After 5 failed attempts, view and retry in Hub.

Best Practices

Return a 200 response immediately, then process the event asynchronously. Webhook requests timeout after 30 seconds.
Use the event_id to deduplicate events. The same event may be delivered more than once.
Always verify the webhook signature. Use HTTPS for your endpoint.

Next Steps