Skip to main content

Overview

Events in Sample workflows allow you to trigger workflows and control their execution based on external or internal events. This creates a reactive workflow system where workflows can respond to changes in your application state.
Events functionality requires samplehc >= 0.3.0 and workflows-py >= 0.1.18.

Emitting Events

You can emit events from your workflow functions using the SampleHC client. Events consist of a name and an optional payload.

Basic Event Emission

Event Structure

Events have the following structure:
  • name: A string identifier for the event type (e.g., “order-updated”, “order-created”)
  • payload: Any JSON-serializable data relevant to the event

Idempotency Keys

You can attach an idempotency_key when emitting an event. The key is stored with the event and shown alongside it in the event history, which makes it easy to trace which emit produced which workflow runs — and to spot duplicate emissions from retried emitters.
The idempotency key does not currently prevent duplicate processing — two emits with the same key both trigger listening workflows. If you need exactly-once behavior, track processed records in your database as shown in Emitter Workflows.

Listening to Events

Workflows can listen to events using two mechanisms: start_on and cancel_on.

Starting Workflows on Events

Use start_on to automatically start a workflow when specific events are received:

Start Handler Return Values

The start_on handler function can return:
  • An object with optional start_data field: Starts the workflow with the provided start data
  • None: Does not start the workflow

Canceling Workflows on Events

Use cancel_on to automatically cancel running workflows when specific events are received:

Cancel Handler Return Values

The cancel_on handler function should return:
  • True: Cancel the workflow run
  • False: Keep the workflow running

Event Context

When handling events, you have access to an event context that provides:

StartOnContext

Available in start_on handlers:

CancelOnContext

Available in cancel_on handlers:

Common Patterns

Order Processing Workflow

Multi-Event Workflow

Emitter Workflows

A common way to structure high-volume automations is to split them into an emitter workflow and a processor workflow:
  • The emitter runs on a cron schedule, queries a system of record for new work (for example, new orders), and emits one event per record.
  • The processor declares start_on for that event, so each record gets its own workflow run — with its own task list entries, column values, and retry behavior.
To avoid emitting the same record twice, track processed records in a database table and only insert the tracking row after the event is emitted successfully:
Keep event payloads small — pass identifiers and have the processor workflow look up full records itself. This keeps events readable and avoids stale data when the processor runs later than the emitter.

Best Practices

Event Naming

  • Use descriptive, consistent event names (e.g., “order-created”, “patient-admitted”)
  • Include entity type and action (e.g., “user-registered”, “document-processed”)
  • Use kebab-case for event names

Payload Design

  • Include essential identifiers in the payload (IDs, timestamps)
  • Keep payloads lightweight - avoid large objects
  • Include context needed for decision making

Error Handling

Performance Considerations

  • Keep event handlers lightweight and fast
  • Avoid heavy computations in start_on and cancel_on handlers
  • Use specific event matching to avoid unnecessary workflow starts/cancellations

Sample System Emitted Events

Sample automatically emits certain events when specific actions occur in your system. These events are prefixed with sample: and can be used to trigger workflows automatically.

Email

All email-related events are emitted under the sample:email:* pattern.

received

When an email is sent to your sample mailbox (your_organization@start.onsample.com), Sample automatically emits a sample:email:received event. Event Name: sample:email:received Payload Structure:
Example Usage:

Kno2

All Kno2-related events are emitted under the sample:kno2:* pattern when messages are received through your Kno2 integration.

message-receive

When a message (such as a fax) is received through your Kno2 connection, Sample automatically emits a sample:kno2:${connection.slug}:message-receive event, where ${connection.slug} corresponds to the specific Kno2 connection that received the message. Event Name: sample:kno2:${connection.slug}:message-receive Payload Structure:
Key Fields:
  • message.id: Unique identifier for the message
  • message.subject: Subject line of the fax/message
  • message.toAddress: Recipient fax number
  • message.fromAddress: Sender fax number
  • message.sourceType: Type of message (e.g., “Fax”)
  • message.attachments: Array of attachment metadata from Kno2
  • attachments: Array of Sample file metadata IDs for downloaded attachments
Example Usage:

Troubleshooting

Common Issues

Workflow not starting on events:
  • Verify event names match exactly between emit and listen
  • Check that handler functions return appropriate values
  • Ensure version requirements are met
Unexpected workflow cancellations:
  • Review cancel_on handler logic
  • Check event payload structure
  • Verify cancellation conditions are specific enough
Missing event data:
  • Ensure event payload contains required fields
  • Check that get_start_data() returns expected structure
  • Verify event emission includes necessary context