Set Up Webhooks

Learn how to create, test, and manage webhook endpoints in the RiskOS™ Dashboard.

Quick start

  1. Prepare your endpoint

    Create an HTTPS endpoint capable of receiving POST requests from RiskOS™. Ensure the endpoint accepts application/json payloads, validates authentication, and returns a 2xx response code after successful receipt.

  2. Access the Developer Workbench

    Go to Developer Workbench > Webhooks in the RiskOS™ Dashboard. From this page, you can view, edit, or create webhook configurations for your account.


  3. Create a new webhook

    Click + New Webhook and enter the following details:

    • Name: A descriptive name to help identify this webhook later.
    • URL: The HTTPS destination endpoint that receives webhook events.
    • Use Case: Scope webhook delivery to a specific RiskOS™ use case (for example, Consumer Onboarding or Account Takeover).
    • Event Type: Select one or more event types to subscribe to. Each event follows a predefined schema.
    • Auth Type: Choose from the supported authentication methods:
      • Basic Authentication — Username and password-based authentication.
      • Bearer Token — Uses a UUID token for authentication.
      • OAuth2 — Requires a client ID, client secret, and token URL.

  4. Test your webhook

    Click Continue to Test to send a sample payload to your endpoint. The RiskOS™ Dashboard displays success or failure results, confirming whether your webhook is reachable and properly configured.

  5. Activate your webhook

    Once the test is successful, click Save to activate your webhook for real-time event delivery. RiskOS™ now begins sending event notifications whenever subscribed events occur.


Webhook testing tools

To verify that events are being successfully triggered and sent by RiskOS™, you can use Webhook Cool (or a similar tool), which provides a unique URL to receive events.

⚠️

Security note:

When using external testing tools like Webhook Cool, be mindful that your webhook payload contains your authorization and sensitive customer information (depending on your workflow configuration). RiskOS™ doesn't endorse this third-party tool and isn't responsible for the security or handling of data received by Webhook Cool or any other external service. Use such tools only for non-production testing and with awareness of the data you expose.


Manage webhooks

Users with the appropriate permissions can configure and manage their webhooks on the Developer Workbench > Webhooks section of the RiskOS™ Dashboard.

The Webhooks section displays all configured webhooks with key details:

  • Webhook URL: Destination endpoint that receives event payloads.
  • Created / Last Modified: When the webhook was created or last updated.
  • Subscribed Events: Event types that trigger the webhook.

Delete a webhook

Click the trash icon for the webhook, then confirm Delete.


Sample receivers

Use the code samples in this section as a starting point. They acknowledge and de-duplicate via event_id.

import express from "express";
import crypto from "crypto";

const app = express();
app.use(express.json({ type: "application/json" }));

// Replace with a real, persistent store:
const seen = new Set();

app.post("/webhooks/riskos", async (req, res) => {
  const { event_id, event_type, data } = req.body || {};
  if (!event_id || !event_type) return res.status(400).send("Bad Request");

  // Idempotency: drop duplicates
  if (seen.has(event_id)) return res.status(200).send("OK");
  seen.add(event_id);

  // Queue async work (do not block the response)
  queueMicrotask(() => handleEvent(event_type, data).catch(console.error));

  return res.status(200).send("OK");
});

async function handleEvent(type, data) {
  switch (type) {
    case "evaluation_completed":
      // process...
      break;
    default:
      // no-op
  }
}

app.listen(3000, () => console.log("Listening on :3000"));
from flask import Flask, request, jsonify

app = Flask(__name__)
seen = set()  # replace with durable store

@app.post("/webhooks/riskos")
def riskos():
    payload = request.get_json(silent=True) or {}
    event_id = payload.get("event_id")
    event_type = payload.get("event_type")
    data = payload.get("data")

    if not event_id or not event_type:
        return ("Bad Request", 400)

    if event_id in seen:
        return ("OK", 200)
    seen.add(event_id)

    # Do processing async/off-thread in production
    handle_event(event_type, data)
    return ("OK", 200)

def handle_event(event_type, data):
    if event_type == "evaluation_paused":
        pass  # handle
    # etc.

if __name__ == "__main__":
    app.run(port=3000)