Event-Driven Workflows
Connect autonomous agents through business events — no fixed sequence required.
The Agent Builder's cron and webhook triggers fire a workflow when a schedule fires or an HTTP call arrives. Event-driven workflows extend this: a workflow fires when a business event is published to the Event Bus, and it can publish events back, chaining to the next workflow without any hard-coded coupling between them.
This unlocks two capabilities the sequential graph model cannot express:
| Sequential Workflow | Event-Driven Workflow | |
|---|---|---|
| Execution order | Fixed in the graph at design time | Decided at runtime by events |
| Cross-workflow coordination | Direct sub-workflow call | Loose coupling via events |
| Failure recovery | Retry the whole run | Compensate only what succeeded |
| Multi-domain processes | One large graph | Independent workflows per domain |
How it works
External system / agent node
│ POST /api/v1/events/ingest OR emit_event tool
▼
┌─────────────────────────────────────┐
│ Event Bus (Postgres + Redis) │
│ Stores every event immutably; │
│ fans out to subscribed workflows │
└──────────────────┬──────────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
Workflow A Workflow B Saga Coordinator
(subscribed) (subscribed) (advances sagas)
│ │
▼ ▼
agent runs agent runs
calls tools emits events
emits events ──▶ triggers Workflow C
- An event is published — by an external system, a webhook, or an
emit_eventtool call inside a running workflow. - The Event Bus fans out — every workflow subscribed to that event type receives a run, with the event payload as input.
- The workflow runs — the agent reads the payload, calls tools, and optionally publishes follow-up events.
- The chain continues — follow-up events trigger the next subscribed workflows.
Event structure
Every event is a typed, immutable record:
{
"event_id": "evt_abc123",
"event_type": "leave_applied",
"source": "hridaone",
"correlation_id": "EMP001",
"user_id": "usr_456",
"payload": {
"employee_id": "EMP001",
"leave_type": "EARNED",
"days": 5
},
"published_at": 1751234567890
}| Field | Purpose |
|---|---|
event_type | Snake_case name that subscriptions match against |
correlation_id | Business key that links all events in the same process (e.g. EMP001 for an employee) |
payload | Arbitrary JSON — the event's data |
source | Who published it — hridaone, workflow:{id}, api, etc. |
The correlation_id is the key to tracing a full business process. Pass it through every emit_event call.
Subscribing a workflow to an event
The Event trigger type is currently configured via API. A dedicated tab will be added to the Triggers panel in a future release. The workflow must be published before creating a subscription.
curl -X POST "http://localhost:8080/api/v1/agent-workflows/{workflow_id}/triggers/event" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "On leave_applied",
"event_type": "leave_applied",
"filter_expr": "payload.get(\"days\", 0) > 5",
"concurrency": "one_per_correlation"
}'Subscription options:
| Field | Description |
|---|---|
event_type | Event type string to subscribe to |
filter_expr | Optional Python expression evaluated against the event. payload and event are available as variables. Returns True = fire the workflow, False = skip. |
concurrency | parallel (default) — one run per event. one_per_correlation — skip if a run is already active for the same correlation_id. |
catalog_id | Catalog whose LLM credentials to use for the run |
space_id | Space context for the run |
Reading event data in a workflow
When fired by an event subscription, the workflow's initial state contains the full event under _event:
{
"_event": {
"id": "evt_abc123",
"type": "leave_applied",
"payload": { "employee_id": "EMP001", "days": 5 },
"correlation_id": "EMP001",
"source": "hridaone",
"published_at": 1751234567890
}
}The workflow input passed to the first agent node is the event serialized as JSON — the agent can read it directly.
Publishing events from a workflow
Use the emit_event built-in tool inside any agent node to publish events mid-workflow:
{
"event_type": "leave_auto_approved",
"payload": "{\"employee_id\": \"EMP001\", \"leave_id\": \"LV456\"}",
"correlation_id": "EMP001"
}This is how workflows in a chain communicate — one workflow's emit_event output is another workflow's subscription trigger.
Always pass correlation_id from the incoming event to the emitted event so all runs in the same process stay linked.
External event ingestion
External systems (HRMS, ERP, CRM) publish events via a dedicated endpoint authenticated by API key — no JWT required:
# Set HRIDA_EVENT_API_KEY on the server
curl -X POST http://localhost:8080/api/v1/events/ingest \
-H "X-Api-Key: <HRIDA_EVENT_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"event_type": "invoice_received",
"correlation_id": "INV-2026-001",
"source": "erp",
"payload": {
"invoice_id": "INV-2026-001",
"amount": 15000,
"vendor": "Acme Corp"
}
}'Returns 202 Accepted immediately. Dispatch to subscribers is asynchronous.
Viewing events and monitoring
# List recent events
GET /api/v1/events?event_type=leave_applied&correlation_id=EMP001
# Live SSE stream (for dashboards)
GET /api/v1/events/streamAdmin panel → Events (coming in future release) will show this as a real-time feed.
Related
- Saga Orchestration — coordinate multi-step processes with automatic failure compensation
- Unpredictable Process Patterns — design patterns for processes with no fixed sequence
- emit_event tool — publish events from within a workflow node
- Triggers — cron and webhook triggers (the other two trigger types)
- Run Infrastructure — SSE streaming, distributed execution