Skip to main content

WebhookSignalProvider

Concrete signal provider for push-based event delivery. Routes incoming webhook payloads to subscribed agent threads by matching the payload against a configurable resource ID extractor.

Extends SignalProvider with public subscription management and a built-in handleWebhook() implementation.

Usage example
Direct link to Usage example

Route GitHub webhook events to subscribed threads:

src/signals/webhook.ts
import { WebhookSignalProvider } from '@mastra/core/signals'

const webhookProvider = new WebhookSignalProvider({
extractResourceId: payload => `${payload.repository?.full_name}`,
buildNotification: (payload, subscription) => ({
source: 'github-webhook',
kind: payload.action ?? 'event',
summary: `${payload.action} on ${subscription.externalResourceId}`,
payload,
}),
})

Register with an agent and subscribe a thread:

src/mastra/index.ts
import { Agent } from '@mastra/core/agent'

const agent = new Agent({
signals: [webhookProvider],
})

// subscribe a thread to a specific repo
webhookProvider.subscribeThread({ threadId: 'thread-1', resourceId: 'user-1' }, 'mastra-ai/mastra')

// handle an incoming webhook
const result = await webhookProvider.handleWebhook({
body: { repository: { full_name: 'mastra-ai/mastra' }, action: 'push' },
headers: {},
})
// result.matched === 1

Constructor parameters
Direct link to Constructor parameters

id?:

string
= 'webhook-signals'
Unique identifier for the provider instance.

name?:

string
= 'Webhook Signals'
Human-readable name.

extractResourceId?:

(payload: unknown) => string | string[] | undefined
= Returns `payload.resource` or `payload.externalResourceId` if present
Extract the external resource ID from a webhook payload. Return `undefined` to skip the event. Can return an array to match multiple resources.

buildNotification?:

(payload: unknown, subscription: SignalSubscription) => SendNotificationSignalInput
= Returns `{ source: id, kind: 'webhook-event', summary, payload }`
Build the notification object from a webhook payload and the matched subscription.

Methods
Direct link to Methods

Subscription management
Direct link to Subscription management

subscribeThread(target, externalResourceId, metadata?)
Direct link to subscribethreadtarget-externalresourceid-metadata

Subscribe a thread to receive webhook events for a specific external resource.

webhookProvider.subscribeThread(
{ threadId: 'thread-1', resourceId: 'user-1' },
'mastra-ai/mastra',
{ watchType: 'push' },
)

Returns: SignalSubscription

target:

SignalProviderTarget
The thread to subscribe. Must include `threadId` and `resourceId`.

externalResourceId:

string
The external resource to monitor (for example, a repository full name).

metadata?:

Record<string, unknown>
Additional data to store with the subscription.

unsubscribeThread(target, externalResourceId)
Direct link to unsubscribethreadtarget-externalresourceid

Unsubscribe a thread from a specific external resource.

const removed = webhookProvider.unsubscribeThread(
{ threadId: 'thread-1', resourceId: 'user-1' },
'mastra-ai/mastra',
)

Returns: boolean

Webhook handling
Direct link to Webhook handling

handleWebhook(request)
Direct link to handlewebhookrequest

Process an incoming webhook request. Extracts the resource ID from the payload, finds matching subscriptions, builds a notification for each, and calls notify().

const result = await webhookProvider.handleWebhook({
body: { repository: { full_name: 'mastra-ai/mastra' }, action: 'push' },
headers: { 'x-github-event': 'push' },
})

Returns: Promise<{ status: number; body: { matched: number } }>

Returns { status: 200, body: { matched: N } } where N is the number of subscriptions that received notifications. Returns matched: 0 when no resource ID could be extracted or no subscriptions match.

request:

object
The incoming webhook request.
unknown
Record<string, string>

Static signal factories
Direct link to Static signal factories

WebhookSignalProvider.signals.subscribe(externalResourceId)
Direct link to webhooksignalprovidersignalssubscribeexternalresourceid

Create a reactive signal input that subscribes the current thread to an external resource.

const signal = WebhookSignalProvider.signals.subscribe('mastra-ai/mastra')

Returns: { type: 'reactive'; tagName: string; contents: string; attributes: { resource: string } }

WebhookSignalProvider.signals.unsubscribe(externalResourceId)
Direct link to webhooksignalprovidersignalsunsubscribeexternalresourceid

Create a reactive signal input that unsubscribes the current thread from an external resource.

const signal = WebhookSignalProvider.signals.unsubscribe('mastra-ai/mastra')

Returns: { type: 'reactive'; tagName: string; contents: string; attributes: { resource: string } }