Triggers
A trigger is what starts a run. This page covers the eight trigger types, the data each one hands your workflow, which version of your workflow a trigger fires, and the limits and safeguards around them. Read it when you wire an entry point or when a trigger does not fire.
The eight trigger types
A workflow can carry several triggers. Each one starts its own graph and keeps its own history of fires. Every trigger output is available downstream as {{trigger:<label>.output.<field>}}, where <label> is the normalized trigger label. A trigger node has no inputs: it is the entry point of the graph.
| Trigger | Fires when | Key outputs |
|---|---|---|
| Webhook | an HTTP request reaches the webhook URL. | payload, headers, query, method |
| Scheduler | a cron time is reached, in the timezone you pick. | execution_count, next_execution |
| Manual | someone runs the workflow by hand. | triggered_at, triggered_by |
| Chat | a message arrives, optionally only when it matches a filter. | message, extracted_message, matched |
| Form | someone submits the form. | form_data, submission_id, one field per input |
| Tables | a row is created, updated, or deleted in a table. | row, previous_row, event_type |
| Workflows | another workflow finishes a cycle without a failed step. | parentStatus, result |
| Error | a cycle of another workflow has a failed step. | status, errorMessage, failedSteps |
Reference any of them by the trigger's label:
{{trigger:webhook.output.payload}} → the JSON body a webhook received
{{trigger:contact_form.output.email}} → one field of a form submission
{{trigger:new_orders.output.row.status}} → a column from the changed table row
{{trigger:on_failure.output.errorMessage}} → why the upstream workflow failedWhen an agent adds a trigger through the builder, the accepted type values are manual, chat, webhook, schedule, table, datasource, workflow, form, and error. table is an alias of datasource. Trigger labels must be unique within a workflow, and a trigger label cannot collide with another node's label after normalization.
Epochs: one run, many fires
Every trigger type is reusable. A fire does not start a new run: it opens a new epoch on the workflow's live run, which then rests in WAITING_TRIGGER until the next fire. Each epoch keeps its own results, so you can browse every fire of a schedule or every call of a webhook on the same run. Epochs are numbered per trigger. See Runs & execution for how to read them.
Which version a trigger fires
Every save records a new plan version. Pinning a version, labelled Set as production in the version history, tells LiveContext which version the outside world talks to. There is no automatic pin.
| Fire | Version it runs | Without a pinned version |
|---|---|---|
| Run from the editor (Manual, or testing a chat or form in the builder) | The version open in the editor | Works. The fire reuses the live run of that version when there is one, and opens a new epoch on it. |
| Webhook, Scheduler, Tables, Workflows | The pinned version | Refused. A webhook answers 409 (not_active), a schedule is not armed, a table event is skipped. |
| The public chat or form URL | The pinned version, read when each message or submission arrives | Refused. The message or submission does not start anything. |
| Error | The handler workflow’s newest live run (of the pinned version, when one is pinned) | Works. The pin is optional for an error handler, it only needs a live run. |
Pin a version
- Open the version historyOpen the workflow in the builder and open its version history.
- Choose Set as productionPick the version and choose Set as production. If you have unsaved changes, Save & set as production saves them as a new version first.
- Check the triggersThe Webhook, Scheduler, Tables, Chat, and Form triggers are re-synced to the pinned plan straight away; a Workflows trigger reads the pinned version each time it fires. Open Public access or the Agenda to see them armed.
You can pin a version that has never run. If no run exists at that version, pinning creates the production run itself. Nothing executes and no credits are used; the run simply waits for its first fire. A plan with no trigger is pinned without a run.
Remove from productionclears the pin and suspends the workflow's production triggers rather than deleting them. Pinning again arms them again. Moving production to another version switches every future execution to it; a chat conversation in progress runs the new version from its very next message.
When the production run ends
If the production run ends as failed, cancelled, or timed out, LiveContext points production at the newest other live run of the pinned version (or, failing that, a completed one). It never creates a new run for you. When no such run exists, production triggers skip until you pin again (which provisions a run) or reactivate the run from the run panel.
Webhook
A webhook trigger listens on a URL of the form {base}/webhook/{token}. Accepted methods are GET, POST, PUT, PATCH, and DELETE; a webhook accepts exactly one, and the default is POST.
| Auth type | How it works |
|---|---|
| none | No verification: anyone with the URL can call it. |
| basic | HTTP Basic authentication with a username and password. |
| header | A header name and value you choose (API-key style). |
| jwt | A bearer JWT verified with an HMAC secret: HS256 by default, or HS384 or HS512. |
Authentication fails closed: a request that does not pass the configured check, or a webhook configured with an auth type the platform does not recognize, gets 401.
| Field | Notes |
|---|---|
| payload | The JSON body as an object. Query parameters are merged in for any key the body does not already have. For a GET request, the query parameters are the payload. |
| headers | All request headers. |
| query | The query string parameters (alias queryParams). |
| method | The HTTP method used. |
| triggered_at | ISO timestamp (alias triggeredAt). |
| triggered_by | Display name of the workflow owner, empty when the request is unauthenticated. |
Two metadata fields, _webhookMethod and _webhookTimestamp, are added to the payload. The sync query parameter is removed from it.
| Status | Meaning |
|---|---|
| 202 | Accepted: the fire was queued. |
| 200 | Completed: a synchronous call finished and returns the response. |
| 401 | Authentication failed. |
| 402 | The workspace is out of credits. |
| 404 | No webhook exists for this token (for example after the token was regenerated). |
| 405 | The request used a different HTTP method than the webhook accepts. |
| 409 | Not active: the workflow has no pinned version, its production run has ended (for example it was cancelled), or the webhook is inactive. |
| 429 | Rate limited. Retry after the delay in the Retry-After header. |
When an agent builds a webhook trigger, the webhook endpoint is created at once, so the URL works before the workflow is even saved. Its token is kept across re-pins, so the URL does not change as you iterate. It only changes when you regenerate the token from Public access, where you can also read the call history. The full HTTP surface, including the Respond to Webhook node, is in REST API & webhooks.
Scheduler
| Parameter | Default | Notes |
|---|---|---|
| schedule | 0 * * * * (hourly) | Standard 5-field cron: minute, hour, day of month, month, day of week. |
| timezone | UTC | Any IANA zone, for example America/New_York. |
| enabled | true | Set false to keep the trigger defined but idle. |
| maxExecutions | unlimited | Optional cap on the number of fires (alias max_executions). |
Outputs: triggered_at, execution_count (starts at 1, alias executionCount), next_execution (aliases nextExecution and nextScheduled), and triggered_by (the workflow owner's display name). A schedule is armed only while the workflow has a pinned version. To see upcoming fires, move one, or run one early, use the Agenda.
Manual
No parameters. Running the workflow from the editor fires it. The fire reuses the live run of the same version when one exists and opens a new epoch on it; a new run is created only for a new version or when no live run exists. Outputs: triggered_at and triggered_by (alias user), the display name of whoever ran it (an empty string if unknown). Extra data_inputs passed when an agent executes the workflow are added as top-level fields.
Chat
A chat trigger fires on incoming messages. With no filter it fires on every message.
| Field | Notes |
|---|---|
| message | The raw message text. |
| extracted_message | The message with the matched prefix or suffix trimmed (alias extractedMessage). |
| conversation_id | Alias conversationId. |
| attachments | An array of file references. |
| matched | Boolean: whether the optional chatMatch filter matched. |
| match_type, match_value | Which rule matched and against what value (aliases matchType, matchValue). |
| triggered_at, triggered_by | ISO timestamp and the display name of the sender. |
Filter which messages fire the run
An optional chatMatch block decides which messages fire the trigger.
| Match type | Fires when | Needs a value? |
|---|---|---|
| ANY | every message (the default). | No |
| STARTS_WITH | the message starts with the value. | Yes |
| ENDS_WITH | the message ends with the value. | Yes |
| CONTAINS | the message contains the value anywhere. | Yes |
| EQUALS | the message equals the value exactly. | Yes |
| REGEX | the value, as a regular expression, matches anywhere in the message. | Yes |
Options: caseSensitive (default false), trimPrefix (default true, for STARTS_WITH) and trimSuffix (default true, for ENDS_WITH). With trimming on, extracted_message drops the matched command token. REGEX matches a substring, not the whole string.
A chat trigger built by an agent creates its public chat endpoint at once. You manage the endpoint and its share links in Public access.
Form
The form builder offers 17 field types:
| Group | Types |
|---|---|
| Text | text, email, password, textarea, url, tel, hidden |
| Numbers and dates | number, date, datetime, time |
| Choices | select, multiselect, checkbox, checkboxGroup, radio |
| Files | file |
| Accepted aliases | string and str become text, int and integer become number, bool and boolean become checkbox, phone becomes tel |
select, multiselect, radio, and checkboxGroup need an options list, either plain strings or {label, value} pairs.
Outputs: submission_id, submitted_at (alias submittedAt), form_data (every field in one object, alias formData), triggered_at, triggered_by, plus one output per field, named after the field's name. The hosted form page and its share links are managed in Public access.
Tables (row changes)
The Tables trigger fires on changes to one of your tables. One row-level event fires once.
Configuration: table_id (or datasource_id, required), event_types to choose which changes fire (row_created, row_updated, row_deleted; omit it for all three), and an optional filter ({column, operator, value}) so only matching rows fire.
Filter operators: = (or ==, eq), != (or neq), > (gt), >= (gte), < (lt), <= (lte), in, not_in, contains, starts_with, ends_with, is_null, and is_not_null. The last two take no value; every other operator needs one.
| Field | Notes |
|---|---|
| row | The row after the change, or its last known state for row_deleted. |
| previous_row | The row before the change. Filled only for row_updated, null otherwise. |
| event_type | row_created, row_updated, or row_deleted. |
| row_id | The primary key of the affected row. |
| datasource_id | Which table. |
| triggered_at | ISO timestamp, right after the change was saved. |
| triggered_by | Alias triggeredBy, empty by default. |
When an agent executes the workflow without a real row event (a batch scan), the trigger emits data (an array of {id, data} rows) and count instead. Put a Split over output.data to process every row. See Workflows.
Workflows (chaining)
Starts this workflow when a parent workflow finishes. The only setting is workflow_id, the parent's id (required).
- For a parent with a reusable trigger (the usual case), the chain fires after every cycle of the parent that had no failed step.
- For a single-shot parent run, it fires when that run ends
COMPLETED.
It never fires on a failure. To react to one, use the Error trigger below.
| Field | Notes |
|---|---|
| triggered_at, triggered_by | Timestamp and identity. |
| parentWorkflowId | Alias parent_workflow_id. |
| parentRunId | Alias parent_run_id. |
| parentStatus | Alias parent_status. |
| result | The parent’s outputs as an object. They are also copied to the top level. |
| parentStatistics | Alias parent_statistics. |
Read the parent's outputs with {{trigger:on_done.output.result}} or directly with {{trigger:on_done.output.<parent field>}}. There is no parent_outputs field.
Error
Starts an error-handler workflow when a parent workflow has a step fail. The only setting is parent_workflow_id.
- For a parent with a reusable trigger, it fires on any cycle with a failed step, whatever the run's own status.
- For a single-shot parent run, it fires when that run ends
FAILED(or with the olderPARTIAL_SUCCESSstatus).
| Field | Notes |
|---|---|
| parentWorkflowId, parentRunId | Which parent workflow and run failed. |
| status | The parent run’s status when the failure was reported. |
| errorMessage | What went wrong. |
| triggered_at | ISO timestamp (alias triggeredAt). |
| failedSteps, completedSteps, totalSteps, skippedSteps | Step counts, present when the parent recorded them. |
| triggered_by | Identity field. |
Limits and safeguards
Endpoint limits per plan
On the cloud, the number of webhooks, schedules, chat endpoints, and form endpoints you can hold depends on your plan. Each kind has its own quota, shown as a gauge on its tab in Public access. Creating one past the limit is refused.
| Plan | Per kind |
|---|---|
| Free | 3 |
| Starter | 10 |
| Pro | 50 |
| Team, Enterprise | 100 |
| Self-hosted Community Edition | Unlimited |
Chains and error handlers
- A Workflows or Error trigger is skipped when the target workflow already has 5 runs executing at once.
- Chains and error handlers never fire across workspaces.
Credits and spending caps
When the workspace is out of credits, a fire is not silently dropped: the trigger node fails with the error code CREDIT_EXHAUSTED and every downstream node is skipped. The run stays reusable, so the next fire after a top-up works with no action from you. A webhook caller may receive 402.
A workflow or application can also carry a Cost budget (set in the Advanced section when you create or edit it), which Resetsevery month, every week, or never. It counts agent spend on every run except a test fire from the builder. Once the period's spend reaches it, no new epoch opens until the allowance starts again. See Plans & billing.
Troubleshooting
| Symptom | What to check |
|---|---|
| A webhook answers 409 | Set a version as production. If one is pinned, the production run has ended: reactivate it from the run panel, or pin again. |
| A webhook answers 404 | The token was regenerated or the webhook deleted. Copy the current URL from Public access. |
| A webhook answers 401 | The caller does not send the configured Basic, header, or JWT credentials. |
| A schedule never fires | The workflow is not pinned, the schedule is suspended (for example after the run was cancelled), or it reached maxExecutions. Check it in the Agenda. |
| The public chat or form does nothing | The workflow has no pinned version. |
| Every run fails at the trigger | Look for CREDIT_EXHAUSTED on the trigger node, or a spending cap reached on the run. |
| An error handler never runs | The handler has no live run. Pin it or execute it once. |
| A chat trigger fires on every message | Check the chatMatch type spelling: an unknown type falls back to ANY. |