# Plugin Webhook Framework Lumi exposes a webhook service to enabled plugins as `webhooks` in their `init` context and as `global.lumiFrameworks.webhooks`. ## Inbound Webhooks ```js init({ webhooks }) { webhooks.registerInbound({ pluginId: "example", endpointId: "primary", namespace: "example", slug: webhooks.generateSlug({ identifier: "alerts" }), handler: async ({ rawBody, rawBodyText, parsedJson }) => { return { status: 204 }; } }); } ``` Endpoints are mounted below `/webhooks/:namespace/:slug`, accept `POST` by default, and have a 256 KB request limit. Handlers receive the exact raw body as a `Buffer` and UTF-8 text. Provider signature verification must use `rawBody` or `rawBodyText`, never a re-serialized `parsedJson` object. Use `unregisterInbound({ pluginId, endpointId })` before replacing or removing an endpoint. `generateSlug`, `buildPublicUrl`, and `isTimestampWithinWindow` support common endpoint and replay-protection work. ## Outbound Webhooks ```js const result = await webhooks.sendJson({ pluginId: "example", url: "https://example.test/hooks", payload: { event: "example" }, timeoutMs: 10000, retries: 1 }); ``` `send` supports strings, buffers, custom headers, methods, retries, and an optional signing callback. Results include status, response headers, response body text, duration, and a success flag. Query strings and authorization headers are not written to Lumi logs.