Signal System

Signal Tasks

Master event emission and workflow coordination with signal tasks. Learn how to send structured messages between workflows, implement event-driven architectures, and build decoupled communication patterns.

Overview

Signal tasks are the event publishers in Compozy's workflow orchestration system, enabling sophisticated publish-subscribe communication patterns. They dispatch structured messages that can trigger wait tasks, start workflows via signal triggers, and coordinate complex multi-system operations.

Event Broadcasting

Publish to multiple subscribers with guaranteed delivery

Dynamic Routing

Context-aware signal IDs using template expressions

Structured Payloads

Rich data structures with schema validation

Error Handling

Retry strategies and failure recovery patterns

Quick Start

1

Define a signal task

Create your first signal emitter
- id: send-notification
  type: signal
  signal:
    id: "user-approved"
    payload:
      user_id: "{{ .workflow.input.user_id }}"
      approved_by: "{{ .workflow.input.approver }}"
      timestamp: "{{ now }}"

Learn more about template expressions and Sprig functions.

2

Create a receiver

Set up a workflow to receive signals

Configure a workflow with a wait task or signal trigger:

# Option 1: Wait task
- id: wait-for-approval
  type: wait
  wait_for: "user-approved"
  on_timeout: handle-timeout

# Option 2: Signal trigger
triggers:
  - type: signal
    name: user-approved
3

Test the flow

Execute and monitor signal delivery

Use the CLI workflow commands to test your signal flow and monitor execution.

Signal Configuration

FieldDescriptionExample / Icon
type: signalIdentifies this as a signal emission task⚙️ (Settings)
signal.idUnique identifier for signal routing🆔 (Fingerprint)
signal.payloadOptional data to send with the signal📦 (Package)

Signal ID Strategies

Use static IDs for consistent system-wide events:

signal:
  id: "system-maintenance"
  id: "daily-batch-complete"
  id: "deployment-finished"

Best for: System notifications, scheduled workflows, infrastructure events

Common Patterns

Event Notification

Send workflow completion notifications:

- id: notify-completion
  type: signal
  signal:
    id: "workflow-completed"
    payload:
      workflow_id: "{{ .workflow.id }}"
      completed_at: "{{ now }}"
      status: "success"

Perfect for monitoring integration and triggering downstream workflows.

Approval Workflows

Implement human-in-the-loop patterns with the Event API:

- id: request-approval
  type: signal
  signal:
    id: "approval-requested"
    payload:
      request_id: "{{ .workflow.input.request_id }}"
      requester: "{{ .workflow.input.user_id }}"
      amount: "{{ .workflow.input.amount }}"
      approval_link: "{{ .env.APP_URL }}/approve/{{ .workflow.input.request_id }}"

See complete approval workflow patterns in the patterns documentation.

Data Pipeline Coordination

Coordinate multi-stage processing with collection tasks:

- id: data-stage-complete
  type: signal
  signal:
    id: "pipeline-{{ .workflow.input.pipeline_id }}-stage-{{ .workflow.input.stage }}"
    payload:
      pipeline_id: "{{ .workflow.input.pipeline_id }}"
      stage: "{{ .workflow.input.stage }}"
      next_stage: "{{ .task.output.next_stage }}"
      output_location: "{{ .task.output.data_path }}"

Advanced Patterns

Conditional Signal Dispatch

Combine with router tasks for dynamic routing:

- id: route-by-priority
  type: router
  routes:
    - condition: '.task.output.priority == "urgent"'
      next: send-urgent-signal
    - condition: '.task.output.priority == "normal"'
      next: send-normal-signal
    - default: send-low-priority-signal

- id: send-urgent-signal
  type: signal
  signal:
    id: "urgent-task-created"
    payload:
      task_data: "{{ .task.output }}"
      escalation_required: true

Error Recovery Signals

Implement error handling patterns with notifications:

- id: process-data
  type: basic
  tool:
    id: data-processor
  with:
    data: "{{ .workflow.input.data }}"

  on_error:
    next: send-error-signal

- id: send-error-signal
  type: signal
  signal:
    id: "processing-error"
    payload:
      workflow_id: "{{ .workflow.id }}"
      error: "{{ .tasks.process-data.error }}"
      timestamp: "{{ now }}"
      severity: "high"
      retry_recommended: true

Best Practices

Consistent Naming

Use clear, hierarchical signal IDs like 'domain-entity-action'

Minimal Payloads

Include essential data only; use references for large objects

Version Compatibility

Include version info in payloads for backward compatibility

Next Steps