Portal Community

The Problem

Many external systems (payment processors, document signing, AI processing) accept a request and return a result via a callback webhook later. The workflow must:

  1. Send the outbound request with a correlation ID and callback URL
  2. Suspend and wait for the callback to arrive
  3. Resume with the callback payload

Pattern Implementation


[GenerateCorrelationId]          // sets $output.corrId.id
        │
[WebhookCallNode]                // sends to payment processor
  body: {
    amount: $output.cart.total,
    callbackUrl: $env.WEBHOOK_BASE + "/webhook/tenant/payment-callback",
    correlationId: $output.corrId.id
  }
        │
[WaitForWebhookNode]             // suspends — waits for inbound call
  correlationField: "correlationId"
  correlationValue: $output.corrId.id
  timeoutSeconds: 300
        │
[ProcessPaymentResult]           // continues with callback data
  $json.status  // "success" | "failed"
  

WaitForWebhookNode Config

{
  "nodeType": "WaitForWebhook",
  "config": {
    "webhookId": "wh-payment-callback",
    "correlationField": "correlationId",
    "correlationValue": "$output.corrId.id",
    "timeoutSeconds": 300,
    "timeoutPort": "timeout"
  }
}

The engine matches the inbound callback to the suspended execution by comparing correlationField in the callback body to the expected value. When matched, the callback body becomes $json for all nodes after the wait node.

Correlation ID Generation

// Expression to generate a unique correlation ID
crypto.randomUUID()   // → "3f7a2b1c-..."

// Or use the execution ID as correlation:
$context.executionId  // already unique per execution
Use the execution ID: $context.executionId is already unique per execution and is the simplest correlation ID. Pass it to the external system and instruct them to include it in the callback payload.