Triggers & Scheduling
Gmail triggers, Outlook triggers, webhooks/API input, scheduled (cron) input, polling behavior.
Triggers are input nodes that start process executions. Each trigger type listens for a specific event and feeds data into the process graph when that event occurs.
Trigger Types
| Trigger | Event | Polling | Real-time |
|---|---|---|---|
| Gmail Input | New email in inbox | Yes (configurable interval) | No |
| Outlook Input | New email in inbox | Yes (configurable interval) | No |
| API Input (Webhook) | HTTP POST to endpoint | No | Yes |
| Scheduled Input | Cron expression fires | No | Yes (timer-based) |
Gmail Input Trigger
How It Works
- When the process is started, a Gmail listener begins polling in the background.
- Every
pollingIntervalseconds, it queries Gmail for new emails:in:inbox after:{last_poll_timestamp}. - Matching emails are filtered by sender and subject.
- Each matching email triggers a separate process execution.
Authentication Methods
OAuth
Uses a user's connected Gmail account. The OAuth token is stored encrypted and refreshed automatically.
- Connect your Gmail account under Settings > OAuth Accounts.
- In the input node config, select
authMethod: "oauth"and choose the account.
Service Account
Uses a Google Workspace service account to impersonate a user's mailbox. Requires domain-wide delegation.
- Upload the service account JSON under Settings > Service Accounts.
- Configure allowed impersonation targets.
- In the input node, select
authMethod: "service_account", choose the service account, and specify theimpersonationEmail.
Service accounts can monitor shared inboxes and group addresses without requiring individual user OAuth consent.
Sender Filter
Comma-separated list of allowed sender emails:
john@example.com, jane@example.com
Supports wildcard domain matching:
*@steelcustomer.com
This matches any sender from steelcustomer.com. Multiple patterns can be combined:
*@steelcustomer.com, vip@othercompany.com
Leave empty to accept all senders.
Subject Filter
Comma-separated keywords. An email matches if its subject contains any of the keywords (case-insensitive substring match):
order, quote, steel
This matches subjects like:
- "Steel Order Request" (matches "order" and "steel")
- "Quote needed for project" (matches "quote")
- "Meeting tomorrow" (no match)
Leave empty to accept all subjects.
Polling Behavior
| Behavior | Detail |
|---|---|
| Initial interval | pollingInterval configured (default 30s) |
| Backoff | Exponential when no emails found |
| Max interval | 5 minutes between polls |
| Reset | Returns to initial interval when emails arrive |
| Deduplication | Tracks last poll timestamp to avoid processing the same email twice |
Attachment Handling
- Attachments are downloaded from the Gmail API
- Each attachment is uploaded to cloud storage
- Attachments exceeding
attachmentMaxSizeare skipped - File metadata (name, URL, size) is included in the output
Thread Support
When includeThread: true, the full conversation history is fetched and included as a thread array. Each entry contains the sender, recipients, body, and date of a message in the thread.
Output Shape
{
"id": "msg_abc123",
"thread_id": "thread_xyz789",
"sender": "buyer@example.com",
"recipients": ["orders@yourcompany.com"],
"cc": ["manager@yourcompany.com"],
"subject": "Steel Order Request",
"body": "Hi, we need 5000 lbs of carbon steel...",
"body_html": "<p>Hi, we need 5000 lbs...</p>",
"date": 1712937600,
"receiving_account": "orders@yourcompany.com"
}Files (attachments):
[
{
"name": "spec-sheet.pdf",
"url": "https://storage.example.com/attachments/msg_abc123-0-spec-sheet.pdf",
"size": 245760
}
]Outlook Input Trigger
Structurally identical to Gmail Input but uses the Microsoft Graph API. Supports:
- OAuth authentication with Outlook accounts
- Shared mailbox access
- The same sender/subject filtering
- The same polling behavior
Additional Outlook Features
- Shared Mailbox: Access a shared mailbox by specifying the shared mailbox address
- Folder Selection: Monitor specific folders beyond the inbox
API Input (Webhook) Trigger
How It Works
- When the process is started, a webhook endpoint becomes active.
- External systems send HTTP POST requests to the endpoint.
- Each request triggers a process execution with the POST body as input data.
Webhook URL
POST https://{your-domain}/api/v1/processes/{processId}/webhookAuthentication
The webhook requires an API key:
X-API-Key: your_api_key_here
Or:
Authorization: Bearer your_api_key_here
API keys can be restricted to specific process IDs for security.
Content Types
| Content Type | Handling |
|---|---|
application/json | Parsed as JSON, fields accessible individually |
multipart/form-data | Files uploaded to storage, form fields parsed |
text/plain | Available as raw text |
Schema Validation
If the input node has a schemaId and dataBlockId configured, the incoming payload is validated against the data block's JSON schema. Invalid payloads are rejected with a 400 response.
Synchronous Response (Return to Client)
If the process has an output node of type Return to Client, the webhook behaves synchronously:
- The HTTP request blocks while the process executes.
- When execution completes, the output node's data is returned as the HTTP response.
- If execution fails, an error response is returned.
This enables request-response patterns where external systems call your process like an API.
Output Shape
Whatever the POST body contains:
{
"customer": "John Smith",
"order": {
"steel_type": "carbon",
"weight_lbs": 5000
}
}For multipart uploads, files are available as file references.
Scheduled Input Trigger
How It Works
- When the process is started, a cron scheduler starts.
- The scheduler evaluates the cron expression in the configured timezone.
- When the cron fires, a process execution starts with the configured body data.
Cron Expression Format
Standard 5-field cron:
┌───────── minute (0-59) │ ┌───────── hour (0-23) │ │ ┌───────── day of month (1-31) │ │ │ ┌───────── month (1-12) │ │ │ │ ┌───────── day of week (0-6, Sunday=0) │ │ │ │ │ * * * * *
Common Expressions
| Expression | Schedule |
|---|---|
* * * * * | Every minute |
*/5 * * * * | Every 5 minutes |
*/15 * * * * | Every 15 minutes |
0 * * * * | Every hour on the hour |
0 9 * * * | Daily at 9:00 AM |
0 9 * * 1-5 | Weekdays at 9:00 AM |
0 9,17 * * 1-5 | Weekdays at 9:00 AM and 5:00 PM |
0 0 * * 0 | Weekly on Sunday at midnight |
0 0 1 * * | Monthly on the 1st at midnight |
0 0 1 1 * | Yearly on January 1st at midnight |
AI-Assisted Generation
The UI includes an AI-assisted cron generator. Describe your schedule in plain English:
"Every weekday at 9am Eastern time" → 0 9 * * 1-5 (timezone: America/New_York)
Timezone
Set the timezone field to an IANA timezone string:
America/New_YorkAmerica/ChicagoAmerica/Los_AngelesEurope/LondonAsia/TokyoUTC(default)
Body Data
The body config field contains a default JSON payload sent with each trigger:
{
"report_type": "daily_summary",
"include_metrics": true
}This data becomes the input node's output and is accessible by downstream nodes.
Output Shape
{
"triggered_at": "2026-04-12T09:00:00-04:00",
"cron_expression": "0 9 * * 1-5",
"report_type": "daily_summary",
"include_metrics": true
}Listener Manager
The listener manager coordinates all input node listeners for a process.
Starting Listeners
When POST /processes/start/{processId} is called:
- The listener manager identifies all input nodes in the process.
- For each input node, it starts the appropriate listener (Gmail poller, cron scheduler, etc.).
- Each listener runs in its own concurrent worker with a cancellation context.
- The process
is_runningflag is set totrue.
Stopping Listeners
When POST /processes/stop/{processId} is called:
- All listener workers are cancelled via context.
- In-flight executions continue to completion.
- No new executions are triggered.
- The process
is_runningflag is set tofalse.
Multiple Input Nodes
A process can have multiple input nodes. Each runs its own listener independently:
[Gmail Input A] ──→ [Shared Processing] ──→ [Output] [Gmail Input B] ──↗ [Webhook Input] ──↗
Any of the three triggers can start an execution. The triggered input node is recorded in trigger_node_id on the execution record.
Error Recovery
Trigger Failures
If a listener encounters an error (e.g., Gmail API rate limit, expired OAuth token):
- The listener logs the error and retries on the next poll interval
- Persistent failures don't crash the process -- other listeners continue
- Error details appear in the system logs
Execution Failures
If the execution triggered by a listener fails:
- The failure is recorded in the execution history
- If
maxRetries > 0, the execution is retried - If
error_webhook_urlis set, the error is POSTed to the webhook - The listener continues triggering new executions for subsequent events