source defines how Trigger.dev verifies requests and types the event every subscriber receives. Choose a named provider source or supply a verification configuration with webhooks.custom().
Presets
Presets supply the verification configuration, and most also carry the provider’s part of the endpoint’s setup prompt. Set the endpoint’s signing secret or public key as described in Connect a provider.stripe(), github(), svix(), standardWebhooks(), square(), and discord().
Svix and Standard Webhooks
svix() and standardWebhooks() use HMAC-SHA256 over id.timestamp.body with a base64-encoded whsec_ secret. Their header names differ:
Named sources such as
webhooks.clerk() and webhooks.composio() select the corresponding configuration.
Named providers
Each function below returns a source with its provider’s verification configuration. Call it throughwebhooks, for example webhooks.calCom().
Provider IDs containing a hyphen use a camel case function name: the
cal-com provider is webhooks.calCom().
Slack also ships as a chat channel in @trigger.dev/slack.
Endpoint validation
Some sources also define a response for the provider’s endpoint-validation request. These requests don’t create deliveries or task runs.discord() answers a verified { type: 0 } PING with HTTP 204 and no body. It also returns 204 for accepted events and 401 for invalid signatures. Set the Discord application’s public key as the endpoint’s verification credential.
Slack’s url_verification challenge is handled the same way by @trigger.dev/slack.
whatsapp() answers Meta’s GET verification request when hub.mode is subscribe and hub.verify_token matches the endpoint’s verify token. It returns hub.challenge as text. The verify token is separate from the App Secret used to verify event signatures; see Verify a WhatsApp endpoint URL. Endpoints without GET verification return 405 to GET requests.
Custom providers
webhooks.custom() accepts a verification configuration. This source verifies an HMAC-SHA256 signature over the raw body in x-webhook-signature and uses the event’s id for deduplication:
/trigger/internal.ts
setupPrompt is the provider-specific part of the endpoint’s setup prompt: where the provider’s webhook settings are and how to register a URL there. Trigger.dev adds the URL, the subscribers’ filters and the signing secret steps around it.
Form-encoded bodies
A verified body sent asapplication/x-www-form-urlencoded reaches subscribers as an object of its fields, so filters, chat.event keys and waiter match paths read form fields the way they read JSON fields. A repeated field becomes an array of its values. Slack slash commands and other providers that post forms work this way.
By default an accepted request gets a 200 with a small JSON receipt. Some providers show the response body to the user who triggered the request, so pass response: { acceptedBody: "empty" } to answer with an empty 200 instead:
/trigger/forms.ts
Typing the event
Stripe and GitHub sources provide default event shapes; other sources default tounknown. Pass an event type to the source function for typed handler parameters and autocomplete. This example uses Stripe.Event from the stripe package, which must be installed in your project:
/trigger/stripe.ts
webhooks.custom<T>(), pass your own event type as T. The endpoint’s event type flows to every subscriber: webhook() handlers, chat.event keys and filters, and waiter match paths are all checked against it.
Event types are compile-time annotations. Signature verification doesn’t validate the body against
a TypeScript type. Validate
event inside onEvent if your handler needs runtime schema checks.Verification schemes
Requests must pass verification before they reach any subscriber. Sources can check a signature or credential, enforce a timestamp tolerance, and derive an idempotency key for deduplication. Verification failures return the source’s rejected HTTP status (400 by default).
Custom sources support these schemes:

