Webhooks API: register and retrieve outbound webhooks
Register and retrieve outbound webhooks via the RCB Automation REST API. Includes payload structure, signature verification examples in JavaScript and Python.
Outbound webhooks let your application receive real-time HTTP notifications when events occur in RCB Automation — such as when a workflow run completes or fails. You register a webhook by providing a URL to receive events, the event types you care about, and an optional secret for payload verification. RCB Automation signs every delivery so you can confirm the payload came from us.
Optional secret string used to sign webhook payloads. RCB Automation includes an X-RCB-Signature header on every delivery computed as sha256=HMAC-SHA256(secret, raw_body). Use this to verify that deliveries originate from RCB Automation. If omitted, no signature header is sent.
RCB Automation expects your endpoint to respond with a 2xx status code within 10 seconds. If your endpoint times out or returns a non-2xx response, the delivery is retried up to 5 times with exponential backoff over the following 24 hours.
When you register a webhook with a secret, RCB Automation includes a signature header on every delivery:
X-RCB-Signature: sha256=<hmac>
The HMAC value is computed as HMAC-SHA256(secret, raw_request_body), encoded as a lowercase hexadecimal string. Verify the signature on your server before processing the payload to confirm the delivery originated from RCB Automation.
Always verify the signature using the raw request body bytes — before any JSON parsing. Parsing the body first and re-serializing it can alter whitespace or key ordering, causing verification to fail even for legitimate deliveries.
import crypto from 'crypto';function verifyWebhookSignature(rawBody, signatureHeader, secret) { if (!signatureHeader || !signatureHeader.startsWith('sha256=')) { return false; } const receivedHmac = signatureHeader.slice('sha256='.length); const expectedHmac = crypto .createHmac('sha256', secret) .update(rawBody) // rawBody must be a Buffer or string of raw bytes .digest('hex'); // Use timingSafeEqual to prevent timing attacks const receivedBuf = Buffer.from(receivedHmac, 'hex'); const expectedBuf = Buffer.from(expectedHmac, 'hex'); if (receivedBuf.length !== expectedBuf.length) { return false; } return crypto.timingSafeEqual(receivedBuf, expectedBuf);}// Express exampleapp.post('/webhooks/rcb', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.headers['x-rcb-signature']; const secret = process.env.RCB_WEBHOOK_SECRET; if (!verifyWebhookSignature(req.body, signature, secret)) { return res.status(401).send('Invalid signature'); } const event = JSON.parse(req.body.toString()); console.log('Received event:', event.event); res.status(200).send('OK');});
Store your webhook secret in an environment variable rather than hardcoding it. Use a randomly generated string of at least 32 characters as your secret.