Skip to main content
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.

Register a webhook

Register a new outbound webhook for a workflow.
POST /webhooks

Body parameters

workflow_id
string
required
ID of the workflow whose events should trigger this webhook.
url
string
required
The publicly accessible HTTPS endpoint where RCB Automation will send event payloads. Must use https://.
events
string[]
required
Array of event types to subscribe to. Available events:
  • run.completed — a workflow run finished successfully
  • run.failed — a workflow run encountered an error
  • run.started — a workflow run has begun
  • workflow.paused — the workflow was paused
  • workflow.activated — the workflow was set to active
secret
string
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.

Response fields

id
string
Unique identifier for the registered webhook.
workflow_id
string
ID of the associated workflow.
url
string
The endpoint URL deliveries are sent to.
events
string[]
Array of subscribed event types.
secret_set
boolean
true if a signing secret was provided, false otherwise. The secret itself is never returned.
created_at
string
ISO 8601 timestamp of registration.

Example

curl --request POST \
  --url https://api.rcbautomation.com/v1/webhooks \
  --header 'Authorization: Bearer rcb_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6' \
  --header 'Content-Type: application/json' \
  --data '{
    "workflow_id": "wf_9kLmNpQrStUv",
    "url": "https://your-app.example.com/webhooks/rcb",
    "events": ["run.completed", "run.failed"],
    "secret": "whsec_my_signing_secret_32chars_long"
  }'
Response (201 Created)
{
  "id": "whk_4RsTuVwXyZaB",
  "workflow_id": "wf_9kLmNpQrStUv",
  "url": "https://your-app.example.com/webhooks/rcb",
  "events": ["run.completed", "run.failed"],
  "secret_set": true,
  "created_at": "2026-04-20T12:00:00Z"
}

Get webhook details

Retrieve a registered webhook by its ID, including the status of the most recent delivery attempt.
GET /webhooks/{id}

Path parameters

id
string
required
The unique identifier of the webhook to retrieve.

Response fields

id
string
Unique identifier for the webhook.
workflow_id
string
ID of the associated workflow.
url
string
The endpoint URL deliveries are sent to.
events
string[]
Array of subscribed event types.
secret_set
boolean
true if a signing secret is configured.
created_at
string
ISO 8601 timestamp of registration.
last_delivery
object
Details of the most recent delivery attempt.

Example

curl --request GET \
  --url https://api.rcbautomation.com/v1/webhooks/whk_4RsTuVwXyZaB \
  --header 'Authorization: Bearer rcb_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
Response (200 OK)
{
  "id": "whk_4RsTuVwXyZaB",
  "workflow_id": "wf_9kLmNpQrStUv",
  "url": "https://your-app.example.com/webhooks/rcb",
  "events": ["run.completed", "run.failed"],
  "secret_set": true,
  "created_at": "2026-04-20T12:00:00Z",
  "last_delivery": {
    "status": "success",
    "http_status": 200,
    "delivered_at": "2026-04-20T14:32:07Z",
    "duration_ms": 143
  }
}

Webhook payload structure

When an event fires, RCB Automation sends a POST request to your registered URL with a JSON body structured as follows:
{
  "id": "evt_8CdEfGhIjKlM",
  "event": "run.completed",
  "created_at": "2026-04-20T14:32:05Z",
  "data": {
    "workflow_id": "wf_9kLmNpQrStUv",
    "workflow_name": "Weekly sales report",
    "run_id": "run_5NoPqRsTuVwX",
    "status": "completed",
    "started_at": "2026-04-20T14:31:55Z",
    "completed_at": "2026-04-20T14:32:05Z",
    "duration_ms": 10243
  }
}
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.

Signature verification

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.

Verification examples

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 example
app.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.