How a trigger fires
lua triggers create --name order-created registers a trigger on the agent and prints its URL, which lua triggers list prints again; these pages show it as <<TRIGGER_URL>>. The URL ends in a token, and that token is the credential: anyone with the URL can fire the trigger, and lua triggers rotate-token --trigger order-created issues a new token and invalidates the old URL at once. A POST to the URL with no code on your side turns the request body into a message to the agent, prefixed by the --instruction you gave at creation, and the agent responds as it would to an end user. Bodies over 50,000 characters are truncated before they reach the model.
When the event needs checking or shaping, define the trigger in code with defineTrigger and register it on the agent’s triggers array. It has no execute function; instead it has up to four slots that run in order on every delivery. verify returns false to reject the request with 401, the place for a vendor signature check over ctx.rawBody. filter returns false to accept the request with 200 and do nothing, for events you don’t care about. transform turns the event into what the agent receives: a string message, a full invocation you control, or { startWorkflow: { name, input, idempotencyKey } } to start a workflow run instead of a model turn. tool names one skill tool to run directly with no model turn at all; when both tool and transform are declared, tool wins.
src/triggers/stripe-payments.trigger.ts
lua push trigger --name stripe-payments and made live with lua deploy trigger --name stripe-payments --set-version latest --force; the trigger record and its URL are managed separately with lua triggers.
A trigger fires on behalf of the person who created it: the resulting agent turn runs as that user, with that user’s tools and data, unless transform names another userId. A { startWorkflow } result is the exception: it starts the run and fires no agent turn at all. Every delivery is recorded; lua triggers logs --trigger order-created lists executions with their status (accepted, completed, failed, rejected_unverified, skipped_filtered, skipped_inactive, started_workflow, skipped_overlap), duration, payload, the agent’s reply, the tools used, and the workflow run ID when one was started. failed covers a slot that threw or ran past its budget, a tool or agent turn that errored, and a { startWorkflow } the platform refused; skipped_overlap is a { startWorkflow } refused because a run of that workflow was in flight under concurrencyPolicy: 'forbid'. Lua never redelivers an event: a slot failure answers the sender 500 so the sender’s own retry policy applies, and a turn or tool that fails after the 200 is only recorded, so the sender has to send again. lua triggers deactivate pauses a trigger so deliveries are acknowledged but ignored; lua triggers activate resumes it.
Triggers and webhooks
A webhook runs yourexecute function and returns whatever you return, so it is the right choice when you need to control the HTTP response, update data without involving the model, or chain your own logic. A trigger never runs handler code of yours; it decides whether the event counts and hands it to the agent, a tool, or a workflow. Events from a connected SaaS are a third case: lua integrations webhooks create subscribes to them without you registering a URL with the vendor, and delivers each one to the agent as a background turn on the integration:<type> channel, or, with --hook-url, to a webhook or trigger URL you choose.
When to use a trigger
- An external system should “tell the agent” something and let the model decide what to do: a trigger, with
--instructionor atransform. - The event maps to exactly one tool with arguments computable from the payload: a trigger with
tool. - The event should start a durable multi-step process: a trigger with
{ startWorkflow }, and anidempotencyKeyfrom the vendor’s delivery ID so a retry doesn’t start a second run. - You must answer the caller with specific data or status: a webhook.
Limits
- A
defineTriggerneeds at least one ofverify,filter,transform,tool;tool.namemust be a string literal. - A
transformthat returns nothing is an error; usefilterto skip an event. - Slots have 15 seconds in total. The tool a trigger runs afterwards has its own budget of 300 seconds.
- Default bodies are truncated at 50,000 characters; a
transformcan forward the fields you need instead. - A paused trigger answers 200; an unknown token answers 404. Executions are kept for 90 days.
- A trigger with pushed versions is deactivated rather than deleted by
lua triggers delete. - Rotating a token needs the
api-keys:issuescope on a scoped key.
Next steps
Create a trigger
Register the URL, test a delivery, and read the log.
LuaTrigger reference
The context object, every slot, and
startWorkflow fields.lua triggers
Create, logs, activate, rotate-token, delete.
Integration events
Subscribe to SaaS events and route them to a trigger.

