Overview
LuaWebhook allows you to create HTTP endpoints that can receive events from external services like Stripe, Shopify, GitHub, or any other webhook-enabled platform.
HTTP webhooks for external integrations. Use with LuaAgent.
Webhooks vs Triggers
ALuaWebhook gives you an execute function and full control of the HTTP response — your code does the work. A LuaTrigger has no execute function: it declaratively verifies, filters, and transforms an incoming event, then wakes the agent to do the work itself. If the right reaction to an event is “have the agent handle it”, reach for a trigger; if you need a custom response body or code-only side effects, stay here. See LuaTrigger for the full comparison.
Use Cases
Payment Events
Stripe, PayPal webhooks for payment processing
E-commerce Updates
Shopify, WooCommerce order notifications
Git Events
GitHub, GitLab deployment triggers
Custom Integrations
Any service that sends HTTP webhooks
User Access in Webhooks
Constructor
new LuaWebhook(config)
Creates a new webhook endpoint.LuaWebhookConfig
required
Webhook configuration object
Configuration Parameters
Required Fields
string
required
Unique webhook nameFormat: lowercase, hyphens, underscoresExamples:
'payment-webhook', 'order-update-webhook'function
required
Function that handles incoming webhook eventsSignature:
(event: WebhookEvent) => Promise<any>Optional Fields
string
Webhook description for documentation
string
HMAC-SHA256 signing key. When set, every request must carry
x-lua-signature: sha256=<hex HMAC-SHA256 of the raw body> or it is rejected with 401 before execute runs. Must be a literal or a build-time-resolvable constant. Rotate by changing the value and re-deploying; set to '' to turn verification off. See Verify Requests.WebhookEvent Shape
Every webhook receives a single object with request details:const { query, headers, body, timestamp } = event;
execution is present only when your handler is invoked via a durably-delivered platform event. It is undefined for synchronous requests sent directly to your webhook URL and during local lua test / lua dev runs. See Delivery Semantics.Complete Examples
Stripe Payment Webhook
Important: Always store the user ID (customerId) in your payment metadata so webhooks can notify the correct user. Example:
metadata: { customerId: user.id, orderId: order.id }Shopify Order Webhook
Customer Identification: Map external customer IDs (Shopify, Stripe) to Lua user IDs. Store this mapping in your order/payment metadata for webhook notifications.
GitHub Deployment Webhook
Generic Webhook Template
Event Subscriptions
Webhooks can subscribe to platform events: delivery status updates for every outbound channel (WhatsApp, SMS, email, Messenger, Instagram, and the rest). When subscribed, your webhook’sexecute function receives the event payload automatically.
Available Event Types
Channels without receipts (Slack, Teams, Front, web chat) stop at
message.sent.
Subscribing via CLI
Event Payload Shape
When an event fires, your webhook receives aWebhookEvent where body is the delivery record, the same object Channels.getStatus returns:
Delivery Semantics
Subscribed platform events are delivered at least once. Each event is durably queued and processed on isolated infrastructure with automatic retries — up to 3 attempts total, a fixed 60-second wait between attempts, retried only on failure. Your handler may therefore run more than once for a single logical event, so keep side effects idempotent. Each invocation receivesevent.execution:
event.execution is only present for durably-delivered platform events — it is undefined for synchronous direct requests to your webhook URL and during local lua test / lua dev runs. Very large event payloads (over 50,000 characters, which is rare) are delivered without the at-least-once retry guarantee.Example: Track Delivery for Analytics
Using with LuaAgent
Webhooks are added to your agent configuration:Webhook URLs
After deploying, your webhooks can be called using either identifier:agentIdis your agent identifier (e.g.,agent_abc123)webhookIdis the UUID shown when you create the webhookwebhook-nameis thenameyou pass tonew LuaWebhook- You can copy both URLs after pushing:
lua push webhook
Testing Webhooks
Local Testing
Test Payloads
Security Best Practices
✅ Use Environment Variables
✅ Use Environment Variables
Never hardcode secrets
✅ Validate Webhook Structure
✅ Validate Webhook Structure
Always validate incoming data
✅ Return Quickly
✅ Return Quickly
Webhook handlers should return fast (< 5 seconds)
Error Handling
Invoking an Agent from a Webhook
UseAgents.invoke to delegate work to a conversational agent after receiving a webhook event. Pass the user ID from the event payload so the invocation runs in that user’s context (conversation history is stored). If no user ID is available, omit userId and the invocation runs without user identity (no conversation history).
Agents API Reference
Full documentation for Agents.invoke — options, output shape, error handling, and more examples
Common Integrations
- Stripe
- Shopify
- GitHub
- Custom
Webhook Events:
payment_intent.succeededpayment_intent.payment_failedcharge.refundedinvoice.payment_succeeded
Related APIs
LuaAgent
Agent configuration
LuaTrigger
Declarative triggers that wake the agent instead of running code
Agents API
Invoke another agent from a webhook
Jobs API
Queue long-running work
User API
Send notifications
Data API
Store webhook data
See Also
- LuaAgent - Adding webhooks to your agent
- LuaTrigger - Wake the agent on an event, no execute function
- Agents API - Invoking agents from webhook handlers
- Environment Variables - Securely managing secrets
- Workflows Concept

