> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heylua.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> HTTP endpoints for receiving external events

## What are Webhooks?

**Webhooks** are HTTP endpoints that allow external services to send events to your agent. When something happens in an external system (like a payment completing or an order shipping), that system can notify your agent in real-time.

<Card title="Think of it as:" icon="webhook">
  A phone number for your agent - external services can "call" it when events happen
</Card>

<Warning>
  **No Conversational Context:** Webhooks execute outside of user conversations. You MUST provide a userId when calling `User.get(userId)` to notify specific users. Store user IDs in your payment/order metadata.
</Warning>

<Note>
  Built-in webhook support for seamless external integrations.
</Note>

## Why Webhooks?

<CardGroup cols={2}>
  <Card title="Real-Time Events" icon="bolt">
    Get notified instantly when events happen in external systems
  </Card>

  <Card title="Automated Actions" icon="gears">
    Automatically respond to external events without user interaction
  </Card>

  <Card title="Seamless Integration" icon="plug">
    Connect with Stripe, Shopify, GitHub, and any webhook-enabled service
  </Card>

  <Card title="Event-Driven" icon="satellite-dish">
    Build reactive agents that respond to real-world events
  </Card>
</CardGroup>

## How Webhooks Work

<Steps>
  <Step title="External Event Occurs">
    Something happens: payment completes, order ships, PR merges, etc.
  </Step>

  <Step title="Service Sends HTTP Request">
    The external service (Stripe, Shopify) sends a POST request to your webhook URL
  </Step>

  <Step title="Your Webhook Receives Event">
    Your LuaWebhook's execute function is called with the event data
  </Step>

  <Step title="Your Code Takes Action">
    Process the event: update orders, notify users, trigger jobs, etc.
  </Step>

  <Step title="Return Response">
    Return acknowledgment to the external service
  </Step>
</Steps>

## Simple Example

```typescript theme={null}
import { LuaWebhook, User } from 'lua-cli';

const paymentWebhook = new LuaWebhook({
  name: 'payment-webhook',
  description: 'Handle Stripe payment events',
  
  execute: async (event) => {
    const { body } = event;
    if (body?.type === 'payment_intent.succeeded') {
      // ⚠️ Webhooks have NO conversational context
      // You MUST provide userId to User.get()
      
      // Get user ID from payment metadata
      const customerId = body.data?.object?.metadata?.customerId;
      
      if (!customerId) {
        console.error('No customerId in payment metadata');
        return { received: true, error: 'No customer ID' };
      }
      
      // Retrieve specific user by ID
      const user = await User.get(customerId);
      
      // Send payment confirmation to that user
      await user.send([{
        type: 'text',
        text: `✅ Payment confirmed! Amount: ${body.data.object.amount} ${body.data.object.currency.toUpperCase()}`
      }]);
    }
    
    return { received: true };
  }
});
```

<Warning>
  **Critical:** Webhooks execute outside conversational context. `User.get()` REQUIRES a userId parameter. Always store the user ID in your payment/order metadata when creating transactions.
</Warning>

## Common Use Cases

<Tabs>
  <Tab title="Payments">
    **Stripe, PayPal, Square**

    Handle payment events:

    * Payment succeeded
    * Payment failed
    * Refund processed
    * Subscription updated

    Actions:

    * Update order status
    * Notify customer
    * Trigger fulfillment
  </Tab>

  <Tab title="E-commerce">
    **Shopify, WooCommerce**

    Handle order events:

    * Order created
    * Order fulfilled
    * Order cancelled
    * Inventory updated

    Actions:

    * Sync order data
    * Update inventory
    * Send confirmations
  </Tab>

  <Tab title="Development">
    **GitHub, GitLab**

    Handle code events:

    * Push to repository
    * Pull request opened
    * Deployment completed
    * Release published

    Actions:

    * Notify team
    * Trigger workflows
    * Update dashboards
  </Tab>

  <Tab title="Custom">
    **Your Internal Systems**

    Any event from your backend:

    * User signup
    * Task completed
    * Threshold exceeded
    * Data changed

    Actions:

    * Whatever you need!
  </Tab>
</Tabs>

## Event Subscriptions

Webhooks can also subscribe to **platform events** — real-time notifications from your messaging channels. When you send a template message via WhatsApp, for example, you can track whether it was delivered, read, or failed.

<Note>
  Webhook event subscriptions for message delivery tracking. Currently supports WhatsApp status events; additional channels may be added in the future.
</Note>

### Available Event Types

| Event               | Description                                     | Channel  |
| ------------------- | ----------------------------------------------- | -------- |
| `message.sent`      | Message was sent to the recipient               | WhatsApp |
| `message.delivered` | Message was delivered to the recipient's device | WhatsApp |
| `message.read`      | Recipient read the message                      | WhatsApp |
| `message.failed`    | Message failed to send                          | WhatsApp |
| `message.played`    | Recipient played a voice/video message          | WhatsApp |

### How It Works

<Steps>
  <Step title="Create a webhook">
    Define a `LuaWebhook` that handles delivery status events
  </Step>

  <Step title="Subscribe to events">
    Use the CLI to subscribe your webhook to the event types you care about

    ```bash theme={null}
    lua webhooks subscribe --webhook-name delivery-tracker --event message.delivered
    lua webhooks subscribe --webhook-name delivery-tracker --event message.read
    lua webhooks subscribe --webhook-name delivery-tracker --event message.failed
    ```
  </Step>

  <Step title="Receive events">
    Your webhook's `execute` function is called with the event payload whenever a status update arrives
  </Step>
</Steps>

### Example: Delivery Tracking Webhook

```typescript theme={null}
import { LuaWebhook, Data } from 'lua-cli';

const deliveryTracker = new LuaWebhook({
  name: 'delivery-tracker',
  description: 'Track WhatsApp message delivery status',
  
  execute: async (event) => {
    const { body } = event;
    const { eventType, recipientId, status, messageWamid } = body;
    
    await Data.create('delivery-events', {
      messageId: messageWamid,
      recipient: recipientId,
      status: status,
      eventType: eventType,
      trackedAt: new Date().toISOString()
    }, `${status} - ${recipientId}`);
    
    if (status === 'failed') {
      console.error(`Message ${messageWamid} failed for ${recipientId}`);
    }
    
    return { received: true };
  }
});

export default deliveryTracker;
```

### Managing Subscriptions via CLI

```bash theme={null}
# List all available event types
lua webhooks list-events

# Subscribe a webhook to an event
lua webhooks subscribe --webhook-name delivery-tracker --event message.delivered

# Unsubscribe a webhook from an event
lua webhooks unsubscribe --webhook-name delivery-tracker --event message.delivered
```

## Adding Webhooks to Your Agent

Webhooks are added to your LuaAgent configuration:

```typescript theme={null}
import { LuaAgent } from 'lua-cli';
import paymentWebhook from './webhooks/payment';
import orderWebhook from './webhooks/order';

export const agent = new LuaAgent({
  name: "my-agent",
  persona: "...",
  skills: [...],
  
  // Add webhooks
  webhooks: [
    paymentWebhook,
    orderWebhook
  ]
});
```

## Webhook URLs

After deploying, you can call webhooks by ID **or** by name:

```
https://webhook.heylua.ai/{agentId}/{webhookId}
https://webhook.heylua.ai/{agentId}/{webhook-name}
```

**Notes:**

* `agentId` is your agent identifier (e.g., `agent_abc123`)
* `webhookId` is the UUID shown when the webhook is created
* `webhook-name` is the friendly name from your code
* `lua push webhook` prints both links

Configure either URL in your external service's webhook settings.

## Best Practices

<AccordionGroup>
  <Accordion title="✅ Store User IDs in Metadata">
    **Always include user ID in payment/order metadata**

    When creating payments or orders, store the Lua user ID:

    ```typescript theme={null}
    // When creating Stripe payment
    const paymentIntent = await stripe.paymentIntents.create({
      amount: 2000,
      currency: 'usd',
      metadata: {
        customerId: user.id,  // ← Lua user ID
        orderId: order.id
      }
    });
    ```

    Then in your webhook, retrieve the specific user:

    ```typescript theme={null}
    execute: async (event) => {
      const { body } = event;
      const customerId = body.data.object.metadata.customerId;
      const user = await User.get(customerId);
      await user.send([{ type: 'text', text: 'Payment confirmed!' }]);
    }
    ```
  </Accordion>

  <Accordion title="✅ Handle Errors Gracefully">
    **Don't throw errors - return error status**

    ```typescript theme={null}
    execute: async (event) => {
      const { body } = event;
      try {
        // Process webhook
        return { success: true };
      } catch (error) {
        console.error('Webhook error:', error);
        return { success: false, error: error.message };
      }
    }
    ```
  </Accordion>

  <Accordion title="✅ Return Quickly">
    **Webhooks should respond within 5 seconds**

    For long-running work, queue a job:

    ```typescript theme={null}
    execute: async (event) => {
      const { body } = event;
      // Quick validation
      if (!isValid(body)) return { error: 'Invalid' };
      
      // Queue long-running work
      await Jobs.create({
        execute: async () => {
          // Process here
        }
      });
      
      return { received: true };
    }
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Webhooks API Reference" icon="book" href="/api/luawebhook">
    Complete API documentation with examples
  </Card>

  <Card title="Agent Concept" icon="robot" href="/overview/agent">
    Learn about LuaAgent configuration
  </Card>

  <Card title="Jobs Concept" icon="clock" href="/overview/jobs">
    Understand scheduled tasks
  </Card>

  <Card title="Skills Concept" icon="puzzle-piece" href="/overview/skill">
    Learn about skills and tools
  </Card>
</CardGroup>
