Lindy Webhooks EventsSAFE
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
Overview
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
4f83675ca38aOBSERVED · 2026-10-09What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
--- 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 version: 1.20.0 license: MIT author: Jeremy Longshore <[email protected]> tags: - saas - lindy - webhooks compatibility: Compatible with AI coding agents that can read and edit application code and Markdown --- # Lindy Webhooks and Events ## Overview Build two documented boundaries: an application calls a Lindy **Webhook Received** trigger using its generated Bearer secret, and Lindy calls an application through an outbound callback action such as **HTTP Request**. Treat them as separate trust directions with separate secrets, schemas, retry policies, and evidence. Use **Read** to inspect the integration and **Write** or **Edit** to implement its closed contracts. Implement only the documented generated-Bearer trigger and configurable outbound-request surfaces; do not add unaudited control-plane, registration, event-feed, or signature mechanisms. ## Prerequisites - A Webhook Received trigger with its generated URL and nonempty generated secret. - An approved secret manager; never store secret values in code or skill output. - A separate, nonempty application-owned callback secret. - A fixed or strictly allowlisted HTTPS callback destination controlled by the application owner. - Closed request and callback schemas with local field, length, enum, and byte limits. - A shared atomic idempotency store and durable queue for scaled or retryable work. - Access to Lindy's Tasks view and synthetic test data with unique request IDs. ## Instructions ### Step 1: Define minimal contracts Specify only fields the workflow needs. A safe application-owned trigger envelope might contain `requestId`, an enumerated `eventType`, a non-sensitive `subjectId`, and `occurredAt`. Reject unknown fields, invalid types, excessive lengths, and payloads above the documented local byte limit before enqueue or transmission. Define the callback separately—for example `requestId`, `taskId`, and an enumerated `status`. Do not return full prompts, model output, source records, or customer data unless an approved data contract requires those fields. ### Step 2: Configure the Lindy trigger In the workflow, add **Webhook Received**, create or select a webhook, generate its secret, and store that secret immediately. Lindy documents URLs in this form: ```text https://public.lindy.ai/api/v1/webhooks/[unique-id] ``` Callers send `Authorization: Bearer [generated-secret]`. Select the documented follow-up behavior that matches the workflow: handle in the same task, create a new task, or ignore follow-ups. Treat request body, headers, and query parameters as untrusted input. Never copy the full headers object into a prompt or log because it can contain the Authorization secret. ### Step 3: Validate before attaching the trigger secret Fail startup unless the URL uses HTTPS, has hostname exactly `public.lindy.ai`, no unexpected port or embedded credentials, and the expected generated webhook path. Load a nonempty per-trigger secret only after the destination passes validation. ```typescript type TriggerConfig = { url: URL; secret: string }; function loadTriggerConfig(env: NodeJS.ProcessEnv): TriggerConfig { const url = new URL(env.LINDY_TRIGGER_URL ?? ''); const path = url.pathname.split('/').filter(Boolean); if ( url.protocol !== 'https:' || url.hostname !== 'public.lindy.ai' || url.port !== '' || url.username !== '' || url.password !== '' || url.search !== '' || url.hash !== '' || path.length !== 4 || path[0] !== 'api' || path[1] !== 'v1' || path[2] !== 'webhooks' || path[3].length === 0 ) { throw new Error('LINDY_TRIGGER_URL is not an approved Lindy webhook URL'); } const secret = env.LINDY_TRIGGER_SECRET ?? ''; if (secret.length === 0) throw new Error('LINDY_TRIGGER_SECRET is required'); return { url, secret }; } ``` Do not send the trigger secret to a caller-supplied `callbackUrl`, another Lindy host, or your own callback receiver. ### Step 4: Deduplicate, queue, and send Require a stable request ID derived from the source business event. Atomically reserve that ID and durably enqueue the validated event. A process-local set, background promise, or timer is not durable and does not coordinate across instances. The worker sends the closed payload with the generated Bearer secret. Treat 2xx as transport acceptance only. Treat authentication and other non-retryable 4xx as permanent failures. Retry only explicitly transient outcomes such as 408, 429, or selected 5xx with capped exponential backoff, jitter, bounded attempts, and a total deadline. Reuse the same request ID; dead-letter and alert after exhaustion. An ambiguous timeout may occur after Lindy accepted the request. Local idempotency cannot prove exactly-once remote execution, so reconcile the request ID with the Tasks view or an authenticated callback before retrying or claiming completion. ### Step 5: Configure a distinct authenticated callback Prefer an application-owned, pre-approved HTTPS callback URL. Configure a Lindy HTTP Request action to send the closed callback body and: ```text Authorization: Bearer [application-owned-callback-secret] Content-Type: application/json ``` The HTTP Request action documentation supports explicit headers and status-code handling. If using a callback URL from the trigger body, validate it against an exact scheme/host/path allowlist before any secret-bearing request. If the chosen callback action cannot enforce that validation and the required Authorization header, do not use a caller-controlled URL. At the application receiver, authenticate before ins
Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | PASS |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (0)
No findings outside the package's declared scope.
Gates applied: no_behavioural_pass.
4f83675ca38afull audit observations/trust-audit/skill/jeremylongshore__lindy-webhooks-events.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-09 | 4f83675ca38a | SAFE | B | 89 | first audit |
Questions
What does the Lindy Webhooks Events skill do?
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
Is Lindy Webhooks Events safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can Lindy Webhooks Events access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
How current is this page?
The grade is for one exact copy of the source (4f83675ca38a), read on 2026-10-09. The repository is watched, and a new audit runs when it changes — this is the first audit.