Agent skill

Make Webhooks Skill

Receive and authenticate requests sent by Make (formerly Integromat) scenarios through the HTTP > Make a request module. Use when building an endpoint that a Make scenario calls, securing it with an API key keychain header, debugging 401s from Make, or routing scenario payloads by an event field such as order.created or scenario.failed.

Install this skill

npx skills add hookdeck/webhook-skills --skill make-webhooks


Make scenarios push data to your app with the HTTP > Make a request module. Make does not sign these requests, so the webhook endpoint authenticates them with a secret header added through the module's API key keychain, and routes them by an event field you put in the body.

When to Use This Skill

  • How do I receive webhooks from a Make scenario?
  • How do I secure an endpoint that Make's HTTP module calls?
  • How do I verify the API key header Make sends?
  • Does Make sign webhook requests? (No: use a shared secret header)
  • Why does my Make HTTP module get a 401 from my webhook endpoint?

Verification (core)

Create an API key keychain on the module with API key placement In the header, an API key parameter name of your choice, and a Key that Make sends exactly as entered (including any prefix such as Bearer ). If Restrict requests to service URLs is on, add your endpoint's origin to Allowed service origins, because Make sends the key only to the origins listed there. The endpoint compares the whole header value:

const crypto = require('crypto');

// Hash both sides: equal-length buffers, so timingSafeEqual never throws.
function safeEqual(a, b) {
  const ha = crypto.createHash('sha256').update(String(a)).digest();
  const hb = crypto.createHash('sha256').update(String(b)).digest();
  return crypto.timingSafeEqual(ha, hb);
}

function verifyMakeRequest(headers, config = process.env) {
  const expected = config.MAKE_WEBHOOK_SECRET;
  if (!expected) return false; // never accept when unconfigured

  const headerName = (config.MAKE_WEBHOOK_HEADER || 'Authorization').toLowerCase();
  const received = headers[headerName]; // req.headers has lowercased keys
  return typeof received === 'string' && safeEqual(received, expected);
}

MAKE_WEBHOOK_HEADER (default Authorization) is the parameter name and MAKE_WEBHOOK_SECRET is the exact, whole value, including any Bearer prefix you typed into Make. Don't strip or parse the prefix. Return 401 for a missing header or a mismatch.

A static shared credential authenticates the sender, not the body. There is no signature and no timestamp, so it gives no replay protection: use HTTPS, rotate the key in Make and in your app if it leaks, and dedupe on an id in the body if replays matter. Query-string key placement can't be checked reliably, so use the header placement.

The method is whatever you pick in the module, so accept POST, PUT, PATCH, DELETE and GET, and tolerate an empty body. Read the raw body (express.raw({ type: '*/*' })) and parse JSON only after the credential check passes.

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Event Types

Make has no built-in webhook event types; the payload is whatever the scenario maps. Send {"event": "...", "id": "...", "data": {...}} and dispatch on event. The examples use:

EventSent When
order.createdA scenario sees a new order
lead.createdA scenario captures a new lead
scenario.completedA long-running scenario finishes
scenario.failedAn error-handler route reports a failure

These names are a convention for the examples, not Make-defined events.

Environment Variables

MAKE_WEBHOOK_SECRET=Bearer replace-with-a-long-random-secret   # exact header value, as typed in Make
MAKE_WEBHOOK_HEADER=Authorization                               # API key parameter name

Local Development

Make's cloud can't reach localhost. Tunnel with the Hookdeck CLI (no account required):

npx hookdeck-cli listen 3000 make --path /webhooks/make

Use the printed URL as the HTTP module's URL (Make only allows HTTPS).

Resources


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 5, 2026

View on GitHub →