Skip to main content

Triggers

Every workflow has exactly one trigger (dsl.Trigger), defining how an execution starts. The trigger's type and config are stored on the workflow DSL; OrcFlows wires up the corresponding webhook route, Temporal Schedule, or poller automatically when the workflow is enabled.

"trigger": {
"type": "schedule",
"config": { "cron": "0 9 * * 1-5", "timezone": "America/New_York" }
}

HTTP / Webhook

type: "http" — the workflow is triggered by an HTTP request to:

POST https://your-instance/webhooks/{workflowId}
GET https://your-instance/webhooks/{workflowId} (ping/test)
  • The request body, headers, and query params are available to steps as {{trigger.body...}}, {{trigger.headers...}}, {{trigger.query...}}.
  • If the workflow has a webhook_api_key set, requests must include X-API-Key: <key> (manage via /api/v1/workflows/{id}/api-keys).
  • Synchronous mode: POST /webhooks/{workflowId}/sync blocks until the workflow completes and returns its final output directly — useful for request/response integrations. Use a webhook_response node to shape that response.

Manual

type: "manual" — only runs when explicitly triggered from the dashboard or POST /api/v1/workflows/{id}/trigger. Combine with input_schema to render a form for ad-hoc runs.

Schedule (cron)

type: "cron" (config key schedule in the UI) — runs on a cron expression via a Temporal Schedule:

"trigger": { "type": "cron", "config": { "cron": "0 9 * * 1-5", "timezone": "America/New_York" } }
  • Standard 5-field cron syntax, optional IANA timezone (defaults to UTC).
  • Enabling/disabling the workflow pauses/unpauses the underlying Temporal Schedule (PauseSchedule).
  • GET /api/v1/workflows/{id}/schedule returns next/recent fire times and fire count.
  • You can fire it immediately regardless of the cron via the schedule's "Run now" action (TriggerScheduleNow).

Event triggers (pollers)

type: "event" with a config.source covers a family of polling triggers — a Temporal Schedule periodically checks an external service for new items and starts a workflow execution per item found:

SourceWhat it polls for
emailNew emails matching filters (from, to, cc, subject, date) via IMAP.
telegramNew messages, edited messages, callback queries, channel posts, inline queries via Telegram's getUpdates long-poll.
slackNew messages, mentions, reactions, channels, members, DMs, thread replies in connected Slack workspaces.
airtableNew/updated records in a base/table.
typeformNew form responses.
notionNew/updated pages in a database.
google-sheetsNew/updated rows in a spreadsheet.

Each poller has its own Temporal Schedule (e.g. emailPollerScheduleID), so it can be paused/resumed independently when the workflow is enabled/disabled, and inspected via GET /api/v1/workflows/{id}/schedule.

Channel-specific webhooks

Some channels need their own webhook handling because the provider has a custom verification handshake:

  • WhatsApp: GET /webhooks/whatsapp/{workflowId} handles Meta's hub.challenge verification; POST /webhooks/whatsapp/{workflowId} receives inbound messages (Meta Cloud API or Twilio).
  • Instagram: same pattern — GET/POST /webhooks/instagram/{workflowId}.

LiveKit (real-time voice)

type: "livekit" — the workflow is started by a LiveKit room/session event delivered to POST /webhooks/livekit (JWT-signature-verified). Used for voice agents and cold-calling flows — see LiveKit & Voice Agents.

Public API run

Independent of the configured trigger, any workflow can be invoked via the generic public endpoint:

POST /run/{workflowId}

protected by a workflow-scoped API key (see Deploying Workflows).

Enabling/disabling

PUT /api/v1/workflows/{id}/enable and .../disable turn the trigger on/off:

  • For http/manual triggers, this just toggles whether /webhooks/{id} accepts requests.
  • For cron and event/poller triggers, this pauses/unpauses the corresponding Temporal Schedule — so disabling a workflow stops new executions without losing the schedule's history.

Next