Webhook & Event Variables
Reference for template variables, auto-injected event metadata, and the execution context object
When a webhook or scheduled event triggers a workflow, the system provides template variables for input mappings and injects event metadata into the execution context automatically.
Webhook HMAC Authentication
Section titled “Webhook HMAC Authentication”Webhook event sources support HMAC signature verification to ensure incoming requests are authentic. Configure these fields in the event source settings:
| Field | Description | Example |
|---|---|---|
| Webhook Secret | Shared secret for HMAC signature verification | whsec_abc123... |
| Signature Header | HTTP header containing the HMAC signature | X-Hub-Signature-256 |
| Signature Prefix | Prefix before the signature value | sha256= |
| Event Type Header | Header containing the event type (optional) | X-Event-Type |
| Event Type Field | JSON body field containing the event type (optional) | event or type |
When a webhook secret is configured, Bifrost computes an HMAC-SHA256 digest of the request body and compares it against the signature in the specified header. Requests with invalid signatures are rejected.
Agent-Targeted Subscriptions
Section titled “Agent-Targeted Subscriptions”Event subscriptions can target agents in addition to workflows. When an event is received, it can trigger an autonomous agent run:
- Go to your event source and click Add Subscription
- Set Type to Agent
- Select the target agent
- The event payload becomes the agent’s input (available as
_eventin the agent’s context)
This enables event-driven agent workflows — for example, a webhook from a ticketing system can trigger a triage agent that classifies and routes tickets automatically.
Template Variables for Input Mappings
Section titled “Template Variables for Input Mappings”When configuring event subscriptions, use these template expressions in input mappings to extract data from incoming events:
| Variable | Description | Example |
|---|---|---|
{{ payload }} | Full event body (parsed JSON) | {{ payload }} |
{{ payload.field }} | Nested field from event body | {{ payload.ticket.id }} |
{{ headers.X-Something }} | Request header value | {{ headers.Content-Type }} |
{{ scheduled_time }} | Trigger time (schedule events) | {{ scheduled_time }} |
{{ cron_expression }} | Cron expression (schedule events) | {{ cron_expression }} |
These are resolved at dispatch time and passed as workflow input parameters.
The _event Context Parameter
Section titled “The _event Context Parameter”In addition to mapped input parameters, every event-triggered execution receives a reserved _event key in context.parameters with the full event metadata:
| Field | Type | Description |
|---|---|---|
id | str | Unique event ID (UUID) |
type | str | Event type string (e.g. webhook, schedule) |
body | any | Complete raw request body (dict, list, or string) |
headers | dict | null | HTTP request headers (null for schedule events) |
received_at | str | null | ISO 8601 timestamp when the event was received |
source_ip | str | null | IP address of the sender (null for schedule events) |
Accessing Event Data in Workflows
Section titled “Accessing Event Data in Workflows”from bifrost import context
@workflow()async def handle_webhook(): # Mapped input parameters (from your input mapping config) ticket_id = context.parameters.get("ticket_id")
# Full event metadata (auto-injected) event = context.parameters.get("_event", {}) event_id = event.get("id") event_type = event.get("type") raw_body = event.get("body") headers = event.get("headers", {}) received_at = event.get("received_at") source_ip = event.get("source_ip")
# Other context properties org_id = context.org_id # Organization scope caller = context.email # Caller identity time_saved = context.roi.time_saved # ROI tracking
return {"processed": event_id}Example: Logging Webhook Details
Section titled “Example: Logging Webhook Details”from bifrost import context, logger
@workflow()async def audit_webhook(): event = context.parameters["_event"]
logger.info(f"Received {event['type']} event from {event['source_ip']}") logger.info(f"Headers: {event['headers']}") logger.info(f"Body: {event['body']}")
return {"event_id": event["id"], "received_at": event["received_at"]}