Skip to main content

Make.com Webhooks Tutorial: Trigger Scenarios from Any App or Service

· 12 min read
Yassine El Haddad
Software Developer & Automation Specialist

I build production AI agents, web scrapers, and automation pipelines. Most of what I publish here comes from the actual problems they run into: proxies that get banned, anti-bot stacks that fingerprint your client, RAG that drifts when the underlying data moves. Stack: Python, TypeScript, Go, FastAPI, LangChain, Crawlee, Playwright, deployed on AWS, GCP, and Cloudflare.

Make.com webhooks let you trigger a scenario the instant something happens in any external app — no polling, no delays, no scheduled waits.

A webhook is a URL that Make generates for you. Any system that can send an HTTP POST request can fire that URL and kick off your scenario with real-time data. GitHub merges a PR? Your scenario runs. Stripe processes a payment? Your scenario runs. A custom internal script hits the endpoint? Your scenario runs.

This tutorial covers everything: creating webhook triggers, parsing JSON payloads, using the Webhook Response module, verifying HMAC signatures, and practical examples with GitHub, Stripe, and custom apps.

Setup time~10 min
Code requiredOptional (curl / JSON)
DifficultyBeginner–Intermediate
PlatformMake.com (all paid plans)

What is a Make.com webhook?

A Make.com webhook is a Custom Webhook trigger module that generates a unique HTTPS endpoint URL. When an external service sends an HTTP POST request to that URL, Make:

  1. Receives the request body (typically JSON or form data)
  2. Maps the body fields as variables available to the rest of the scenario
  3. Executes all subsequent modules in the scenario

Webhooks are instant triggers — unlike scheduled triggers that poll every N minutes, a webhook fires the moment the HTTP request arrives. This makes them the right choice whenever you need real-time reaction to external events.

Webhook vs. polling: when to use each

MethodLatencyAPI callsBest for
Webhook (instant trigger)< 1 secondZero polling callsReal-time events (payments, form submissions, Git events)
Scheduled trigger1–60 minRegular pollingBatch jobs, periodic syncs, reports
Watch modules1–15 minMake polls on scheduleApps with native watch support (Gmail, Sheets)

Use webhooks whenever the external service supports outbound HTTP calls. Use scheduled triggers for services that only expose pull APIs.


Step 1: Create a custom webhook trigger

  1. Open Make.com and create a new scenario.
  2. Click the + icon to add the first module.
  3. Search for Webhooks and select the Custom Webhook module.
  4. Click Add to create a new webhook configuration.
  5. Give your webhook a descriptive name (e.g., github-pr-merged).
  6. Click Save — Make generates a unique HTTPS endpoint URL.

Your URL looks like this:

https://hook.eu2.make.com/abc123xyz456def789

Copy that URL. You will paste it into the external service's webhook settings.

Important: The webhook URL is a secret. Anyone with the URL can trigger your scenario. Treat it like an API key.


Step 2: Send a test payload to determine the data structure

Before building the rest of your scenario, send a sample payload so Make can auto-detect the JSON structure. This saves you from manually mapping fields.

Option A — Use curl:

curl -X POST https://hook.eu2.make.com/YOUR_WEBHOOK_ID \
-H "Content-Type: application/json" \
-d '{
"event": "pull_request",
"action": "closed",
"pull_request": {
"title": "Add webhook tutorial",
"merged": true,
"number": 42,
"user": { "login": "yassine" }
},
"repository": {
"full_name": "org/repo"
}
}'

Option B — Use a browser's fetch API (developer console):

fetch('https://hook.eu2.make.com/YOUR_WEBHOOK_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event: 'test', value: 42 })
});

After sending the request, go back to Make and click Re-determine data structure. Make parses the sample body and creates a structured bundle of variables you can use downstream.


Step 3: Access webhook payload fields in your scenario

Once Make detects the data structure, every field in your JSON payload becomes a variable in the scenario. For the GitHub example above, you can reference:

VariableValue from sample
eventpull_request
actionclosed
pull_request.titleAdd webhook tutorial
pull_request.mergedtrue
pull_request.user.loginyassine
repository.full_nameorg/repo

Click any field in a subsequent module's mapping panel to insert these variables.

Handling dynamic or unknown payload shapes

If the webhook payload structure changes between calls (e.g., optional fields), use the Get value of a variable function or add a Router module with filter conditions to branch on the presence of a field.

For completely arbitrary JSON, map the raw body string with {{1._raw}} and parse it with Make's built-in parseJSON() function.


Step 4: Use the Webhook Response module

By default, Make returns HTTP 200 with an empty body once it accepts the webhook. Some services (e.g., Stripe, Shopify, Twilio) require a specific response body or status code to confirm receipt.

Use the Webhooks > Webhook Response module at the end of your scenario to control the response:

{
"status": 200,
"body": "{ \"received\": true }",
"headers": {
"Content-Type": "application/json"
}
}

Stripe requires { "received": true } within 30 seconds. If Make doesn't reply in time, Stripe marks the delivery as failed and retries. The Webhook Response module ensures the acknowledgement is sent before Make begins processing long operations.

Practical pattern for slow workflows: Add Webhook Response immediately after the trigger, then continue with the rest of your automation. This acknowledges the sender quickly while Make processes asynchronously.

[Custom Webhook] → [Webhook Response: 200 OK] → [Long processing modules...]

Step 5: Verify webhook signatures (HMAC)

Any public webhook URL can receive arbitrary POST requests. Production webhooks from services like GitHub and Stripe include a cryptographic HMAC signature in the request headers. Verify it before processing the payload to prevent spoofed requests.

GitHub webhook signature verification

GitHub includes X-Hub-Signature-256: sha256=<hex_digest> in every webhook request.

In your Make scenario after the Custom Webhook trigger:

  1. Add an HTTP > Make a request module (or use a Tools module) — but Make natively supports this more elegantly via the Webhook Guard pattern:
  2. Add a Filter condition before the first processing module:
    • Field: {{hmac(1.body; "sha256"; "YOUR_WEBHOOK_SECRET"; "hex")}} (use Make's hmac function with SHA256)
    • Operator: Equal to
    • Value: {{replace(1.headers["x-hub-signature-256"]; "sha256="; "")}} (strip the sha256= prefix)

If the computed hash doesn't match the header, the filter blocks execution — your scenario ignores the fraudulent request.

Stripe webhook signature verification

Stripe uses Stripe-Signature with a timestamp to prevent replay attacks:

Stripe-Signature: t=1709123456,v1=abc123def456...,v0=oldhash...

The exact verification algorithm is: HMAC-SHA256(secret, timestamp + "." + raw_body). Implement this in Make with:

  1. Tools > Set Variable — extract t= value from the header using {{split(1.headers["stripe-signature"]; ",")[0]}} and strip t=.
  2. Tools > Set Variable — concatenate {{timestamp}}.{{1.body}}.
  3. Crypto > HMAC-SHA256 — hash the concatenated string with your Stripe webhook secret.
  4. Filter — compare the computed hash against the v1= value in the header.

For high-security production use, consider routing webhook verification through a lightweight Apify Actor or a serverless function before forwarding the verified payload to Make.


Practical example 1: GitHub webhook → Slack notification

Goal: Post a Slack message whenever a pull request is merged into main.

Modules:

  1. Webhooks > Custom Webhook — receive GitHub PR events
  2. Filter{{pull_request.merged}} equals true AND {{pull_request.base.ref}} equals main
  3. Slack > Create a Message — post to #deployments channel

GitHub setup:

  1. Go to your repository → SettingsWebhooksAdd webhook.
  2. Paste your Make webhook URL.
  3. Set Content type to application/json.
  4. Select Pull requests as the event type.
  5. Save.

Make scenario flow:

GitHub PR event → Filter (merged=true, base=main) → Slack message

Sample Slack message template:

🚀 *{{pull_request.title}}* merged into main
By: {{pull_request.user.login}} | PR #{{pull_request.number}}
Repo: {{repository.full_name}}

Practical example 2: Stripe payment → Google Sheets row

Goal: Log every successful Stripe payment to a Google Sheet for revenue tracking.

Modules:

  1. Webhooks > Custom Webhook — receive Stripe events
  2. Filter{{type}} equals payment_intent.succeeded
  3. Google Sheets > Add a Row — append payment data

Stripe setup:

  1. Go to Stripe DashboardDevelopersWebhooksAdd endpoint.
  2. Enter your Make webhook URL.
  3. Select payment_intent.succeeded event.
  4. Copy the signing secret for signature verification (Step 5 above).

Google Sheets row mapping:

ColumnMake variable
Date{{formatDate(now(); "YYYY-MM-DD")}}
Amount{{divide(data.amount; 100)}} (Stripe uses cents)
Currency{{data.currency}}
Customer email{{data.receipt_email}}
Payment ID{{data.id}}

Practical example 3: Custom app webhook trigger

If you are building an internal tool or a custom web application, you can fire Make scenarios programmatically with a simple HTTP call:

import requests
import json

MAKE_WEBHOOK_URL = "https://hook.eu2.make.com/YOUR_WEBHOOK_ID"

def trigger_make_scenario(event_type: str, payload: dict) -> bool:
data = {"event": event_type, **payload}
response = requests.post(
MAKE_WEBHOOK_URL,
headers={"Content-Type": "application/json"},
data=json.dumps(data),
timeout=10,
)
return response.status_code == 200

# Trigger when a new user signs up
trigger_make_scenario("user.signup", {
"user_id": "usr_abc123",
"email": "new@example.com",
"plan": "pro"
})

This fires your Make scenario with a structured payload. The scenario can then:

  • Send a welcome email via Gmail or Mailchimp
  • Create a CRM record in HubSpot or Pipedrive
  • Post a notification to Slack
  • Add the user to a Notion database

No SDK required — any language or framework that can make HTTP requests works identically.


Webhook limits and plan considerations

Make planMax webhooksInstant trigger latencyWebhook response timeout
Free2~1 second40 seconds
CoreUnlimited~1 second40 seconds
ProUnlimited~1 second40 seconds
Teams/EnterpriseUnlimited~1 second40 seconds

The Free plan limits you to 2 active webhooks. Upgrade to Make Core or above to remove this restriction.

Execution limits still apply. Each webhook delivery consumes one Make operation per module executed. Monitor your monthly operation count under Organization > Usage.


Troubleshooting common webhook issues

Webhook not firing

  • Confirm the external service shows the request as "delivered" (green checkmark in GitHub/Stripe webhook logs).
  • Check that your scenario is active (toggle in the top-right of the scenario editor). Inactive scenarios ignore incoming webhooks.
  • Verify the Content-Type header is application/json — Make does not auto-parse text/plain payloads.

Data structure not detected

  • Click Re-determine data structure in the webhook module settings after sending a new test payload.
  • If the payload is deeply nested (>10 levels), Make may truncate the preview. Map the raw body manually.

Webhook URL changed / rotated

Rotating the webhook URL (by deleting and recreating the webhook module) invalidates all existing integrations. To change the secret without rotating the URL, use the webhook's Custom Headers filter to require a shared secret in a header instead of in the URL path.

Duplicate executions

External services occasionally retry webhooks on network timeouts. Add a Data Store module at the top of your scenario to check whether you've already processed a given event ID. If the ID exists, filter out the execution.

[Custom Webhook] → [Data Store: search for event_id] → [Filter: not found] → [Processing...] → [Data Store: insert event_id]

FAQ

Frequently Asked Questions

Yes. Any app or service that can send an HTTP POST request can trigger a Make scenario — no native integration required. This includes GitHub, Stripe, Shopify, Typeform, custom scripts, internal APIs, and serverless functions. If the app supports outbound webhooks, it works with Make.

Scheduled triggers poll at a fixed interval (minimum 1 minute on paid plans, 15 minutes on free). Webhooks are instant — the scenario fires within milliseconds of the external event. Use webhooks for real-time reactions; use scheduled triggers for periodic batch jobs.

Yes, once created the URL remains active until you explicitly delete the webhook module. However, if you duplicate a scenario, the new copy gets a different webhook URL. Treat each URL as a separate endpoint — the original and the copy do not share the same URL.

Make Custom Webhooks accept GET requests, but payload data from GET requests is available as query string parameters (not a JSON body). For GET-based webhooks, map the data from {{1.query.your_param}}. Most webhook integrations use POST with a JSON body — only a few older services use GET.

Make marks the scenario run as an error and records it in the execution history. The webhook sender already received a 200 response (or your custom Webhook Response). Make does not automatically retry failed scenario executions — configure error handlers or incomplete execution recovery under Scenario Settings to handle failures gracefully.

Three complementary approaches: (1) Keep the URL private — it contains a long random token by default. (2) Verify HMAC signatures from services like GitHub and Stripe before processing the payload (see Step 5). (3) Add an IP allowlist filter using the {{1.remoteAddress}} variable if the sender publishes a fixed IP range.

Make webhooks parse JSON (application/json) and URL-encoded form data (application/x-www-form-urlencoded) natively. For multipart/form-data file uploads, the raw body is available but Make does not automatically parse attached binary files. Route file uploads through an intermediary (e.g., a serverless function) that extracts the file and sends the metadata + file URL to the webhook instead.


Next steps

Webhooks unlock the gateway to real-time Make automation. Once comfortable with custom webhooks, explore:

  • Make's built-in app triggers — hundreds of apps offer native instant triggers (Gmail, Slack, HubSpot) without needing a custom webhook
  • Subscenarios — modular workflows that other scenarios can call, replacing complex webhook-to-webhook chains
  • The Make API — programmatically create, enable, and run scenarios without the UI

If your workflow involves scraping data before triggering automation, consider pairing Make with ApifyApify Actors can push results directly to your Make webhook URL on completion, creating a seamless scrape-then-automate pipeline.