Skip to content

Provider Template Reference

Detailed reference for all 28 webhook provider templates. Payload shapes, signature methods, headers, and event types for Stripe, GitHub, Shopify, Twilio, Slack, Paddle, Linear, SendGrid, Clerk, Discord, Vercel, GitLab, Typeform, Standard Webhooks, Meta (WhatsApp/Messenger/Instagram), Lemon Squeezy, Coinbase Commerce, Razorpay, Cal.com, Intercom, Telegram, Square, HubSpot, Mailgun, Calendly, Mux, Sentry, and Bitbucket.

Updated May 2026

Templates generate realistic payloads with correct provider headers. Providers with shared-secret or token-style signing also get matching signature material — usually a signature header, except Mailgun, which embeds its signature fields in the request body. Use templates from the dashboard, the SDK, or the MCP server.

Use templates from code

Send a provider-shaped webhook to a hosted endpoint:

import { WebhooksCC } from "@webhooks-cc/sdk";
 
const client = new WebhooksCC({ apiKey: process.env.WHK_API_KEY! });
 
await client.endpoints.sendTemplate("abc123", {
  provider: "typeform",
  template: "form_response",
  secret: "typeform_test_secret",
});

Build the request without sending it when you want to inspect headers or use your own HTTP client:

import { buildTemplateSendOptions, detectWebhookInfo } from "@webhooks-cc/sdk";
 
const request = await buildTemplateSendOptions("https://go.webhooks.cc/w/abc123", {
  provider: "typeform",
  template: "form_response",
  secret: "typeform_test_secret",
});
 
const detected = detectWebhookInfo({
  headers: request.headers ?? {},
  body: typeof request.body === "string" ? request.body : JSON.stringify(request.body),
  contentType: request.headers?.["content-type"],
});
 
console.log(detected);
// { provider: "typeform", event: "form_response", via: "header", matchedOn: "typeform-signature" }

SendGrid and Discord templates are intentionally unsigned. SendGrid relies on Event Webhook IP allowlisting, and Discord signatures are Ed25519 signatures generated by Discord itself.

Stripe

Signature: HMAC-SHA256 over {timestamp}.{body} in stripe-signature header.

EventDescription
payment_intent.succeededPayment completed
checkout.session.completedCheckout session paid
invoice.paidInvoice payment succeeded

Payload shape:

{
  "id": "evt_...",
  "object": "event",
  "api_version": "2025-01-27.acacia",
  "created": 1700000000,
  "data": {
    "object": { "id": "pi_...", "amount": 2000, "currency": "usd", "status": "succeeded" }
  },
  "type": "payment_intent.succeeded",
  "livemode": false
}

Headers: stripe-signature, user-agent: Stripe/1.0


GitHub

Signature: HMAC-SHA256 over raw body in x-hub-signature-256 header (prefixed sha256=).

EventDescription
pushCode pushed to a branch
pull_request.openedPull request opened
pingWebhook configuration test

Payload shape (push):

{
  "ref": "refs/heads/main",
  "before": "abc...",
  "after": "def...",
  "repository": { "id": 123, "full_name": "org/repo" },
  "commits": [{ "id": "def...", "message": "...", "timestamp": "..." }],
  "pusher": { "name": "user", "email": "[email protected]" }
}

Headers: x-github-event, x-github-delivery, x-hub-signature-256


Shopify

Signature: HMAC-SHA256 over raw body, base64-encoded in x-shopify-hmac-sha256 header.

EventDescription
orders/createNew order created
orders/paidOrder payment done
products/updateProduct updated
app/uninstalledApp removed by shop

Payload shape (orders/create):

{
  "id": 1234567890,
  "email": "[email protected]",
  "financial_status": "pending",
  "total_price": "19.99",
  "line_items": [{ "title": "Demo Item", "quantity": 1, "price": "19.99" }]
}

Headers: x-shopify-topic, x-shopify-hmac-sha256, x-shopify-shop-domain, x-shopify-api-version, x-shopify-webhook-id


Twilio

Signature: HMAC-SHA1 over URL + sorted form params, base64-encoded in x-twilio-signature header.

EventDescription
messaging.inboundIncoming SMS
messaging.status_callbackMessage delivery status
voice.incoming_callIncoming voice call

Content-Type: application/x-www-form-urlencoded (not JSON)

Payload fields (messaging.inbound): AccountSid, MessageSid, From, To, Body, NumMedia, MessageStatus

Headers: x-twilio-signature


Slack

Signature: HMAC-SHA256 over v0:{timestamp}:{body} in x-slack-signature header (prefixed v0=).

EventDescriptionContent-Type
event_callbackEvents API eventapplication/json
slash_commandSlash command invocationapplication/x-www-form-urlencoded
url_verificationChallenge handshakeapplication/json

Payload shape (event_callback):

{
  "type": "event_callback",
  "team_id": "T...",
  "api_app_id": "A...",
  "event": { "type": "app_mention", "user": "U...", "text": "hello", "channel": "C..." },
  "event_id": "Ev...",
  "event_time": 1700000000
}

Headers: x-slack-signature, x-slack-request-timestamp


Paddle

Signature: HMAC-SHA256 over {timestamp}:{body} in paddle-signature header (format ts={ts};h1={hex}).

EventDescription
transaction.completedPayment completed
subscription.createdNew subscription started
subscription.updatedSubscription changed

Payload shape:

{
  "event_id": "uuid",
  "event_type": "transaction.completed",
  "occurred_at": "2026-03-20T...",
  "notification_id": "uuid",
  "data": { "id": "txn_...", "status": "completed", "customer_id": "ctm_...", "total": "49.00" }
}

Headers: paddle-signature


Linear

Signature: HMAC-SHA256 over raw body in linear-signature header (prefixed sha256=).

EventDescription
issue.createIssue created
issue.updateIssue updated
comment.createComment added

Payload shape (issue.create):

{
  "action": "create",
  "type": "Issue",
  "webhookTimestamp": "2026-03-20T...",
  "data": { "id": "uuid", "identifier": "ENG-42", "title": "..." }
}

Headers: linear-signature


SendGrid

Signature: None. SendGrid uses IP allowlisting, not HMAC signatures.

EventDescription
deliveredEmail delivered to recipient
openEmail opened
bounceEmail bounced
spam_reportRecipient marked as spam

Payload shape: SendGrid sends a JSON array (not an object):

[
  {
    "email": "[email protected]",
    "timestamp": 1700000000,
    "event": "delivered",
    "sg_event_id": "...",
    "sg_message_id": "...",
    "category": ["webhooks-cc-demo"]
  }
]

Headers: user-agent: SendGrid Event Webhook


Clerk

Signature: Standard Webhooks (Svix) — HMAC-SHA256 over {msgId}.{timestamp}.{body}, base64-encoded. Both webhook-* and svix-* headers are sent.

EventDescription
user.createdNew user signed up
user.updatedUser profile changed
user.deletedUser deleted
session.createdNew session started

Payload shape (user.created):

{
  "data": {
    "id": "user_...",
    "object": "user",
    "first_name": "Webhook",
    "last_name": "Tester",
    "email_addresses": [{ "email_address": "[email protected]" }],
    "created_at": 1700000000000
  },
  "object": "event",
  "type": "user.created",
  "timestamp": 1700000000000
}

Headers: webhook-id, webhook-timestamp, webhook-signature, svix-id, svix-timestamp, svix-signature


Discord

Signature: Ed25519 (not HMAC). Templates include placeholder signature headers but cannot generate valid Ed25519 signatures from a shared secret. Use the SDK's verifyDiscordSignature(publicKey, request) separately for verification testing.

EventDescription
interaction_createSlash command invocation
message_componentButton/select menu interaction
pingDiscord verification ping

Payload shape (interaction_create):

{
  "id": "...",
  "application_id": "...",
  "type": 2,
  "data": { "id": "...", "name": "webhook-test", "type": 1 },
  "guild_id": "...",
  "channel_id": "...",
  "member": { "user": { "username": "webhooks-cc-bot" } },
  "token": "..."
}

Interaction types: 1 = Ping, 2 = Application Command, 3 = Message Component

Headers: x-signature-timestamp (informational)


Vercel

Signature: HMAC-SHA1 over raw body, hex-encoded in x-vercel-signature header.

EventDescription
deployment.createdDeployment started
deployment.succeededDeployment completed
deployment.errorDeployment failed

Payload shape (deployment.created):

{
  "id": "uuid",
  "type": "deployment.created",
  "createdAt": 1700000000000,
  "payload": {
    "deployment": { "id": "dpl_...", "name": "my-project", "url": "my-project-abc.vercel.app" },
    "project": { "id": "prj_...", "name": "my-project" },
    "team": { "id": "team_...", "name": "my-team" }
  }
}

Headers: x-vercel-signature


GitLab

Signature: Raw secret token in x-gitlab-token header (string comparison, not HMAC).

EventDescription
pushCode pushed
merge_requestMerge request event

Payload shape (push):

{
  "object_kind": "push",
  "event_name": "push",
  "ref": "refs/heads/main",
  "project": { "id": 12345, "name": "demo-repo", "web_url": "https://gitlab.com/..." },
  "commits": [{ "id": "abc...", "message": "...", "timestamp": "..." }],
  "total_commits_count": 1
}

Headers: x-gitlab-token, x-gitlab-event (Push Hook or Merge Request Hook)


Typeform

Signature: HMAC-SHA256 over the raw JSON body, base64-encoded in typeform-signature header with a sha256= prefix.

EventDescription
form_responseCompleted form submission
partial_responsePartial response submission
paymentForm response with payment

Payload shape (form_response):

{
  "event_id": "uuid",
  "event_type": "form_response",
  "form_response": {
    "form_id": "abc123",
    "token": "token_...",
    "landed_at": "2026-04-25T12:00:00.000Z",
    "submitted_at": "2026-04-25T12:01:00.000Z",
    "definition": {
      "id": "abc123",
      "title": "Webhook test form",
      "fields": [{ "id": "field_email", "type": "email", "title": "What is your email?" }]
    },
    "answers": [{ "type": "email", "email": "[email protected]" }]
  }
}

Headers: typeform-signature


Standard Webhooks

Signature: HMAC-SHA256 over {msgId}.{timestamp}.{body}, base64-encoded in webhook-signature header. Used by Polar.sh, Svix, Resend, Liveblocks, and Novu.

EventDescription
order.createdNew order placed
invoice.paidInvoice paid
subscription.activeSubscription activated

Payload shape:

{
  "type": "order.created",
  "timestamp": "2026-03-20T12:00:00Z",
  "data": {
    "id": "ord_...",
    "customer_id": "cust_...",
    "amount": "49.00",
    "currency": "usd",
    "status": "completed"
  }
}

Headers: webhook-id, webhook-timestamp, webhook-signature


Meta (WhatsApp / Messenger / Instagram)

Signature: HMAC-SHA256 over the raw body in x-hub-signature-256 header (prefixed sha256=), keyed by your Meta app secret — the same scheme as GitHub. Auto-detection uses the body shape (object + entry), so configure meta explicitly when verifying server-side.

TemplateDescription
whatsapp.messagesInbound WhatsApp message
page.messagesMessenger conversation event
instagram.commentsInstagram comment event

Payload shape (whatsapp.messages):

{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "...",
      "changes": [
        {
          "field": "messages",
          "value": {
            "messaging_product": "whatsapp",
            "metadata": { "display_phone_number": "15550100", "phone_number_id": "..." },
            "messages": [
              {
                "from": "15551234567",
                "id": "wamid....",
                "type": "text",
                "text": { "body": "Hello" }
              }
            ]
          }
        }
      ]
    }
  ]
}

Headers: x-hub-signature-256, user-agent: facebookplatform/1.0


Lemon Squeezy

Signature: HMAC-SHA256 over the raw body, hex-encoded in x-signature header.

TemplateDescription
order_createdNew order placed
subscription_createdNew subscription started
subscription_payment_successRecurring payment succeeded

Payload shape (order_created):

{
  "meta": { "event_name": "order_created", "custom_data": {} },
  "data": {
    "type": "orders",
    "id": "123456",
    "attributes": {
      "status": "paid",
      "total": 1999,
      "currency": "USD",
      "user_email": "[email protected]"
    }
  }
}

Headers: x-signature, user-agent: Lemon Squeezy Webhooks


Coinbase Commerce

Signature: HMAC-SHA256 over the raw body, hex-encoded in x-cc-webhook-signature header.

TemplateDescription
charge:confirmedCharge confirmed/paid
charge:failedCharge failed
charge:pendingCharge pending

Payload shape:

{
  "event": {
    "id": "uuid",
    "type": "charge:confirmed",
    "api_version": "2018-03-22",
    "data": {
      "code": "ABC123",
      "name": "Order",
      "pricing": { "local": { "amount": "19.99", "currency": "USD" } }
    }
  }
}

Headers: x-cc-webhook-signature, user-agent: weipay-webhooks


Razorpay

Signature: HMAC-SHA256 over the raw body, hex-encoded in x-razorpay-signature header.

TemplateDescription
payment.capturedPayment captured
payment.failedPayment failed
order.paidOrder fully paid

Payload shape:

{
  "entity": "event",
  "account_id": "acc_...",
  "event": "payment.captured",
  "contains": ["payment"],
  "payload": {
    "payment": {
      "entity": {
        "id": "pay_...",
        "amount": 5000,
        "currency": "INR",
        "status": "captured",
        "method": "card"
      }
    }
  }
}

Headers: x-razorpay-signature, user-agent: Razorpay-Webhook/1.0


Cal.com

Signature: HMAC-SHA256 over the raw body, hex-encoded in x-cal-signature-256 header.

TemplateDescription
BOOKING_CREATEDBooking created
BOOKING_CANCELLEDBooking cancelled
BOOKING_RESCHEDULEDBooking rescheduled

Payload shape (BOOKING_CREATED):

{
  "triggerEvent": "BOOKING_CREATED",
  "createdAt": "2026-05-31T12:00:00.000Z",
  "payload": {
    "type": "30min",
    "title": "30min between Ada and webhooks.cc",
    "startTime": "2026-05-31T12:00:00.000Z",
    "endTime": "2026-05-31T12:30:00.000Z",
    "attendees": [{ "email": "[email protected]", "name": "Guest", "timeZone": "UTC" }]
  }
}

Headers: x-cal-signature-256, user-agent: Cal.com Webhook


Intercom

Signature: HMAC-SHA1 over the raw body, hex-encoded in x-hub-signature header (prefixed sha1=), keyed by your Intercom app client secret. Distinguished from GitHub (which sends x-hub-signature-256 + x-github-event) and Bitbucket (sha256=) by the sha1= prefix.

TemplateDescription
conversation.user.createdUser started a conversation
conversation.admin.repliedAdmin replied
contact.createdNew contact created

Payload shape:

{
  "type": "notification_event",
  "id": "notif_...",
  "topic": "conversation.user.created",
  "data": {
    "type": "notification_event_data",
    "item": { "type": "conversation", "id": "1234567890" }
  }
}

Headers: x-hub-signature (sha1=...), user-agent: Intercom-Webhook/1.1


Telegram

Signature: Raw secret token in x-telegram-bot-api-secret-token header (string comparison, not HMAC). The token is the secret_token you pass to Telegram's setWebhook.

TemplateDescription
messageIncoming message update
callback_queryInline button callback
edited_messageEdited message update

Payload shape (message):

{
  "update_id": 100001,
  "message": {
    "message_id": 1,
    "from": { "id": 42, "is_bot": false, "first_name": "Ada" },
    "chat": { "id": 42, "type": "private" },
    "date": 1700000000,
    "text": "hi"
  }
}

Headers: x-telegram-bot-api-secret-token


Square

Signature: HMAC-SHA256 over the notification URL concatenated with the raw body, base64-encoded in the x-square-hmacsha256-signature header.

Square mixes the destination URL into the signed payload, so verification needs the exact URL Square delivers to. When verifying with the SDK, pass the url option (see the signature guide).

TemplateDescription
payment.createdPayment created
payment.updatedPayment updated
refund.createdRefund created

Payload shape (payment.created):

{
  "merchant_id": "...",
  "type": "payment.created",
  "event_id": "uuid",
  "created_at": "2026-05-31T12:00:00.000Z",
  "data": {
    "type": "payment",
    "id": "...",
    "object": {
      "payment": {
        "id": "...",
        "amount_money": { "amount": 2000, "currency": "USD" },
        "status": "APPROVED"
      }
    }
  }
}

Headers: x-square-hmacsha256-signature, user-agent: Square-Webhooks/1.0


HubSpot

Signature: HMAC-SHA256 (v3) over {method}{requestUri}{body}{timestamp}, base64-encoded in the x-hubspot-signature-v3 header. The timestamp (in milliseconds) is sent in x-hubspot-request-timestamp.

HubSpot v3 signs the HTTP method and request URI alongside the body, and rejects signatures whose timestamp is more than 5 minutes old. When verifying with the SDK, pass both the url and method options (see the signature guide).

TemplateDescription
contact.creationContact created
contact.propertyChangeContact property changed
deal.creationDeal created

Payload shape: HubSpot delivers a JSON array of subscription notifications:

[
  {
    "eventId": 123456789,
    "subscriptionId": 1,
    "portalId": 123,
    "occurredAt": 1700000000000,
    "subscriptionType": "contact.creation",
    "attemptNumber": 0,
    "objectId": 1,
    "propertyName": null,
    "propertyValue": null
  }
]

Headers: x-hubspot-signature-v3, x-hubspot-request-timestamp, user-agent: HubSpot-Webhooks/1.0


Mailgun

Signature: HMAC-SHA256 over {timestamp}{token}, hex-encoded. Mailgun has no signature header — the values live in the request body under signature.{timestamp,token,signature}.

Because Mailgun signs body fields rather than a header, auto-detection keys on the presence of signature.token and signature.timestamp in the body. The SDK's verifyMailgunSignature reads the body directly and returns false (never throws) on malformed input.

TemplateDescription
deliveredMessage delivered
failedDelivery failed
openedMessage opened

Payload shape (delivered):

{
  "signature": { "timestamp": "1700000000", "token": "...", "signature": "..." },
  "event-data": {
    "event": "delivered",
    "id": "...",
    "timestamp": 1700000000,
    "recipient": "[email protected]",
    "message": { "headers": { "message-id": "[email protected]" } }
  }
}

Headers: user-agent: Mailgun-Webhooks/1.0 (no signature header)


Calendly

Signature: HMAC-SHA256 over {timestamp}.{body}, hex-encoded in the calendly-webhook-signature header using the Stripe-style t=<unix>,v1=<hex> format.

TemplateDescription
invitee.createdInvitee scheduled
invitee.canceledInvitee canceled
routing_form_submission.createdRouting form submitted

Payload shape (invitee.created):

{
  "event": "invitee.created",
  "created_at": "2026-05-31T12:00:00.000Z",
  "payload": {
    "email": "[email protected]",
    "name": "Ada",
    "scheduled_event": {
      "start_time": "2026-05-31T12:00:00.000Z",
      "end_time": "2026-05-31T12:30:00.000Z",
      "name": "30 Minute Meeting"
    }
  }
}

Headers: calendly-webhook-signature (t=...,v1=...), user-agent: Calendly-Webhooks/1.0


Mux

Signature: HMAC-SHA256 over {timestamp}.{body}, hex-encoded in the mux-signature header using the Stripe-style t=<unix>,v1=<hex> format (identical scheme to Calendly).

TemplateDescription
video.asset.createdAsset created
video.asset.readyAsset ready for playback
video.upload.asset_createdUpload produced an asset

Payload shape (video.asset.created):

{
  "type": "video.asset.created",
  "object": { "type": "asset", "id": "..." },
  "id": "uuid",
  "created_at": "2026-05-31T12:00:00.000Z",
  "data": { "status": "preparing", "id": "..." }
}

Headers: mux-signature (t=...,v1=...), user-agent: Mux-Webhooks/1.0


Sentry

Signature: HMAC-SHA256 over the raw body, hex-encoded in the sentry-hook-signature header. The resource type (e.g. issue, error) is sent in sentry-hook-resource, which auto-detection uses for the event name.

TemplateDescription
issue.createdIssue created
issue.resolvedIssue resolved
error.createdError captured

Payload shape (issue.created):

{
  "action": "created",
  "installation": { "uuid": "uuid" },
  "data": {
    "issue": {
      "id": "...",
      "title": "TypeError: undefined is not a function",
      "culprit": "app/main",
      "level": "error"
    }
  },
  "actor": { "type": "application", "id": "sentry" }
}

Headers: sentry-hook-signature, sentry-hook-resource, user-agent: Sentry-Webhooks/1.0


Bitbucket

Signature: HMAC-SHA256 over the raw body, hex-encoded in the x-hub-signature header with a sha256= prefix — the same scheme as GitHub. The event key is sent in the unique x-event-key header.

Bitbucket and Intercom both send x-hub-signature. Auto-detection keys on Bitbucket's unique x-event-key header (and is ordered before Intercom) so the sha256= Bitbucket scheme is never confused with Intercom's sha1= scheme.

TemplateDescription
repo:pushCode pushed
pullrequest:createdPull request opened
pullrequest:fulfilledPull request merged

Payload shape (repo:push):

{
  "push": { "changes": [{ "new": { "name": "main", "type": "branch" } }] },
  "repository": { "name": "demo-repo", "full_name": "webhooks-cc/demo-repo" },
  "actor": { "display_name": "webhooks-cc-bot" }
}

Headers: x-hub-signature (sha256=...), x-event-key, user-agent: Bitbucket-Webhooks/1.0