Router Node

The Router node inspects event payloads and directs them to different webhooks based on configurable rules. Build conditional branching logic without code — route payment events to one service and subscription events to another, all from a single pipeline.

Overview

A Router evaluates an ordered list of rules against the incoming event payload. Each rule specifies a field path, an operator, a comparison value, and a target webhook. The first matching rule wins: the event is forwarded to that rule's outputWebhookId. If no rule matches, the event goes to the defaultWebhookId (if configured) or is dropped.

On the canvas, Router nodes appear as blue rectangles. They fire during the onEventCreated phase, before primary delivery.


Configuration

FieldTypeDefaultDescription
namestringFriendly label for the router
routesRoute[][]Ordered list of routing rules (see below)
defaultWebhookIdstringnullFallback webhook when no route matches
inputNodes{ nodeType, nodeId }[][]Upstream nodes that feed this one. nodeType is the node kind (webhook, scheduledWorkflow, filter, …)
isActivebooleantrueWhether the router is enabled

Route object

FieldTypeDescription
fieldstringDot-notation path into the payload (e.g. data.type)
operatorstringComparison operator (see operators table)
valuestringValue to compare against
outputWebhookIdstringWebhook ID to route matching events to

Supported operators

OperatorDescriptionExample value
eqExact match (string comparison)payment_intent.succeeded
neqDoes not equaldraft
containsString contains substringerror
gtGreater than (numeric)1000
ltLess than (numeric)50
existsField is present and not null(no value needed)
not_existsField is absent or null(no value needed)
inValue is in comma-separated listactive,pending,processing
not_inValue is not in comma-separated listcancelled,refunded

Create a Router

bashCreate Router
curl -X POST /api/routers \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Payment Event Router",
    "routes": [
      {
        "field": "type",
        "operator": "equals",
        "value": "payment_intent.succeeded",
        "outputWebhookId": "ep_payments_success"
      },
      {
        "field": "type",
        "operator": "equals",
        "value": "payment_intent.payment_failed",
        "outputWebhookId": "ep_payments_failed"
      },
      {
        "field": "type",
        "operator": "contains",
        "value": "subscription",
        "outputWebhookId": "ep_subscriptions"
      }
    ],
    "defaultWebhookId": "ep_catch_all",
    "inputNodes": [{ "nodeType": "webhook", "nodeId": "6654a1b2c3d4e5f6a7b8c9d0" }],
    "isActive": true
  }'

Response

json201 Created
{
  "_id": "6654d4e5f6a7b8c9d0e1f2a3",
  "name": "Payment Event Router",
  "routes": [
    {
      "field": "type",
      "operator": "equals",
      "value": "payment_intent.succeeded",
      "outputWebhookId": "ep_payments_success"
    },
    {
      "field": "type",
      "operator": "equals",
      "value": "payment_intent.payment_failed",
      "outputWebhookId": "ep_payments_failed"
    },
    {
      "field": "type",
      "operator": "contains",
      "value": "subscription",
      "outputWebhookId": "ep_subscriptions"
    }
  ],
  "defaultWebhookId": "ep_catch_all",
  "inputNodes": [{ "nodeType": "webhook", "nodeId": "6654a1b2c3d4e5f6a7b8c9d0" }],
  "isActive": true,
  "ownerId": "org_abc123",
  "createdAt": "2025-05-01T12:00:00.000Z",
  "updatedAt": "2025-05-01T12:00:00.000Z"
}

Update a Router

bashUpdate Router
curl -X PATCH /api/routers/6654d4e5f6a7b8c9d0e1f2a3 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "routes": [
      {
        "field": "type",
        "operator": "equals",
        "value": "payment_intent.succeeded",
        "outputWebhookId": "ep_payments_success"
      },
      {
        "field": "data.object.amount",
        "operator": "gt",
        "value": "10000",
        "outputWebhookId": "ep_high_value"
      }
    ]
  }'
Updating routes replaces the entire array. Always include all routes you want to keep — omitted routes are removed.

Canvas Integration

The Router uses canvas type router and renders in blue. Each route creates an outgoing edge to its target webhook. The default route (if set) creates an additional edge styled with a dashed line.

jsonCanvas node data
{
  "id": "router-6654d4e5f6a7b8c9d0e1f2a3",
  "type": "router",
  "position": { "x": 400, "y": 200 },
  "data": {
    "label": "Payment Event Router",
    "routerId": "6654d4e5f6a7b8c9d0e1f2a3",
    "routeCount": 3,
    "hasDefault": true,
    "isActive": true
  }
}

Payload Examples

Incoming event — matches first route

jsonPayload
{
  "type": "payment_intent.succeeded",
  "data": {
    "object": {
      "id": "pi_abc123",
      "amount": 5000,
      "currency": "usd"
    }
  }
}

Result: Event is routed to ep_payments_success because the type field equals payment_intent.succeeded.

Incoming event — no match, uses default

jsonPayload
{
  "type": "invoice.finalized",
  "data": {
    "object": {
      "id": "inv_xyz789",
      "total": 3000
    }
  }
}

Result: No route matches. Event is routed to ep_catch_all (the default webhook).


Use Cases

  • Event type routing — Route Stripe events by type to dedicated processing services.
  • Priority routing — Send high-value transactions (amount > $100) to a priority queue and low-value ones to standard processing.
  • Regional routing — Route events by data.region to region-specific webhooks.
  • A/B testing — Use regex or in operators to split traffic across different processing versions.
  • Error isolation — Route error events to a dedicated error-handling service while normal events go to the main pipeline.

API Reference

MethodWebhookDescription
GET/api/routersList all routers
POST/api/routersCreate a new router
GET/api/routers/:idGet a specific router
PATCH/api/routers/:idUpdate a router
DELETE/api/routers/:idDelete a router
Routes are evaluated in order — place more specific rules first. For example, check for payment_intent.succeeded before a broader contains: payment rule.