Skip to main content

Triggers

Run a published workflow automatically — on a schedule, in response to an HTTP call, or when a business event occurs.

In addition to the Run panel and the manual POST /api/v1/agent-workflows/{id}/run API, a workflow fires based on a cron schedule, an incoming webhook, or a business event from the Event Bus. Cron and webhook triggers are configured from the Triggers panel in the workflow editor (the bolt icon). Event subscriptions are configured via API (UI tab coming soon).

Published workflows only

All trigger types refuse to fire a workflow that isn't in published status. Stage and publish the workflow first.


Cron triggers​

Run a workflow on a recurring schedule using standard 5-field cron syntax.

Creating a cron trigger​

  1. Open the workflow in the editor and click the Triggers button.
  2. Click + Cron Schedule.
  3. Fill in:
FieldDescription
NameHuman-readable label (e.g. "Daily 9am summary")
Cron ExpressionStandard 5-field cron syntax: minute hour day-of-month month day-of-week
TimezoneIANA timezone name (default UTC)
Input TemplateText passed as the workflow's input on each fire. Supports {date} and {now} placeholders

Example expressions:

ExpressionMeaning
0 9 * * 1-59:00 AM, Monday–Friday
*/15 * * * *Every 15 minutes
0 0 1 * *Midnight on the 1st of every month

Example input template:

Generate the daily summary for {date}. Current time: {now}.
Template format errors

If the input template contains an unrecognized placeholder (e.g. {user}) or invalid syntax, the template is used verbatim — the cron trigger still fires, but the unresolved placeholder appears as literal text in the workflow input. A warning is logged for visibility.

How firing works​

A background scheduler checks for due triggers every 60 seconds. When a cron trigger's next_run_at has passed:

  1. The trigger is atomically claimed (its schedule is advanced immediately, so it can't be double-fired if multiple app instances are running).
  2. The workflow runs with the rendered input template.
  3. last_run_at and run_count are recorded once the run completes.

No external scheduler (cron job, Celery beat, systemd timer) is required — firing happens automatically inside the app.

Manual tick (admin/debugging)​

POST /api/v1/triggers/cron/tick
Authorization: Bearer <admin-token>

Admins can call this directly to fire all currently-due cron triggers on demand, without waiting for the next automatic tick — useful for testing a new cron trigger immediately after creating it.


Webhook triggers​

Expose a public URL that fires the workflow whenever it receives an HTTP POST.

Creating a webhook trigger​

  1. Open the Triggers panel and click + Webhook.
  2. Give it a name and optionally restrict it to specific source IPs.
  3. Click Create — the response shows:
    • Webhook URL — the public endpoint to POST to
    • Signing Secret — shown once. Store it immediately; it cannot be retrieved again.
Save the signing secret immediately

The signing secret is only ever shown at creation time. If you lose it, delete the trigger and create a new one.

Firing the webhook​

POST /api/v1/triggers/webhook/{token}
Content-Type: application/json
X-Hrida-Signature: sha256=<hmac_hex>
X-Hrida-Timestamp: <unix_seconds>

{
  "input": "New support ticket: customer reports a billing discrepancy"
}
  • The request body's input (or message) field becomes the workflow's input. If the body isn't valid JSON, the raw body is used as the input text.
  • Returns 202 Accepted immediately — the workflow runs asynchronously.
  • If allowed_ips was configured, requests from other source IPs are rejected with 403.
  • A malformed or incorrect X-Hrida-Signature is rejected with 401.
Send X-Hrida-Timestamp for replay protection

Two signing schemes are accepted:

  • Timestamped (recommended) — also send X-Hrida-Timestamp: <unix_seconds> and sign f"{timestamp}.".encode() + body instead of the bare body. A request whose timestamp is more than WEBHOOK_TIMESTAMP_TOLERANCE_SECONDS (default 300s) from the server's clock is rejected with 401 — so a captured, valid (body, signature) pair can't be replayed indefinitely by whoever intercepts it.
  • Legacy (bare body, no timestamp) — still accepted for callers configured before this scheme existed (hmac.new(secret, body, sha256)), but has no replay protection: an intercepted request stays valid forever. Migrate to the timestamped scheme when you can.

If you send X-Hrida-Timestamp, the signature must be computed over the timestamp-prefixed payload — a legacy (bare-body) signature will not validate once a timestamp header is present.

Response​

{
  "accepted": true,
  "trigger_id": "...",
  "workflow_id": "...",
  "run_id": "run_abc123"
}

The run_id is created synchronously before the workflow is queued. Use it to poll GET /api/v1/agent-analytics/workflows/{workflow_id}/runs for the run's status and output — no need to scan the full run list.

This confirms the request was accepted and queued — not that the workflow succeeded.


Incident triggers​

Fire a workflow automatically when a configured incident provider (e.g. Grafana OnCall) reports a state change — an alert firing, being acknowledged, or resolved. Unlike cron and webhook triggers, an incident trigger isn't a separate trigger object — it's a single setting stored directly on the workflow (graph.meta.oncall_trigger), saved immediately when you change it.

Requires a configured incident provider

Incident triggers only fire if at least one incident provider is set up in Admin Panel → Incidents → Providers. See Grafana OnCall Provider for the full setup guide.

Setting an incident trigger​

  1. Open the workflow in the editor and click the Triggers button.
  2. Under Incident Trigger, choose which state change should fire the workflow:
OptionFires when
DisabledNever (default)
On FiringAn incident enters the firing state
On AcknowledgedAn incident is acknowledged
On ResolvedAn incident is resolved
Any state changeAny of the above

The selection saves automatically — there's no separate "Create" step like cron or webhook triggers, and it doesn't appear in the trigger list described under Managing triggers below since it isn't a WorkflowTrigger row.

How firing works​

  1. The incident provider POSTs a webhook to /api/v1/webhooks/incidents/{provider_id} (configured on the provider side — see the provider's own setup doc).
  2. hrida-ai-studio normalizes the payload into an internal event and deduplicates retries — the same provider + incident + state combination within 60 seconds is ignored.
  3. Every published workflow whose Incident Trigger setting matches the event's state (or is set to Any state change) fires — a single incident event can trigger more than one workflow.

Reading incident data inside the workflow​

The fired workflow's input is the incident event serialized as JSON:

{
  "provider_id": "...",
  "provider_type": "grafana_oncall",
  "incident_id": "...",
  "state": "firing",
  "title": "High CPU on web-3",
  "severity": "critical",
  "created_at": "2026-07-17T10:15:00Z",
  "acknowledged_at": null,
  "resolved_at": null,
  "permalink": "https://..."
}
Parsing this inside the workflow

This arrives as the workflow's plain-text input, not under a state._event key the way event subscription payloads do. The sandboxed expression evaluator used by transform/set_state/if_else nodes does not expose a JSON parser, so you can't do json.loads(input) in a node expression. Use an agent node and ask the LLM to read the relevant fields out of the JSON text instead.


Managing triggers​

The Triggers panel lists every cron and webhook trigger for the current workflow:

ActionEffect
Toggle enabledPause/resume firing without deleting the trigger
DeletePermanently remove the trigger. Webhook URLs and cron schedules stop working immediately

Both creating and deleting webhook triggers requires agent_developer role or higher within the workflow's space; deleting requires lifecycle_manager or higher.

Trigger changes are audited

Creating, enabling/disabling, updating, or deleting any trigger is recorded in the parent workflow's Audit Log as an UPDATE entry — including who made the change and, for edits, a before/after diff. Webhook signing secrets are always redacted from the audit record.


Catalog and space scoping​

Both trigger types accept an optional catalog_id and space_id at creation. When set, the fired run uses that catalog/space's credentials and access policies. When omitted, the run falls back to the instance's global LLM credentials.



Event subscription triggers​

Fire a workflow whenever a specific business event arrives on the Event Bus. Unlike webhooks (one sender, one receiver) event subscriptions support fan-out — multiple workflows can subscribe to the same event type and all fire independently.

API only — UI tab coming soon

Event subscription triggers are currently configured via the API. A dedicated Event tab will be added to the Triggers panel in a future release.

Creating an event 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"
  }'
FieldDescription
event_typeEvent type string to subscribe to (e.g. leave_applied, invoice_received)
filter_exprOptional Python expression evaluated against the event. Variables: payload (dict), event (full event). Return True to fire, False to skip.
concurrencyparallel (default) — fire for every matching event. one_per_correlation — skip if a run is already active for the same correlation_id.

Reading event data inside the workflow​

When fired by an event subscription the initial workflow state contains:

{
  "_event": {
    "id":             "evt_abc123",
    "type":           "leave_applied",
    "payload":        { "employee_id": "EMP001", "days": 5 },
    "correlation_id": "EMP001",
    "source":         "hridaone"
  }
}

The workflow input (passed to the first agent node) is the event serialized as JSON. Agent nodes can read state._event.payload directly.

How events are published​

External systems and internal workflows both publish to the same Event Bus:

# External system (API key, no JWT)
POST /api/v1/events/ingest
X-Api-Key: <HRIDA_EVENT_API_KEY>

# Admin / internal (JWT required)
POST /api/v1/events
Authorization: Bearer <admin_token>

# From inside a workflow — use the emit_event built-in tool

See Event-Driven Workflows for the full event model and Saga Orchestration for coordinating multi-step processes.


Trigger comparison​

CronWebhookIncidentEvent Subscription
Trigger sourceTime scheduleExternal HTTP POSTIncident provider state changeBusiness event on Event Bus
Configured inTriggers panel (UI)Triggers panel (UI)Triggers panel (UI)API (UI tab coming soon)
Stored asWorkflowTrigger rowWorkflowTrigger rowgraph.meta.oncall_trigger on the workflowWorkflowTrigger row
Fan-outNoNoYes — one incident can fire multiple matching workflowsYes — multiple workflows per event
PayloadInput template with {date} / {now}Request bodyIncident event as JSON textEvent payload + full event context
Authn/aHMAC-SHA256 signaturen/a (provider webhook auth handled per-provider)API key (external) or JWT (admin)
Saga supportNoNoNoYes — correlation_id links events
Filtern/aIP allowlistIncident state (firing/acknowledged/resolved/any)Python expression on payload

Hrida.ai is proprietary software of Zlabs Innovation. See the license for terms. © 2026 Zlabs Innovation.