Appearance
Event-Driven Automation
Learn how to configure event listeners that automatically trigger AI agents and teams in response to external events from your systems.
Overview
The Event Listener System enables external systems to trigger AI agents and teams through a webhook-style API. Events are processed asynchronously via Redis Streams, ensuring high throughput and reliability.
Use Cases:
- Automatically process orders when
order.createdevents arrive - Send notifications when
user.signupevents occur - Trigger data collection workflows from external systems
- Build event-driven automations between systems
Quick Start
1. Create an Event Listener
bash
curl -X POST "http://localhost:8000/api/v1/event-listeners" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Order Processing Handler",
"description": "Handles new order events",
"event_pattern": "order.created",
"match_type": "exact",
"target_type": "agent",
"agent_id": 1,
"message_template": "New order received: #{{payload.order_id}} from {{payload.customer}} for ${{payload.total}}. Please process this order.",
"priority": 5,
"is_active": true
}'2. Test Template Rendering
Test your message template without executing the agent:
bash
curl -X POST "http://localhost:8000/api/v1/event-listeners/1/test" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"event_type": "order.created",
"payload": {
"order_id": "12345",
"customer": "John Doe",
"total": 99.99
}
}'Response:
json
{
"listener_id": 1,
"listener_name": "Order Processing Handler",
"template": "New order received: #{{payload.order_id}} ...",
"rendered_message": "New order received: #12345 from John Doe for $99.99. Please process this order.",
"input": { ... }
}3. Send an Event
bash
curl -X POST "http://localhost:8000/api/v1/events" \
-H "X-AUTH-TOKEN: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event_type": "order.created",
"payload": {
"order_id": "12345",
"customer": "John Doe",
"total": 99.99,
"items": [
{"name": "Widget", "quantity": 2}
]
},
"context": {
"source": "shopify",
"environment": "production"
}
}'Response:
json
{
"id": 1,
"event_type": "order.created",
"event_id": "auto-generated-uuid",
"status": "PENDING",
"listeners_matched": 1,
"created_at": "2025-01-06T10:30:00Z"
}4. Monitor Execution
bash
# Check event status
curl "http://localhost:8000/api/v1/events/1" \
-H "X-AUTH-TOKEN: YOUR_API_KEY"
# View all executions for this event
curl "http://localhost:8000/api/v1/events/1/executions" \
-H "X-AUTH-TOKEN: YOUR_API_KEY"Pattern Matching
Event listeners support three match types:
EXACT Match
Matches event type exactly:
json
{
"event_pattern": "order.created",
"match_type": "exact"
}| Event Type | Match? |
|---|---|
order.created | ✅ Yes |
order.updated | ❌ No |
order.item.added | ❌ No |
PREFIX Match
Matches events starting with pattern:
json
{
"event_pattern": "order.",
"match_type": "prefix"
}| Event Type | Match? |
|---|---|
order.created | ✅ Yes |
order.updated | ✅ Yes |
order.item.added | ✅ Yes |
user.signup | ❌ No |
WILDCARD Match
Uses fnmatch-style wildcards:
json
{
"event_pattern": "order.*",
"match_type": "wildcard"
}| Pattern | Event Type | Match? |
|---|---|---|
order.* | order.created | ✅ Yes |
order.* | order.item.added | ❌ No (nested) |
order.** | order.item.added | ✅ Yes |
*.created | order.created | ✅ Yes |
*.created | user.created | ✅ Yes |
When to use each:
- EXACT: When you want to handle one specific event type
- PREFIX: When you want to handle all events in a namespace
- WILDCARD: When you need complex matching patterns
Message Templates
Message templates use Jinja2 syntax with these available variables:
| Variable | Type | Description |
|---|---|---|
{{event_type}} | string | The event type (e.g., "order.created") |
{{payload}} | dict | Full payload object |
{{payload.field}} | any | Access specific payload fields |
{{context}} | dict | Context object (may be empty) |
Basic Template
text
New {{event_type}} event received!
Order ID: {{payload.order_id}}
Customer: {{payload.customer}}
Total: ${{payload.total}}Template with Conditionals
text
{% if payload.priority == 'high' %}
URGENT:{% endif %} Order #{{payload.order_id}}
Customer: {{payload.customer.name}} ({{payload.customer.email}})
Total: ${{payload.total}}
{% if payload.items %}
Items:
{% for item in payload.items %}
- {{item.name}} x{{item.quantity}} @ ${{item.price}}
{% endfor %}
{% endif %}
Source: {{context.source | default('unknown')}}Template Best Practices
- Provide context: Include enough information for the agent to act
- Use defaults: Handle missing fields gracefully with
| default('value') - Format currency: Use consistent formatting for numbers
- Add structure: Use clear formatting for readability
Listener Configuration
Target Types
Agent Target:
json
{
"target_type": "agent",
"agent_id": 1,
"team_id": null
}Triggers a single agent with the rendered message.
Team Target:
json
{
"target_type": "team",
"agent_id": null,
"team_id": 1
}Triggers all agents in the team (parallel execution).
Priority
Listeners with the same event pattern execute in priority order (1 = highest, 10 = lowest):
json
{
"priority": 5
}Use cases:
- Priority 1: Critical notifications
- Priority 5: Standard processing (default)
- Priority 10: Background tasks
Active/Inactive
Disable listeners without deleting them:
json
{
"is_active": true
}List only active listeners:
bash
curl "http://localhost:8000/api/v1/event-listeners?active_only=true"Event Flow
Authentication
Event reception supports JWT tokens or API keys:
bash
# JWT Token
curl -X POST "http://localhost:8000/api/v1/events" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }'
# API Key
curl -X POST "http://localhost:8000/api/v1/events" \
-H "X-AUTH-TOKEN: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ ... }'Both methods work identically. API keys are recommended for server-to-server integrations.
Idempotency
Prevent duplicate processing by providing an event_id:
json
{
"event_id": "evt_abc123_unique_id",
"event_type": "order.created",
"payload": { ... }
}If an event with the same event_id already exists for the account, the API returns the existing event instead of creating a duplicate.
Without event_id: A new UUID is auto-generated.
Error Handling
Event-Level Errors
If the event cannot be processed:
InboundEvent.status→FAILEDInboundEvent.error_message→ Error description- Event is acknowledged (not retried automatically)
Execution-Level Errors
If a specific listener fails:
EventExecution.status→FAILEDEventExecution.error_message→ Error description- Other listeners continue processing
- Final
InboundEvent.status→FAILEDif any listener failed
Retry Strategy
Failed executions can be retried via the queue system's retry mechanism. See Background Systems for details.
Monitoring
List All Listeners
bash
curl "http://localhost:8000/api/v1/event-listeners" \
-H "Authorization: Bearer YOUR_TOKEN"Get Listener Details
bash
curl "http://localhost:8000/api/v1/event-listeners/1" \
-H "Authorization: Bearer YOUR_TOKEN"View Execution History
bash
# All executions for a listener
curl "http://localhost:8000/api/v1/event-listeners/1/executions" \
-H "Authorization: Bearer YOUR_TOKEN"
# All executions for an event
curl "http://localhost:8000/api/v1/events/1/executions" \
-H "X-AUTH-TOKEN: YOUR_API_KEY"Example: E-commerce Order Processing
1. Create Listener
bash
curl -X POST "http://localhost:8000/api/v1/event-listeners" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"name": "Order Processor",
"event_pattern": "order.created",
"match_type": "exact",
"target_type": "agent",
"agent_id": 5,
"message_template": "Process order #{{payload.order_id}}\n\nCustomer: {{payload.customer.name}}\nEmail: {{payload.customer.email}}\nTotal: ${{payload.total}}\n\n{% for item in payload.items %}{{loop.index}}. {{item.name}} x{{item.quantity}}\n{% endfor %}\n\nShipping: {{payload.shipping.address}}"
}'2. Send Order Event
bash
curl -X POST "http://localhost:8000/api/v1/events" \
-H "X-AUTH-TOKEN: $API_KEY" \
-d '{
"event_type": "order.created",
"event_id": "order_12345",
"payload": {
"order_id": "12345",
"customer": {
"name": "Jane Smith",
"email": "jane@example.com"
},
"total": 149.99,
"items": [
{"name": "Widget Pro", "quantity": 2, "price": 59.99},
{"name": "Gadget Plus", "quantity": 1, "price": 29.99}
],
"shipping": {
"address": "123 Main St, City, ST 12345"
}
},
"context": {
"source": "shopify",
"webhook_id": "wh_abc123"
}
}'3. Monitor Results
bash
# Check execution
curl "http://localhost:8000/api/v1/events/1/executions" \
-H "X-AUTH-TOKEN: $API_KEY"Cross-References
- Events API Reference - Full API documentation
- Event Listeners API Reference - Listener management endpoints
- Events System Architecture - Internal architecture details