- A project created with
lua initand signed in withlua auth configure(Install and sign in). - The sender’s payload shape and how it authenticates (a shared header or a body signature).
1
Create the trigger and copy its URL
lua triggers create registers the trigger and prints ✅ Trigger "order-created" created, the URL under 🔗 Trigger URL (paste it anywhere):, and a curl line that fires it. The token in the URL is the only credential; treat the URL like an API key.Type: URL in lua triggers list): every POST body becomes a message to the agent, prefixed with [Trigger: order-created] and any --instruction. The turn runs as you, the creator, with your tools and data, unless transform returns another userId; no end user receives anything unless the model calls a tool that sends a message.2
Shape events in code
defineTrigger has no execute. Up to four slots run on the platform per delivery, in order: verify (401 when false), filter (200 and dropped when false), transform (the event becomes the message), and tool (one tool, no model turn). The slots share a 15-second budget and can read env().src/triggers/order-created.trigger.ts
ctx.body in every slot. A sender that signs its payload is verified over ctx.rawBody, the exact bytes received. Store the token with lua env production -k SHOP_WEBHOOK_TOKEN -v <token>.3
Register it and compile
Add the trigger to
LuaAgent.triggers; unreferenced triggers aren’t compiled. The file below is the quickstart’s; if yours differs, add only the highlighted lines to your own LuaAgent.src/index.ts
lua compile checks the slots.Output
lua compile fails when no slot is set and warns when both tool and transform are declared: the tool wins.4
Push and release the version
lua push trigger uploads the compiled slots as a version of the trigger with that name and links the lua.skill.yaml row to the trigger from Step 1 by name: one trigger, one URL (the server refuses a duplicate name). Without Step 1, the push creates the trigger and lua triggers list prints its URL. lua deploy trigger then creates and promotes an agent version scoped to this trigger, so the slots are live at once and lua triggers list shows Type: SDK.lua push all --ci --force, then lua version create --ci -m "Add order-created trigger", which prints ✓ Created v<n> (staged). Run `lua version promote v<n>` to deploy., then lua version promote <n> (<n> or v<n>, no confirmation; in a script n=$(lua version list --limit 1 --json --ci | jq -r '.[0].version')) (Release an agent to production).5
Paste the URL and fire it
There is no The response is
lua test trigger, so this request is the first test. Give the sender the URL, or send one event yourself with the header verify expects.200 with { "status": "accepted", "executionId": "…" } once the slots pass; the turn runs afterwards. A wrong x-shop-token answers 401; a type other than order.created answers 200 and is dropped.6
Verify
Every delivery is a row in the trigger’s log for 90 days, newest first, with status, duration, payload, reply, and tools used.Your event shows as
COMPLETED with the reply text once the turn finishes, or ACCEPTED (in flight) while it runs; a bad token shows as REJECTED (verify failed → 401) and a filtered event as SKIPPED (filtered out). --json returns the rows as data.Options you may need
Run one tool instead of a model turn
Replacetransform with tool: { name: 'lookup_order', input: (ctx) => ({ orderId: ctx.body.data.orderNumber }) }: name is a string literal naming a tool in one of the agent’s skills, and input maps the event to its arguments. No message is sent; the result goes on the log row. To start a workflow run instead, return { startWorkflow } from transform (LuaTrigger reference).
Rotate a leaked token
lua triggers rotate-token --trigger order-created prints a replacement URL and the old one stops working at once; lua triggers deactivate --trigger order-created pauses deliveries without changing the URL.
If it isn’t working
Every delivery is REJECTED (verify failed → 401)
Every delivery is REJECTED (verify failed → 401)
The header the slot compares isn’t what the sender sends (keys are lowercase in
ctx.headers), or SHOP_WEBHOOK_TOKEN isn’t set in production. Set it with lua env production -k SHOP_WEBHOOK_TOKEN -v <token>; slots read it on the next delivery.A delivery is FAILED
A delivery is FAILED
transform returned nothing, a slot threw or ran over its budget (the sender got 500), or the turn or tool failed after the 200. Lua never redelivers, so the sender must send again; use filter, not an empty transform, to skip an event.The sender gets 404 and nothing is logged
The sender gets 404 and nothing is logged
The URL is wrong or its token was rotated.
lua triggers list prints the current URL; a request that matches no trigger is not recorded.Next steps
LuaTrigger reference
The context object, every slot, statuses, and startWorkflow fields.
lua triggers reference
create, list, logs, activate, rotate-token, delete.
Handle a webhook
When you need your own handler and response.
Integration events
Route events from a connected SaaS to a trigger.

