Wait for Callback Node
Overview
The Wait for Callback node pauses workflow execution and waits for an external system to send data via a webhook callback. This enables integration with external services, long-running processes, or human actions outside the workflow system.
When to Use
Use a Wait for Callback node when you need to:
- Integrate with external systems that process asynchronously
- Wait for third-party API webhooks
- Receive payment processing results
- Get data from external approval systems
- Wait for manual data entry from external forms
- Coordinate with systems that don’t have direct API integration
Configuration
Callback URL
The URL where the external system should send its callback:
- Must be a valid HTTP/HTTPS URL
- Can be a literal URL or JSONPath expression
- The workflow provides a unique token for security
Output Schema
Define the structure of data you expect to receive from the callback:
- Add fields matching the webhook payload structure
- Supports all field types (text, number, boolean, object, array)
- This schema validates incoming callback data
- Validated data becomes available in the node’s output
How It Works
- Workflow Pauses: Execution stops at the wait-for-callback node
- Token Generated: A unique callback token is created
- External Call: You trigger the external system (via Tool Call or Agent node)
- Await Callback: Workflow waits for the external system to POST data
- Data Received: External system sends data to the callback URL with token
- Validation: Incoming data is validated against the output schema
- Resume: Workflow continues with the callback data available
Examples
Example: Payment Processing
Node ID: waitForPayment
Callback URL: https://api.example.com/workflows/callback
Output Schema:
transactionId(String) - Payment transaction IDstatus(String) - Payment status (success/failed)amount(Number) - Amount processedtimestamp(String) - When payment completed
Flow:
initiatePayment (Tool Call)
└─ waitForPayment (Wait for Callback)
└─ Conditional: checkPaymentStatus
├─ Success → fulfillOrder
└─ Failed → refundCustomerAccess Data:
$.results.waitForPayment.transactionId
$.results.waitForPayment.status
$.results.waitForPayment.amountExample: External Approval System
Node ID: externalApproval
Callback URL: https://api.example.com/workflows/callback
Output Schema:
approved(Boolean) - Whether approvedapproverId(String) - Who approved itcomments(String) - Approval commentsapprovedAt(String) - Timestamp
Flow:
sendToApprovalSystem (Tool Call)
└─ externalApproval (Wait for Callback)
└─ Conditional: checkApproval
├─ Approved → processRequest
└─ Rejected → notifySubmitterExample: Document Processing
Node ID: documentProcessing
Callback URL: $.results.trigger.callbackEndpoint
Output Schema:
documentId(String) - Processed document IDextractedData(Object) - Data extracted from documentname(String)date(String)amount(Number)
confidence(Number) - Confidence score (0-1)errors(Array) - Any processing errors
Flow:
uploadDocument (Tool Call)
└─ documentProcessing (Wait for Callback)
└─ Conditional: checkConfidence
├─ High Confidence → saveToDatabase
└─ Low Confidence → manualReviewExample: Third-Party API Webhook
Node ID: stripeWebhook
Callback URL: https://api.example.com/workflows/callback
Output Schema:
eventType(String) - Stripe event typecustomerId(String) - Customer IDsubscriptionId(String) - Subscription IDstatus(String) - Subscription statuscurrentPeriodEnd(String) - Billing period end
Flow:
createStripeSubscription (Tool Call)
└─ stripeWebhook (Wait for Callback)
└─ Conditional: checkEvent
├─ subscription.created → activateAccount
├─ subscription.updated → updateAccount
└─ subscription.deleted → deactivateAccountExample: Long-Running Job
Node ID: batchJob
Callback URL: https://api.example.com/workflows/callback
Output Schema:
jobId(String) - Job identifierstatus(String) - Job statusprocessedCount(Number) - Items processedfailedCount(Number) - Items failedresults(Array) - Processing resultscompletedAt(String) - Completion timestamp
Flow:
startBatchJob (Tool Call)
└─ batchJob (Wait for Callback)
└─ Function: summarizeResults
└─ sendCompletionEmailCallback Payload Format
External systems should send a POST request to the callback URL with:
Headers:
Content-Type: application/json
Authorization: Bearer <callback-token>Body:
{
"transactionId": "txn_123456",
"status": "success",
"amount": 99.99,
"timestamp": "2025-12-22T10:30:00Z"
}The payload must match the output schema defined in the node.
Accessing Callback Data
After the callback is received:
// Access all callback data
$.results.<nodeId>
// Access specific fields
$.results.<nodeId>.fieldName
// Examples:
$.results.waitForPayment.transactionId
$.results.externalApproval.approved
$.results.documentProcessing.extractedData.nameBest Practices
- Define Clear Schema: Specify exactly what data you expect
- Validate Data: Use the output schema to ensure data integrity
- Security: Protect callback URLs with tokens/authentication
- Timeout Handling: Set onFailure paths for timeout scenarios
- Error Handling: Handle cases where callback data is invalid
- Document Format: Clearly document expected callback format for external teams
- Unique URLs: Use unique callback URLs per workflow execution when possible
- Test Callbacks: Test callback integration thoroughly before production
Security Considerations
- Authentication: Always use tokens or other authentication for callbacks
- HTTPS Only: Use HTTPS URLs for callback endpoints
- Validate Source: Verify callbacks come from expected sources
- Rate Limiting: Implement rate limiting on callback endpoints
- Token Expiry: Consider time-limited callback tokens
- Data Validation: Strictly validate incoming data against schema
Common Patterns
Wait for Multiple Webhooks
Parallel: waitForMultiple
├─ Branch 1: waitForPayment
├─ Branch 2: waitForShipping
└─ Branch 3: waitForInventoryAll three callbacks must be received before proceeding.
Conditional Processing Based on Callback
waitForWebhook
└─ Conditional: checkEventType
├─ Choice 1: eventType = "success" → processSuccess
├─ Choice 2: eventType = "failed" → handleFailure
└─ Default → logUnknownEventRetry with Timeout
initiateExternalProcess
└─ waitForCallback
onFailure: retryProcessCallback with Data Transformation
waitForData
└─ Function: transformCallbackData
└─ validateTransformedData
└─ saveToDatabaseLimitations
- Workflow Pauses: Execution halts until callback received
- Timeout Risk: Long waits may hit workflow execution limits
- Single Callback: Each node accepts one callback only
- Schema Required: Must define output schema upfront
- No Retry: Cannot automatically retry callback request
- External Dependency: Relies on external system to send callback
Error Handling
Callback Failure
If callback is not received or invalid:
- Use onFailure path to handle timeout
- Log the failure for debugging
- Consider retry logic
Invalid Data
If callback data doesn’t match schema:
- The node fails validation
- onFailure path is triggered
- Check logs for validation errors
Example Error Handling
waitForCallback
onSuccess: processData
onFailure: handleCallbackError
└─ Function: logError
└─ Conditional: checkRetryCount
├─ Count < 3 → retryInitiation
└─ Count >= 3 → notifyAdminDebugging
To debug callback issues:
- Check Logs: Review workflow execution logs for callback attempts
- Verify URL: Ensure callback URL is accessible
- Test Payload: Test with sample payload matching schema
- Check Auth: Verify authentication tokens are correct
- Network Issues: Check for network/firewall issues
- Schema Mismatch: Ensure callback data matches output schema exactly