Webhooks (Callbacks)

Webhooks allow you to be notified in real-time as soon as a block is added to your chain. Here is the complete lifecycle of a webhook.

Webhooks (Callbacks)

Webhooks allow you to be notified in real-time as soon as a block is added to your chain. Here is the complete lifecycle of a webhook.

1. Creation & Configuration

Create the webhook via the API or the Dashboard. You will then receive:

  • A **Secret**: used to sign notifications.
  • A **Challenge**: a random word (e.g., 'tomato') for validation.
POST /v1/chains/{chainId}/callbacks
{
  "url": "https://votre-api.com/webhook",
  "name": "Serveur Production"
}

2. Validation Handshake

To activate the webhook, you must prove that you control the URL. Click 'Verify' in the dashboard to start the handshake:

SoWasIt sends a **GET** request to `{your_url}?check=true`.
GET https://votre-api.com/webhook?check=true
Your server must respond **200 OK** with the JSON: `{ "challenge": "tomato" }`.
{
  "challenge": "tomato"
}

3. Receiving Notifications

Once active, SoWasIt sends a **POST** request for every new block.

{
  "event": "block.added",
  "idempotency_key": "uuid-v4",
  "block": {
    "hash": "e3b0c442...",
    "data": { ... }
  }
}

Security & Signature

Each POST notification includes security headers to ensure the call comes from SoWasIt:

  • **X-Callback-Signature**: HMAC-SHA256 signature of the request body, calculated with your secret.
  • **X-Callback-Secret**: Reminder of your secret (to facilitate development, should be ignored in production in favor of the signature).

To verify integrity, recalculate the HMAC-SHA256 of the raw body with your secret and compare it to the signature header.

// Exemple Node.js / Express
const crypto = require('crypto');

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-callback-signature'];
  const secret = process.env.SOWASIT_WEBHOOK_SECRET;
  
  // Recalcul du HMAC avec le body brut (raw body)
  const hmac = crypto.createHmac('sha256', secret);
  const digest = hmac.update(JSON.stringify(req.body)).digest('hex');
  
  if (signature !== digest) {
    return res.status(401).send('Invalid signature');
  }
  
  // Traitement...
  res.status(200).send('OK');
});
Idempotency : Each notification includes an `idempotency_key`. If you receive the same key twice (in case of retry), ignore the second call.

Debugging and Logs

If you are not receiving your webhooks, enable **Debug Mode** in your dashboard (Logs menu). You will be able to see the details of each call attempt, the HTTP codes returned by your server, and any signature or network errors.