← All @molecule/* packages · App templates
@molecule/api-webhookCore interface · webhook · API (Node) · v1.0.1 · Apache-2.0
Webhook core interface for molecule.dev
npm install @molecule/api-webhook@molecule/api-webhook is the webhook core interface on the API (Node) side: the API your app calls, with no vendor inside.
Choose the implementation by bonding one of its 3 providers: @molecule/api-webhook-capture, @molecule/api-webhook-http, @molecule/api-webhook-queue.
import { setProvider, register, dispatch } from '@molecule/api-webhook'
import { createProvider } from '@molecule/api-webhook-http'
setProvider(createProvider()) // bond at startup
// SSRF guard: reject private/link-local/metadata destinations BEFORE registering.
if (!isAllowedWebhookUrl(url)) throw new Error('Destination not allowed')
const hook = await register(url, ['order.created']) // provider signs deliveries with hook.secret
await saveWebhookRow({ id: hook.id, userId: getUserId(res) }) // own it → scope list/delete by user
// Share hook.secret with the receiver so they can verify the signature header.
const results = await dispatch('order.created', { orderId: '123' })
console.log(results[0].success) // trueProviders (3): @molecule/api-webhook-capture, @molecule/api-webhook-http, @molecule/api-webhook-queue
Works with: @molecule/api-bond, @molecule/api-i18n
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Webhook core interface for molecule.dev.
Defines the standard interface for webhook dispatch providers (HTTP, queue-backed, etc.).
import { setProvider, register, dispatch } from '@molecule/api-webhook'
import { createProvider } from '@molecule/api-webhook-http'
setProvider(createProvider()) // bond at startup
// SSRF guard: reject private/link-local/metadata destinations BEFORE registering.
if (!isAllowedWebhookUrl(url)) throw new Error('Destination not allowed')
const hook = await register(url, ['order.created']) // provider signs deliveries with hook.secret
await saveWebhookRow({ id: hook.id, userId: getUserId(res) }) // own it → scope list/delete by user
// Share hook.secret with the receiver so they can verify the signature header.
const results = await dispatch('order.created', { orderId: '123' })
console.log(results[0].success) // true
core
npm install @molecule/api-webhook @molecule/api-bond @molecule/api-i18n
PaginationOptionsPagination options for listing webhook deliveries.
interface PaginationOptions {
/** Maximum number of results to return. */
limit?: number
/** Number of results to skip. */
offset?: number
}
WebhookDeliveryA recorded webhook delivery attempt.
interface WebhookDelivery {
/** Provider-assigned delivery identifier. */
id: string
/** The webhook this delivery belongs to. */
webhookId: string
/** The event type that triggered this delivery. */
event: string
/** The payload that was delivered. */
payload: unknown
/** HTTP status code returned by the receiver. */
status: number
/** Whether the delivery was successful (2xx response). */
success: boolean
/** Round-trip delivery time in milliseconds. */
duration: number
/** When this delivery attempt occurred. */
createdAt: Date
}
WebhookDeliveryResultResult of delivering a webhook payload to a single endpoint.
interface WebhookDeliveryResult {
/** The webhook this delivery was sent to. */
webhookId: string
/** Provider-assigned delivery attempt identifier. */
deliveryId: string
/** HTTP status code returned by the receiver. */
status: number
/** Whether the delivery was successful (2xx response). */
success: boolean
/** Round-trip delivery time in milliseconds. */
duration: number
}
WebhookOptionsOptions for registering a webhook endpoint.
interface WebhookOptions {
/** Shared secret used to sign webhook payloads. Auto-generated if omitted. */
secret?: string
/** Custom HTTP headers to include with every delivery. */
headers?: Record<string, string>
/** Number of automatic retries on delivery failure (default: 3). */
retryCount?: number
}
WebhookProviderWebhook provider interface.
All webhook providers must implement this interface to provide registration, dispatch, delivery logging, and retry capabilities.
interface WebhookProvider {
/**
* Registers a new webhook endpoint to receive event notifications.
*
* @param url - Destination URL that will receive POST requests.
* @param events - Event types to subscribe to.
* @param options - Optional registration configuration.
* @returns The created webhook registration.
*/
register(url: string, events: string[], options?: WebhookOptions): Promise<WebhookRegistration>
/**
* Removes a webhook registration, stopping all future deliveries.
*
* @param webhookId - The webhook to unregister.
*/
unregister(webhookId: string): Promise<void>
/**
* Dispatches an event payload to all webhooks subscribed to the event.
*
* @param event - The event type being dispatched.
* @param payload - The event payload to deliver.
* @returns Delivery results for each matching webhook.
*/
dispatch(event: string, payload: unknown): Promise<WebhookDeliveryResult[]>
/**
* Lists all registered webhooks.
*
* @returns All webhook registrations.
*/
list(): Promise<WebhookRegistration[]>
/**
* Retrieves the delivery log for a specific webhook.
*
* @param webhookId - The webhook to retrieve deliveries for.
* @param options - Pagination options.
* @returns Delivery attempts for the webhook.
*/
getDeliveryLog(webhookId: string, options?: PaginationOptions): Promise<WebhookDelivery[]>
/**
* Retries a previously failed delivery attempt.
*
* @param deliveryId - The delivery attempt to retry.
* @returns The result of the retry attempt.
*/
retry(deliveryId: string): Promise<WebhookDeliveryResult>
}
WebhookRegistrationA registered webhook endpoint.
interface WebhookRegistration {
/** Provider-assigned webhook identifier. */
id: string
/** Destination URL that receives webhook payloads. */
url: string
/** Event types this webhook is subscribed to. */
events: string[]
/** Shared secret used to sign payloads for this webhook. */
secret: string
/** Whether this webhook is currently active. */
active: boolean
/** When this webhook was registered. */
createdAt: Date
}
dispatch(event, payload)Dispatches an event payload to all webhooks subscribed to the event.
function dispatch(event: string, payload: unknown): Promise<WebhookDeliveryResult[]>
event — The event type being dispatched.payload — The event payload to deliver.Returns: Delivery results for each matching webhook.
getDeliveryLog(webhookId, options)Retrieves the delivery log for a specific webhook.
function getDeliveryLog(webhookId: string, options?: PaginationOptions): Promise<WebhookDelivery[]>
webhookId — The webhook to retrieve deliveries for.options — Pagination options.Returns: Delivery attempts for the webhook.
getProvider()Retrieves the bonded webhook provider, throwing if none is configured.
function getProvider(): WebhookProvider
Returns: The bonded webhook provider.
hasProvider()Checks whether a webhook provider is currently bonded.
function hasProvider(): boolean
Returns: true if a webhook provider is bonded.
list()Lists all registered webhooks.
function list(): Promise<WebhookRegistration[]>
Returns: All webhook registrations.
register(url, events, options)Registers a new webhook endpoint to receive event notifications.
function register(
url: string,
events: string[],
options?: WebhookOptions,
): Promise<WebhookRegistration>
url — Destination URL that will receive POST requests.events — Event types to subscribe to.options — Optional registration configuration.Returns: The created webhook registration.
retry(deliveryId)Retries a previously failed delivery attempt.
function retry(deliveryId: string): Promise<WebhookDeliveryResult>
deliveryId — The delivery attempt to retry.Returns: The result of the retry attempt.
setProvider(provider)Registers a webhook provider as the active singleton. Called by bond packages during application startup.
function setProvider(provider: WebhookProvider): void
provider — The webhook provider implementation to bond.unregister(webhookId)Removes a webhook registration, stopping all future deliveries.
function unregister(webhookId: string): Promise<void>
webhookId — The webhook to unregister.Returns: Resolves when the webhook has been unregistered.
| Provider | Package |
|---|---|
| Capture | @molecule/api-webhook-capture |
| Webhook | @molecule/api-webhook-http |
| Webhook | @molecule/api-webhook-queue |
Peer dependencies:
@molecule/api-bond ^1.0.1@molecule/api-i18n ^1.0.1@molecule/api-bond@molecule/api-i18nThis is OUTBOUND webhook DISPATCH — your app POSTing events to endpoints your users
register. (Verifying an INBOUND provider webhook, e.g. Stripe's, is the opposite
direction — you verify ITS signature; see @molecule/api-payments.) A weak dispatch
integration is an SSRF hole and a spoofable firehose:
localhost, a private range (10./192.168./127.), or the cloud metadata
IP 169.254.169.254. Validate + allowlist the scheme/host and BLOCK private/link-local
targets BEFORE registering/dispatching, or a user can read internal services.x-webhook-delivery-id on the HTTP bond) that is the SAME across all retries of one
logical delivery and unique per new event — receivers dedup on it (process each id once).user_id and scope list/delete by it — an unscoped list/delete is
an IDOR.Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:
read_activity tool (filter type 'webhook'); never mock the dispatch or
modify production code to expose the payload.localhost, 10.…, 169.254.169.254) is REJECTED before any dispatch.