Skip to content
Back to blog
ProductAuto-detectionDashboardNew Feature

New: See Which Provider Sent Every Webhook

The dashboard now shows the detected provider and event type on every captured request. Stripe icon next to a checkout.session.completed event. GitHub icon next to a push. No configuration required.

May 15, 20265 min read

When you open a captured webhook and see a 4 KB JSON blob with a header named x-foo-signature, the first question is always: who sent this? Stripe? GitHub? Some forgotten integration from last quarter?

Until now you'd answer that by scrolling through headers. Today you don't — the dashboard tells you at a glance.

Every captured request now shows a provider badge (icon + name) and the detected event type next to the standard metadata. A Stripe request shows the Stripe brand color, the "Stripe" label, and checkout.session.completed beside the request ID. A GitHub push event shows the GitHub mark and push. Nothing to configure — detection runs automatically on every request.

How detection works

The detector inspects request headers first, body second. Each provider has a fingerprint:

ProviderDetected by
Stripestripe-signature header → event from type field
GitHubx-github-event header → event from header value
Shopifyx-shopify-topic header → event from header value
Slackx-slack-signature header → event from event.type or type
Twiliox-twilio-signature header
Paddlepaddle-signature header → event from event_type
Linearlinear-signature header → event from action + type
Vercelx-vercel-signature header → event from type
GitLabx-gitlab-event header → event from header value
Clerksvix-id headers → event from type
Discordx-signature-ed25519 header → event from t field
Typeformtypeform-signature header → event from event_type
SendGridBody matches SendGrid event array shape
Standard Webhookswebhook-id + webhook-signature + webhook-timestamp headers

The detector is ordered — specific signatures win over generic ones. Clerk (svix-id) is checked before Standard Webhooks (webhook-signature) so Clerk requests don't fall through to the generic detector.

Detection is best-effort. If nothing matches, the request shows no provider badge — but it still appears in the dashboard with the same headers, body, and verification status it always had.

Typeform joins the provider list

This release adds Typeform as the 14th supported provider. Send a real Typeform form_response event and it's detected, signed templates work in the SDK, and signature verification works the same way it does for Stripe or GitHub:

await client.sendTo("http://localhost:3000/api/webhooks/typeform", {
  provider: "typeform",
  template: "form_response",
  secret: process.env.TYPEFORM_WEBHOOK_SECRET!,
});

The template generates the typeform-signature header (sha256=...) and a realistic form_response body. Verification handles it with the same verifySignature() call as every other provider.

Detection in your code

The dashboard's detection runs on the SDK's detectWebhookInfo() helper, also exported for use in your own code:

import { detectWebhookInfo } from "@webhooks-cc/sdk";
 
const info = detectWebhookInfo({
  headers: request.headers,
  body: request.body,
});
 
// info?.provider  → "stripe"
// info?.event     → "checkout.session.completed"
// info?.via       → "header"
// info?.matchedOn → "stripe-signature"

If you only need the provider name, use the lighter detectWebhookProvider():

import { detectWebhookProvider } from "@webhooks-cc/sdk";
 
const provider = detectWebhookProvider({ headers, body });
// → "stripe" | "github" | ... | null

Useful when you're routing a single inbound endpoint to provider-specific handlers, or logging which providers send the most traffic.

Try it without an account

The guest dashboard at webhooks.cc/go now uses real provider template payloads when you click "Send test webhook." Pick Stripe and the demo sends a properly signed checkout.session.completed. Pick GitHub and it sends a real push event. You'll see the provider badge and event name in the live dashboard before you've created an account.

What else is in this release

The same release tightens signature verification config on the server side:

  • Unsupported providers are rejected at the API layer. Trying to set SendGrid as a signing provider (it uses IP allowlisting, not signatures) returns 400 with a clear message instead of silently storing the config.
  • Generic HMAC requires a header name. The signingHeader field is now required when signingProvider is "generic-hmac". Saving without it returns a validation error.
  • Provider changes require a fresh secret. You can't change the signing provider without re-entering the secret — preventing accidental mismatches where the secret was for the old provider.
  • Owner-only settings are owner-only. Team members can no longer mutate notification URLs or signing config on shared endpoints through direct API calls. The dashboard already enforced this; the API now enforces it too.

These are correctness fixes, not new features — but they close a few rough edges in the signing config path that the signature verification launch introduced.

SDK Reference

detectWebhookInfo, detectWebhookProvider, and 14 provider templates.