--- name: lindy-webhooks-events description: 'Configure Lindy AI webhook triggers, callback patterns, and event handling. Use when setting up webhook triggers, implementing callback receivers, or building event-driven Lindy integrations. Trigger with phrases like "lindy webhook", "lindy events", "lindy callback", "lindy webhook trigger". ' allowed-tools: Read, Write, Edit, Bash(curl:*) version: 1.0.0 license: MIT author: Jeremy Longshore tags: - saas - lindy - webhooks compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw --- # Lindy Webhooks & Events ## Overview Lindy supports webhooks in two directions: **Inbound** (Webhook Received trigger wakes an agent) and **Outbound** (HTTP Request action calls your API). This skill covers both patterns, plus the callback pattern for async two-way communication. ## Prerequisites - Lindy account with active agents - HTTPS endpoint for receiving callbacks (if using outbound/callback patterns) - Completed `lindy-install-auth` setup ## Webhook Architecture ``` INBOUND (your system triggers Lindy): [Your App] --POST--> https://public.lindy.ai/api/v1/webhooks/ ↓ [Lindy Agent Wakes Up] ↓ [Processes with LLM] ↓ [Executes Actions] OUTBOUND (Lindy calls your system): [Lindy Agent] --HTTP Request action--> https://your-api.com/endpoint ↓ [Your Handler] CALLBACK (two-way async): [Your App] --POST with callbackUrl--> [Lindy Agent] ↓ [Your App] <--POST to callbackUrl-- [Lindy: Send POST to Callback] ``` ## Instructions ### Step 1: Create Webhook Received Trigger 1. In your agent, click the trigger node 2. Select **Webhook Received** 3. Lindy generates a unique URL: ``` https://public.lindy.ai/api/v1/webhooks/ ``` 4. Click **Generate Secret** — copy immediately (shown only once) 5. Configure follow-up processing mode: - **Process in workflow**: Handle in current workflow - **Spawn separate task**: Each webhook creates a new task - **Discard follow-ups**: Ignore subsequent requests while processing ### Step 2: Access Webhook Data in Workflow Reference incoming webhook data in any subsequent action field: | Variable | Description | Example | |----------|-------------|---------| | `{{webhook_received.request.body}}` | Full JSON payload | `{"event": "order.created", ...}` | | `{{webhook_received.request.body.event}}` | Specific field | `"order.created"` | | `{{webhook_received.request.headers}}` | All HTTP headers | `{"content-type": "application/json"}` | | `{{webhook_received.request.query}}` | URL query params | `{"source": "stripe"}` | ### Step 3: Implement Webhook Sender ```typescript // webhook-sender.ts — Trigger Lindy agents from your application interface LindyWebhookPayload { event: string; data: Record; callbackUrl?: string; metadata?: Record; } async function triggerLindy(payload: LindyWebhookPayload): Promise { const response = await fetch(process.env.LINDY_WEBHOOK_URL!, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.LINDY_WEBHOOK_SECRET}`, 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }); if (!response.ok) { throw new Error(`Lindy webhook failed: ${response.status}`); } } // Usage examples: await triggerLindy({ event: 'customer.support_request', data: { email: 'user@co.com', subject: 'Billing question', body: '...' }, }); await triggerLindy({ event: 'lead.qualified', data: { name: 'Jane Doe', company: 'Acme', score: 85 }, callbackUrl: 'https://api.yourapp.com/lindy/callback', }); ``` ### Step 4: Implement Callback Receiver When you include a `callbackUrl` in your webhook payload, the agent can respond using the **Send POST Request to Callback** action: ```typescript // callback-receiver.ts import express from 'express'; const app = express(); app.use(express.json()); // Receive Lindy agent results app.post('/lindy/callback', (req, res) => { // Verify authenticity const auth = req.headers.authorization; if (auth !== `Bearer ${process.env.LINDY_WEBHOOK_SECRET}`) { return res.status(401).json({ error: 'Unauthorized' }); } // Respond immediately (Lindy expects a quick response) res.json({ received: true }); // Process async handleCallback(req.body); }); async function handleCallback(data: any) { console.log('Lindy callback:', data); // Example: Agent analyzed a support ticket const { classification, sentiment, draft_response, confidence } = data; if (confidence > 0.9) { await sendAutoResponse(draft_response); } else { await escalateToHuman(data); } } ``` ### Step 5: Configure HTTP Request Action (Outbound) For Lindy agents that call your API as an action step: 1. Add action: **HTTP Request** 2. Configure: - **Method**: POST (or GET, PUT, DELETE) - **URL**: `https://api.yourapp.com/endpoint` - **Headers** (Set Manually): ``` Content-Type: application/json Authorization: Bearer {{your_api_key}} ``` - **Body** (AI Prompt mode): ``` Send the analysis result as JSON with fields: classification, sentiment, summary Based on: {{previous_step.result}} ``` ### Step 6: Add Trigger Filters Prevent unnecessary agent triggers: ``` Filter: body.event equals "order.created" AND body.data.amount greater_than 100 ``` This ensures the agent only processes high-value orders, saving credits. ## Event Patterns ### Pattern: Webhook + Slack Notification ``` Webhook Received → Condition (classify event type) → "billing" → Search KB → Draft Reply → Send Email + Slack Alert → "technical" → Agent Step (investigate) → Create Ticket → Slack Alert → "other" → Forward to team inbox ``` ### Pattern: Webhook + Callback ``` Webhook Received (with callbackUrl) → Process Data → Run Code → Send POST Request to Callback (returns results to caller) ``` ### Pattern: Webhook + Multi-Agent ``` Webhook Received → Agent Send Message (to Research Lindy) → Research Lindy completes → Agent Send Message (to Writer Lindy) → Writer Lindy completes → Send Email with final output ``` ## Monitoring Triggers Lindy provides built-in monitoring triggers: - **Task Completed**: Fires when an agent completes a task - Use this to build observability pipelines: Agent completes → log to sheet → alert on failures ## Error Handling | Issue | Cause | Solution | |-------|-------|----------| | 401 on webhook send | Wrong or missing Bearer token | Verify secret matches Generate Secret value | | Webhook URL returns 404 | Agent deleted or URL changed | Re-copy URL from agent trigger settings | | Callback not received | callbackUrl unreachable | Ensure HTTPS, public endpoint, no firewall | | Duplicate processing | Webhook retried | Implement idempotency with event IDs | | Payload too large | Body exceeds limit | Reduce payload size, send references not data | ## Security - Always use HTTPS for webhook URLs - Generate and verify webhook secrets on every request - Rotate secrets every 90 days - Log all webhook attempts (including rejected ones) - Rate limit your webhook sender to prevent flooding ## Resources - [Webhooks Documentation](https://docs.lindy.ai/skills/by-lindy/webhooks) - [Webhook Triggers Academy](https://www.lindy.ai/academy-lessons/webhook-triggers) - [Calling Any API](https://www.lindy.ai/academy-lessons/calling-any-api) ## Next Steps Proceed to `lindy-performance-tuning` for agent optimization.