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_ONLY for 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.

conditionobject

When 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.

taskstring

agent: 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_iterationsinteger
Default: 10

agent: the most model turns it takes.

workflow_iduuid

workflow: 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 }).

inputsobject

workflow: the inputs each run gets. What fired the trigger is added as trigger_event.

The trigger object

iduuid

The trigger ID.

workspace_iduuid

The workspace it belongs to.

user_iduuid

The person who made it. Its runs act as them.

namestring

Its name.

descriptionstring | null

What it is for.

enabledboolean

false when it is switched off, by a person or after max_errors errors in a row.

trigger_typestring

cron, interval, webhook, email or condition.

trigger_configobject

What fires it (see Kinds of trigger). A webhook trigger's secret is answered to its maker only.

execution_typestring

agent or workflow.

execution_configobject

What it runs (see What a trigger runs).

next_run_atstring | null

When a cron, interval or web page trigger is next checked or fired.

last_run_atstring | null

When it last fired.

run_countinteger

How many times it has fired.

error_countinteger

Its errors in a row; a run that succeeds sets it back to 0.

max_errorsinteger
Default: 5

After this many errors in a row it is switched off.

last_resultobject | null

What its last run returned.

notify_on_completionboolean

Saved with the trigger; no notification is sent from it yet. Default: true.

notify_channelstring
Default: socket

socket, email or both. Saved with the trigger; no notification is sent from it yet.

schedulenull

Not used: a schedule is in trigger_config.

last_fired_atnull

Not used: see last_run_at.

created_atstring

When it was made.

updated_atstring

When it was last changed.

results_hiddenboolean

true 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.

accessobject

What you may do with it: { edit, test, secret, disable, delete, results }, each true or false.

Manage triggers

POST/api/v2/triggersAuthenticated

Make 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

namestringrequired

Its name.

trigger_typestringrequired

cron, interval, webhook, email or condition. type is read too.

trigger_configobject

Its settings (see Kinds of trigger). config is read too.

execution_typestringrequired

agent or workflow.

execution_configobject

What it runs (see What a trigger runs).

descriptionstring

What it is for.

enabledboolean
Default: true

false to make it switched off.

notify_on_completionboolean

Saved with the trigger. Default: true.

notify_channelstring
Default: socket

socket, email or both. Saved with the trigger.

Request

cURL
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
    }
  }
}
GET/api/v2/triggersAuthenticated

The 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
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 }
    }
  ]
}
GET/api/v2/triggers/:idAuthenticated

One 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

iduuidrequired

The trigger ID.

Request

cURL
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
    }
  }
}
PATCH/api/v2/triggers/:idAuthenticated

Change 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

iduuidrequired

The trigger ID.

Body Parameters

namestring

A new name.

descriptionstring

A new description.

enabledboolean

Switch it on or off.

trigger_typestring

A new kind.

trigger_configobject

New settings for its kind.

execution_typestring

agent or workflow.

execution_configobject

What it runs.

max_errorsinteger

Errors in a row before it is switched off: 1 or more.

notify_on_completionboolean

Saved with the trigger.

notify_channelstring

socket, email or both.

Request

cURL
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 }
  }
}
DELETE/api/v2/triggers/:idAuthenticated

Delete a trigger. Its maker may, and so may the workspace's owners and admins.

Path Parameters

iduuidrequired

The trigger ID.

Request

cURL
curl -X DELETE "https://api.lvng.ai/api/v2/triggers/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response 200

{
  "success": true
}

Test and history

POST/api/v2/triggers/:id/testAuthenticated

Fire 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

iduuidrequired

The trigger ID.

Request

cURL
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"
  }
}
GET/api/v2/triggers/:id/historyAuthenticated

The trigger's runs, newest first, with their results.

Path Parameters

iduuidrequired

The trigger ID.

Query Parameters

limitinteger
Default: 20

How many runs, up to 100.

Request

cURL
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

iduuid

The run ID (the executionId a test or a webhook call answers).

trigger_iduuid

The trigger that fired.

workspace_iduuid

The trigger's workspace.

user_iduuid

The person the run acted as: the trigger's maker.

execution_typestring

agent or workflow.

taskstring

The agent's task, or the trigger's name for a workflow.

workflow_iduuid | null

The workflow a workflow trigger ran.

statusstring

pending, running, completed, failed or cancelled.

started_atstring | null

When it started.

completed_atstring | null

When it ended.

created_atstring

When the trigger fired.

iterationsinteger

The model turns an agent run took.

resultobject | null

What it returned: for an agent, text, iterations, maxIterationsReached and usage; for a workflow, text, workflow_id and workflow_run.

errorstring | null

Why a failed run failed.

tools_usedstring[]

The tools an agent run used.

cost_usdnumber | null

The run's own model spend, in US dollars.

trigger_eventobject

What fired it, with its type: cron, interval, webhook (with the call's body as payload), email, condition or test.

error_classstring | null

failed for a failed run; otherwise null.

results_hiddenboolean

true 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.

  1. Make a trigger with trigger_type: "webhook", and keeptrigger_config.secret from the answer (only you, its maker, can read it again).
  2. Send the body you want the run to get to https://api.lvng.ai/api/v2/triggers/{id}/webhook.
  3. Sign the exact bytes of that body: an HMAC-SHA256 made with the secret, in lowercase hex, sent in the x-webhook-signature header (a sha256= prefix is accepted, and so are thex-hub-signature-256 andx-signature headers).

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.

POST/api/v2/triggers/:id/webhook

Fire 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

iduuidrequired

The trigger ID.

Request

cURL
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

  • 401 WEBHOOK_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.
  • 429 WEBHOOK_RATE_LIMITED — too many calls; wait the seconds in the Retry-After header.
  • 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."
}