CERTEN docs
← All docs

Webhooks

The CERTEN Gateway sends webhook notifications to your configured URL when key events occur. Webhooks enable real-time integration without polling.

Configuration

Set a webhook URL for your organization when creating it, or update it later via the admin API. Each organization also has a webhook_secret used to verify payload authenticity.

Event Types

Event Description
identity.created An identity has been fully provisioned
transaction.completed A transaction has been confirmed on-chain
transaction.failed A transaction has failed
governance.completed A governance operation has been submitted
inbox.action_signed A pending action has been signed
proof.ready A proof bundle is ready for download

Payload Format

All webhook payloads follow this structure:

{
  "event": "transaction.completed",
  "timestamp": "2025-01-01T00:00:00.000Z",
  "data": {
    "intent_id": "uuid",
    "tx_hash": "abcdef...",
    "status": "completed"
  }
}

The data object varies by event type and contains the relevant resource details.

HMAC-SHA256 Verification

Every webhook request includes an X-Certen-Signature header containing an HMAC-SHA256 hex digest of the JSON payload, computed using your organization's webhook_secret.

Verifying in Node.js

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(expected, 'hex'),
  );
}

Verifying in Python

import hmac, hashlib, json

def verify_webhook(payload: dict, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        json.dumps(payload).encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

Headers Included

Header Description
Content-Type application/json
X-Certen-Signature HMAC-SHA256 hex digest
X-Certen-Event Event type (e.g., transaction.completed)

Retry Policy

If your endpoint does not respond with a 2xx status code within 10 seconds, the delivery is retried with exponential backoff:

Attempt Delay
1 Immediate
2 4 seconds
3 8 seconds
4 16 seconds
5 32 seconds
6 64 seconds
7 128 seconds
8 256 seconds

After 8 failed attempts, the delivery is marked as permanently failed. No further retries will be attempted for that event.

Best Practices