Triggers API
A trigger runs an agent task or one of your saved workflows by itself: on a schedule, at an interval, when an outside service calls it with a signed request, when an email arrives or when a web page changes. Each trigger belongs to a workspace and runs as the person who made it. Every route but the webhook address needs a JWT token or an API key and is rate-limited to 60 requests per minute.
Base path: /api/v2/triggers
Workspace
Send the workspace in the x-workspace-id header; you must be a member of it (403 otherwise). Without it your one workspace is used, and a person in several workspaces gets 400 until they send it. A trigger of another workspace answers 404.
Who sees and changes a trigger
- A member sees only the triggers they made; the workspace's owners and admins see every trigger of it.
- Only the person who made a trigger changes it, tests it and sees its webhook secret.
- Owners and admins may switch any trigger off or delete it (403
TRIGGER_CREATOR_ONLYfor anything else). - Someone else's trigger answers a member 404, as a missing ID does.
Kinds of trigger
trigger_type says what fires a trigger, and trigger_config holds its settings.
cron{ expression, timezone }On a schedule: a 5-field cron expression, read in timezone (an IANA name such as America/New_York; UTC when none is given). An unknown timezone is refused.
interval{ seconds }Every so many seconds: from 10 up to 2,592,000 (30 days).
webhook{ secret }When an outside service calls the trigger's address with a signed request (see Calling a webhook trigger). LVNG makes a random secret when you send none; only the trigger's maker sees it.
email{ connection_id, filter }When an email arrives in one of the maker's own connected Gmail or Outlook accounts (connection_id) and matches filter: from, subject_contains and body_contains, at least one of them.
conditionobjectWhen a web page changes: { tool, input, check, contains, poll_interval_seconds }. tool is web_scrape, input.url is the http(s) address of the page, check is content_changed (the default), content_exists or content_contains (with contains, any case), and the page is read every poll_interval_seconds (3600 when not set). The page's text is read through a cache kept 24 hours, so a change is seen within a day.
What a trigger runs
execution_type is agent (an agent does a task) or workflow (a saved workflow runs), and execution_config says what. A workflow run started by a trigger has 15 minutes, or 35 when its workflow has a wait step.
taskstringagent: what the agent does when the trigger fires. What fired it is added to the task.
toolsstring[]agent: the tools it may use, kept to those the workspace allows; with none named it gets the tools chat has. Sending and deleting are refused in a trigger's run.
max_iterationsinteger10agent: the most model turns it takes.
workflow_iduuidworkflow: the saved workflow it runs, one of your organization's. It runs as the trigger's maker, and its runs are listed with the workflow's runs (trigger { type: 'trigger', triggerId }).
inputsobjectworkflow: the inputs each run gets. What fired the trigger is added as trigger_event.
The trigger object
iduuidThe trigger ID.
workspace_iduuidThe workspace it belongs to.
user_iduuidThe person who made it. Its runs act as them.
namestringIts name.
descriptionstring | nullWhat it is for.
enabledbooleanfalse when it is switched off, by a person or after max_errors errors in a row.
trigger_typestringcron, interval, webhook, email or condition.
trigger_configobjectWhat fires it (see Kinds of trigger). A webhook trigger's secret is answered to its maker only.
execution_typestringagent or workflow.
execution_configobjectWhat it runs (see What a trigger runs).
next_run_atstring | nullWhen a cron, interval or web page trigger is next checked or fired.
last_run_atstring | nullWhen it last fired.
run_countintegerHow many times it has fired.
error_countintegerIts errors in a row; a run that succeeds sets it back to 0.
max_errorsinteger5After this many errors in a row it is switched off.
last_resultobject | nullWhat its last run returned.
notify_on_completionbooleanSaved with the trigger; no notification is sent from it yet. Default: true.
notify_channelstringsocketsocket, email or both. Saved with the trigger; no notification is sent from it yet.
schedulenullNot used: a schedule is in trigger_config.
last_fired_atnullNot used: see last_run_at.
created_atstringWhen it was made.
updated_atstringWhen it was last changed.
results_hiddenbooleantrue when its results (last_result) are left out for you. Everyone who sees a trigger (its maker, and the workspace's owners and admins) reads its results, so it is false.
accessobjectWhat you may do with it: { edit, test, secret, disable, delete, results }, each true or false.
Manage triggers
/api/v2/triggersAuthenticatedMake a trigger in the workspace. You are its maker, and its runs act as you. The answer carries the whole trigger, a webhook trigger's secret included: keep it to sign the calls. A workflow trigger needs a workflow of your organization, and an email trigger one of your own connected accounts; a field that cannot be saved answers 400 with a code that names it, and nothing is saved.
Body Parameters
namestringrequiredIts name.
trigger_typestringrequiredcron, interval, webhook, email or condition. type is read too.
trigger_configobjectIts settings (see Kinds of trigger). config is read too.
execution_typestringrequiredagent or workflow.
execution_configobjectWhat it runs (see What a trigger runs).
descriptionstringWhat it is for.
enabledbooleantruefalse to make it switched off.
notify_on_completionbooleanSaved with the trigger. Default: true.
notify_channelstringsocketsocket, email or both. Saved with the trigger.
Request
curl -X POST https://api.lvng.ai/api/v2/triggers \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "x-workspace-id: 9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d" \
-H "Content-Type: application/json" \
-d '{
"name": "New paid order",
"description": "Runs the order follow-up workflow when the shop reports a paid order",
"trigger_type": "webhook",
"execution_type": "workflow",
"execution_config": {
"workflow_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"inputs": { "channel": "orders" }
}
}'Response 201
{
"success": true,
"data": {
"id": "7d9e2f1a-3b4c-4d5e-8f6a-7b8c9d0e1f2a",
"workspace_id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
"user_id": "3c9d2e1f-7a6b-4c5d-9e8f-0a1b2c3d4e5f",
"name": "New paid order",
"description": "Runs the order follow-up workflow when the shop reports a paid order",
"enabled": true,
"trigger_type": "webhook",
"trigger_config": {
"secret": "9f2c7a4e1b8d3f6a0c5e2b7d4a1f8c3e6b9d2a5f0e7c4b1a8d3f6e9c2b5a7d0e"
},
"execution_type": "workflow",
"execution_config": {
"workflow_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"inputs": { "channel": "orders" }
},
"next_run_at": null,
"last_run_at": null,
"run_count": 0,
"error_count": 0,
"max_errors": 5,
"last_result": null,
"notify_on_completion": true,
"notify_channel": "socket",
"schedule": null,
"last_fired_at": null,
"created_at": "2026-03-20T10:00:00.000Z",
"updated_at": "2026-03-20T10:00:00.000Z",
"results_hidden": false,
"access": {
"edit": true,
"test": true,
"secret": true,
"disable": true,
"delete": true,
"results": true
}
}
}/api/v2/triggersAuthenticatedThe triggers of the workspace you see: your own, or every trigger of it for an owner or admin. data and triggers hold the same list.
Request
curl -X GET "https://api.lvng.ai/api/v2/triggers" \
-H "Authorization: Bearer YOUR_API_KEY"Response 200
{
"success": true,
"data": [
{
"id": "8e0f3a2b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
"workspace_id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
"user_id": "3c9d2e1f-7a6b-4c5d-9e8f-0a1b2c3d4e5f",
"name": "Monday customer requests",
"description": null,
"enabled": true,
"trigger_type": "cron",
"trigger_config": { "expression": "0 9 * * 1", "timezone": "America/New_York" },
"execution_type": "agent",
"execution_config": {
"task": "Find last week's notes from customer calls and list the three most common requests.",
"tools": ["search_knowledge"]
},
"next_run_at": "2026-03-23T13:00:00.000Z",
"last_run_at": "2026-03-16T13:00:01.000Z",
"run_count": 4,
"error_count": 0,
"max_errors": 5,
"last_result": {
"text": "The three most common requests last week were faster exports, a shared calendar and SSO.",
"iterations": 3,
"maxIterationsReached": false,
"usage": { "input_tokens": 5120, "output_tokens": 640, "cache_read_input_tokens": 0, "cache_creation_input_tokens": 0 }
},
"notify_on_completion": true,
"notify_channel": "socket",
"schedule": null,
"last_fired_at": null,
"created_at": "2026-02-20T15:00:00.000Z",
"updated_at": "2026-03-16T13:00:31.000Z",
"results_hidden": false,
"access": { "edit": true, "test": true, "secret": true, "disable": true, "delete": true, "results": true }
}
],
"triggers": [
{
"id": "8e0f3a2b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
"workspace_id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
"user_id": "3c9d2e1f-7a6b-4c5d-9e8f-0a1b2c3d4e5f",
"name": "Monday customer requests",
"description": null,
"enabled": true,
"trigger_type": "cron",
"trigger_config": { "expression": "0 9 * * 1", "timezone": "America/New_York" },
"execution_type": "agent",
"execution_config": {
"task": "Find last week's notes from customer calls and list the three most common requests.",
"tools": ["search_knowledge"]
},
"next_run_at": "2026-03-23T13:00:00.000Z",
"last_run_at": "2026-03-16T13:00:01.000Z",
"run_count": 4,
"error_count": 0,
"max_errors": 5,
"last_result": {
"text": "The three most common requests last week were faster exports, a shared calendar and SSO.",
"iterations": 3,
"maxIterationsReached": false,
"usage": { "input_tokens": 5120, "output_tokens": 640, "cache_read_input_tokens": 0, "cache_creation_input_tokens": 0 }
},
"notify_on_completion": true,
"notify_channel": "socket",
"schedule": null,
"last_fired_at": null,
"created_at": "2026-02-20T15:00:00.000Z",
"updated_at": "2026-03-16T13:00:31.000Z",
"results_hidden": false,
"access": { "edit": true, "test": true, "secret": true, "disable": true, "delete": true, "results": true }
}
]
}/api/v2/triggers/:idAuthenticatedOne trigger. In the example a workspace admin reads a webhook trigger a colleague made: the secret is left out, and access says the admin may only switch it off or delete it.
Path Parameters
iduuidrequiredThe trigger ID.
Request
curl -X GET "https://api.lvng.ai/api/v2/triggers/{id}" \
-H "Authorization: Bearer YOUR_API_KEY"Response 200
{
"success": true,
"data": {
"id": "7d9e2f1a-3b4c-4d5e-8f6a-7b8c9d0e1f2a",
"workspace_id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
"user_id": "6b7c8d9e-0f1a-4b2c-8d3e-4f5a6b7c8d9e",
"name": "New paid order",
"description": "Runs the order follow-up workflow when the shop reports a paid order",
"enabled": true,
"trigger_type": "webhook",
"trigger_config": {},
"execution_type": "workflow",
"execution_config": {
"workflow_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"inputs": { "channel": "orders" }
},
"next_run_at": null,
"last_run_at": "2026-03-21T16:42:10.000Z",
"run_count": 12,
"error_count": 0,
"max_errors": 5,
"last_result": {
"text": "The workflow \"Order follow-up\" ran and completed.",
"workflow_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"workflow_run": {
"executionId": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a",
"status": "completed",
"outputs": { "follow_up_sent": true },
"resultId": null,
"duration": 8120
}
},
"notify_on_completion": true,
"notify_channel": "socket",
"schedule": null,
"last_fired_at": null,
"created_at": "2026-03-20T10:00:00.000Z",
"updated_at": "2026-03-21T16:42:18.000Z",
"results_hidden": false,
"access": {
"edit": false,
"test": false,
"secret": false,
"disable": true,
"delete": true,
"results": true
}
}
}/api/v2/triggers/:idAuthenticatedChange a trigger. Its maker may change any of the fields below; an owner or admin who did not make it may only send { enabled: false } to switch it off (403 TRIGGER_CREATOR_ONLY otherwise). A new trigger_config is checked as at create. Answers the trigger as you read it.
Path Parameters
iduuidrequiredThe trigger ID.
Body Parameters
namestringA new name.
descriptionstringA new description.
enabledbooleanSwitch it on or off.
trigger_typestringA new kind.
trigger_configobjectNew settings for its kind.
execution_typestringagent or workflow.
execution_configobjectWhat it runs.
max_errorsintegerErrors in a row before it is switched off: 1 or more.
notify_on_completionbooleanSaved with the trigger.
notify_channelstringsocket, email or both.
Request
curl -X PATCH https://api.lvng.ai/api/v2/triggers/8e0f3a2b-4c5d-4e6f-9a7b-8c9d0e1f2a3b \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "x-workspace-id: 9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d" \
-H "Content-Type: application/json" \
-d '{
"trigger_config": { "expression": "0 8 * * 1-5", "timezone": "America/New_York" }
}'Response 200
{
"success": true,
"data": {
"id": "8e0f3a2b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
"workspace_id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
"user_id": "3c9d2e1f-7a6b-4c5d-9e8f-0a1b2c3d4e5f",
"name": "Monday customer requests",
"description": null,
"enabled": true,
"trigger_type": "cron",
"trigger_config": { "expression": "0 8 * * 1-5", "timezone": "America/New_York" },
"execution_type": "agent",
"execution_config": {
"task": "Find last week's notes from customer calls and list the three most common requests.",
"tools": ["search_knowledge"]
},
"next_run_at": "2026-03-23T12:00:00.000Z",
"last_run_at": "2026-03-16T13:00:01.000Z",
"run_count": 4,
"error_count": 0,
"max_errors": 5,
"last_result": null,
"notify_on_completion": true,
"notify_channel": "socket",
"schedule": null,
"last_fired_at": null,
"created_at": "2026-02-20T15:00:00.000Z",
"updated_at": "2026-03-20T11:00:00.000Z",
"results_hidden": false,
"access": { "edit": true, "test": true, "secret": true, "disable": true, "delete": true, "results": true }
}
}/api/v2/triggers/:idAuthenticatedDelete a trigger. Its maker may, and so may the workspace's owners and admins.
Path Parameters
iduuidrequiredThe trigger ID.
Request
curl -X DELETE "https://api.lvng.ai/api/v2/triggers/{id}" \
-H "Authorization: Bearer YOUR_API_KEY"Response 200
{
"success": true
}Test and history
/api/v2/triggers/:id/testAuthenticatedFire the trigger now. This is a real run, as its maker, with trigger_event { type: 'test' }; only the trigger's maker may start one (403 TRIGGER_CREATOR_ONLY).
Path Parameters
iduuidrequiredThe trigger ID.
Request
curl -X POST https://api.lvng.ai/api/v2/triggers/8e0f3a2b-4c5d-4e6f-9a7b-8c9d0e1f2a3b/test \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "x-workspace-id: 9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d"Response 200
{
"success": true,
"message": "Test execution started",
"data": {
"executionId": "4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b"
}
}/api/v2/triggers/:id/historyAuthenticatedThe trigger's runs, newest first, with their results.
Path Parameters
iduuidrequiredThe trigger ID.
Query Parameters
limitinteger20How many runs, up to 100.
Request
curl -X GET "https://api.lvng.ai/api/v2/triggers/{id}/history" \
-H "Authorization: Bearer YOUR_API_KEY"Response 200
{
"success": true,
"data": [
{
"id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
"trigger_id": "8e0f3a2b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
"workspace_id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
"user_id": "3c9d2e1f-7a6b-4c5d-9e8f-0a1b2c3d4e5f",
"execution_type": "agent",
"task": "Find last week's notes from customer calls and list the three most common requests.",
"workflow_id": null,
"status": "completed",
"started_at": "2026-03-16T13:00:02.000Z",
"completed_at": "2026-03-16T13:00:31.000Z",
"created_at": "2026-03-16T13:00:01.000Z",
"iterations": 3,
"result": {
"text": "The three most common requests last week were faster exports, a shared calendar and SSO.",
"iterations": 3,
"maxIterationsReached": false,
"usage": { "input_tokens": 5120, "output_tokens": 640, "cache_read_input_tokens": 0, "cache_creation_input_tokens": 0 }
},
"error": null,
"tools_used": ["search_knowledge"],
"cost_usd": 0.0251,
"trigger_event": {
"type": "cron",
"triggerId": "8e0f3a2b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
"firedAt": "2026-03-16T13:00:00.000Z"
},
"error_class": null,
"results_hidden": false
}
]
}The run object
iduuidThe run ID (the executionId a test or a webhook call answers).
trigger_iduuidThe trigger that fired.
workspace_iduuidThe trigger's workspace.
user_iduuidThe person the run acted as: the trigger's maker.
execution_typestringagent or workflow.
taskstringThe agent's task, or the trigger's name for a workflow.
workflow_iduuid | nullThe workflow a workflow trigger ran.
statusstringpending, running, completed, failed or cancelled.
started_atstring | nullWhen it started.
completed_atstring | nullWhen it ended.
created_atstringWhen the trigger fired.
iterationsintegerThe model turns an agent run took.
resultobject | nullWhat it returned: for an agent, text, iterations, maxIterationsReached and usage; for a workflow, text, workflow_id and workflow_run.
errorstring | nullWhy a failed run failed.
tools_usedstring[]The tools an agent run used.
cost_usdnumber | nullThe run's own model spend, in US dollars.
trigger_eventobjectWhat fired it, with its type: cron, interval, webhook (with the call's body as payload), email, condition or test.
error_classstring | nullfailed for a failed run; otherwise null.
results_hiddenbooleantrue when result, error, tools_used, cost_usd and trigger_event are left out for you (trigger_event then only says its type). false for everyone who sees the trigger.
Calling a webhook trigger
A webhook trigger fires when an outside service sends a POST to its address. The call needs no LVNG sign-in: it is accepted only when it is signed with the trigger's secret.
- Make a trigger with
trigger_type: "webhook", and keeptrigger_config.secretfrom the answer (only you, its maker, can read it again). - Send the body you want the run to get to
https://api.lvng.ai/api/v2/triggers/{id}/webhook. - Sign the exact bytes of that body: an HMAC-SHA256 made with the secret, in lowercase hex, sent in the
x-webhook-signatureheader (asha256=prefix is accepted, and so are thex-hub-signature-256andx-signatureheaders).
JSON and form bodies reach the run parsed, any other body as text (up to 1 MB). The run gets the call as trigger_event: type webhook, the body as payload, its content type and user agent, and when it arrived. A workflow trigger's run gets it among its inputs; an agent trigger's task gets it added.
/api/v2/triggers/:id/webhookFire a webhook trigger from an outside service. No sign-in: the call is accepted only with a valid signature of its exact body, and it starts one run of the trigger as its maker. Limited to 30 calls a minute per trigger and 60 a minute per address.
Path Parameters
iduuidrequiredThe trigger ID.
Request
BODY='{"order_id":"A-1042","status":"paid"}'
SIGNATURE=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | sed 's/^.* //')
curl -X POST https://api.lvng.ai/api/v2/triggers/7d9e2f1a-3b4c-4d5e-8f6a-7b8c9d0e1f2a/webhook \
-H "Content-Type: application/json" \
-H "x-webhook-signature: sha256=$SIGNATURE" \
--data-raw "$BODY"Response 200
{
"success": true,
"message": "Webhook received, execution started",
"data": {
"executionId": "6f7a8b9c-0d1e-4f2a-9b3c-4d5e6f7a8b9c"
}
}Other answers
401WEBHOOK_NOT_ACCEPTED— the same answer for an ID no trigger has, a trigger of another kind, a switched-off trigger, and a missing or wrong signature. Nothing ran.403— the webhook trigger has no secret; set one to use this address. Nothing ran.429WEBHOOK_RATE_LIMITED— too many calls; wait the seconds in theRetry-Afterheader.503— the trigger could not be read or started just now. Nothing ran; send the call again.
{
"success": false,
"code": "WEBHOOK_NOT_ACCEPTED",
"error": "This webhook call was not accepted. Check the trigger's URL, and sign the exact request body with its secret: an HMAC-SHA256 in hex, sent in the x-webhook-signature header."
}