Skip to main content

Signal Process

Overview

The SignalProcessInstanceCommand sends data/signals to a waiting process instance. This unified command works for both UserTask and ReceiveTask (form mode) nodes, providing a single API for all form submissions.

Unified Form Submission

Use SignalProcessInstanceCommand for both UserTask and ReceiveTask form mode. The backend automatically detects the task type and handles CallbackRegistry updates internally. Your frontend doesn't need to distinguish between task types!

API Endpoint

POST /api/core/cmd

Headers

Content-Type: application/json
Authorization: Bearer {access_token}
X-Tenant-ID: {tenant_id}

Request Structure

{
"cmd": "SignalProcessInstanceCommand",
"data": {
"instanceGuid": "abc-123-def-456",
"callbackData": {
"approved": true,
"comments": "Application looks good"
},
"taskId": "Task_Approval"
}
}

Legacy Format (Still Supported)

{
"cmd": "SignalProcessInstanceCommand",
"data": {
"instanceGuid": "abc-123-def-456",
"signalPayload": {
"approved": true,
"comments": "Application looks good"
}
}
}

Request Fields

FieldTypeRequiredDescription
instanceGuidstringYesThe unique identifier of the process instance to signal
callbackDataobjectConditional*Data to send to the process (new parameter name)
signalPayloadobjectConditional*Legacy parameter (fallback for callbackData)
taskIdstringNoSpecific task ID (optional, uses first waiting task if not provided)
currentUserstringNoUser performing the action (defaults to "system")

*Either callbackData OR signalPayload must be provided. The callbackData parameter is preferred for new implementations.

Backward Compatibility

The legacy signalPayload parameter is still supported for backward compatibility. However, new implementations should use callbackData for consistency with the unified callback architecture.

When to Use Signal Process

Completing UserTasks

When a process reaches a UserTask and waits for human action:

{
"cmd": "SignalProcessInstanceCommand",
"data": {
"instanceGuid": "loan-approval-123",
"signalData": "{\"action\": \"approve\", \"officerComments\": \"Credit score acceptable\", \"approvedAmount\": 50000}"
}
}

Providing External Data

When a process waits for external system responses or data:

{
"cmd": "SignalProcessInstanceCommand",
"data": {
"instanceGuid": "kyc-verification-456",
"signalData": "{\"kycStatus\": \"verified\", \"kycScore\": 95, \"verificationDate\": \"2024-12-19\"}"
}
}

Resuming After Pause

When a process is intentionally paused and needs to resume:

{
"cmd": "SignalProcessInstanceCommand",
"data": {
"instanceGuid": "payment-processing-789",
"signalData": "{\"resume\": true, \"reason\": \"Manual review completed\"}"
}
}

Sample Requests

1. Approve Loan Application

{
"cmd": "SignalProcessInstanceCommand",
"data": {
"instanceGuid": "loan-app-2024-001",
"signalData": "{\"userAction\": \"approve\", \"approvedBy\": \"john.doe@bank.com\", \"approvedAmount\": 75000, \"interestRate\": 5.5, \"term\": 36, \"conditions\": [\"Provide proof of income\", \"Valid ID required\"], \"approvalDate\": \"2024-12-19T14:30:00Z\"}"
}
}

2. Reject Application

{
"cmd": "SignalProcessInstanceCommand",
"data": {
"instanceGuid": "loan-app-2024-002",
"signalData": "{\"userAction\": \"reject\", \"rejectedBy\": \"jane.smith@bank.com\", \"rejectionReason\": \"Insufficient credit score\", \"creditScore\": 580, \"minimumRequired\": 650}"
}
}

3. Request More Information

{
"cmd": "SignalProcessInstanceCommand",
"data": {
"instanceGuid": "account-opening-789",
"signalData": "{\"userAction\": \"requestInfo\", \"requiredDocuments\": [\"Utility bill\", \"Employment letter\"], \"requestedBy\": \"cs@bank.com\", \"dueDate\": \"2024-12-25\"}"
}
}

4. Complete KYC Verification

{
"cmd": "SignalProcessInstanceCommand",
"data": {
"instanceGuid": "kyc-process-456",
"signalData": "{\"kycCompleted\": true, \"verificationMethod\": \"Video Call\", \"verifiedBy\": \"compliance@bank.com\", \"documentsVerified\": [\"Passport\", \"Address Proof\"], \"riskLevel\": \"Low\"}"
}
}

Response Structure

Successful Signal (Process Continues)

{
"isSuccessful": true,
"message": "Process signaled successfully and continued execution",
"statusCode": "00",
"data": {
"instanceGuid": "loan-app-2024-001",
"status": "running",
"currentActivityId": "Task_DisburseL oan",
"result": {
"message": "Signal processed successfully",
"nextActions": [
{
"action": "continue",
"label": "Process Continuing",
"currentTask": "Task_DisburseLoan"
}
],
"waiting": false
},
"stateJson": "{...}",
"nextActions": [...]
}
}

Successful Signal (Process Waiting Again)

{
"isSuccessful": true,
"message": "Process signaled successfully and is waiting at next UserTask",
"statusCode": "00",
"data": {
"instanceGuid": "loan-app-2024-001",
"status": "waiting",
"currentActivityId": "Task_ManagerApproval",
"result": {
"message": "Waiting for manager approval",
"nextActions": [
{
"action": "approve",
"label": "Approve",
"userAction": true
},
{
"action": "reject",
"label": "Reject",
"userAction": true
}
],
"waiting": true
},
"taskInfo": {
"taskId": "Task_ManagerApproval",
"taskName": "Manager Approval Required",
"taskType": "UserTask",
"assignedTo": "managers"
}
}
}

Successful Signal (Process Completed)

{
"isSuccessful": true,
"message": "Process completed successfully",
"statusCode": "00",
"data": {
"instanceGuid": "loan-app-2024-001",
"status": "completed",
"currentActivityId": "EndEvent_Success",
"result": {
"message": "Process completed",
"finalVariables": {
"loanId": 12345,
"approvedAmount": 75000,
"disbursementDate": "2024-12-20"
},
"waiting": false
}
}
}

Error Responses

Instance Not Found

{
"isSuccessful": false,
"message": "Process instance 'invalid-guid' not found.",
"statusCode": "99",
"data": null
}

Instance Not Waiting

{
"isSuccessful": false,
"message": "Process instance is not in a waiting state. Current status: running",
"statusCode": "99",
"data": {
"currentStatus": "running"
}
}

Invalid Signal Data

{
"isSuccessful": false,
"message": "Invalid signal data JSON format",
"statusCode": "99",
"data": {
"error": "Unexpected character at position 15"
}
}

Signal Data Structure

The signalData must be a JSON string. Variables provided here are merged into the process context:

Before Signal

{
"loanAmount": 50000,
"customerId": 123,
"status": "pending"
}

Signal Data

"{\"userAction\": \"approve\", \"approvedAmount\": 75000, \"approvedBy\": \"manager@bank.com\"}"

After Signal (Merged Context)

{
"loanAmount": 50000,
"customerId": 123,
"status": "pending",
"userAction": "approve",
"approvedAmount": 75000,
"approvedBy": "manager@bank.com"
}

Process Flow with Signals

Best Practices

1. Include Context in Signal Data

Always include relevant context to help downstream tasks:

Good:

{
"signalData": "{\"action\": \"approve\", \"approvedBy\": \"john@bank.com\", \"timestamp\": \"2024-12-19T10:30:00Z\", \"approvedAmount\": 50000, \"comments\": \"All checks passed\"}"
}

Bad:

{
"signalData": "{\"action\": \"approve\"}"
}

2. Use Consistent Action Names

Define standard action names across your processes:

// Standard actions
"userAction": "approve"
"userAction": "reject"
"userAction": "requestMoreInfo"
"userAction": "escalate"

3. Validate State Before Signaling

Check that the process is in the correct state:

// First, get process state
const state = await getProcessState(instanceGuid);

if (state.status !== 'waiting') {
console.error('Process is not waiting for signal');
return;
}

// Then signal
await signalProcess(instanceGuid, signalData);

4. Handle Different Outcomes

The process may continue, wait again, or complete after signaling:

const response = await signalProcess(instanceGuid, signalData);

switch (response.data.status) {
case 'waiting':
// Process is waiting at another UserTask
showNextTaskForm(response.data.taskInfo);
break;

case 'running':
// Process is executing automatically
showProcessingMessage();
break;

case 'completed':
// Process finished
showCompletionMessage(response.data.result);
break;

case 'error':
// Something went wrong
showErrorMessage(response.message);
break;
}

Notes

  • The process must be in "waiting" state to receive signals
  • Signal data is merged with existing process variables
  • If a variable already exists, it will be overwritten by signal data
  • The process automatically continues after receiving the signal
  • If the process encounters another UserTask, it will pause again
  • All signal operations are logged for audit purposes
  • Signal data should be a valid JSON string