Documentation

Automate Merlonix with Zapier, Make & n8n

Every Merlonix monitoring event — an SSL certificate about to expire, a DNS record that changed, a status-page incident, a fired alert — can trigger an action in whatever tools you already run. Log it to a spreadsheet, open a ticket, post to a channel, page an on-call engineer, or kick off a client workflow.

There are two ways to connect, both using shipped, production capabilities and neither requiring us to publish a marketplace app first:

  1. Real-time webhooks (recommended). Merlonix POSTs a signed JSON event to a URL you control the instant something happens. Point that URL at a Zapier, Make, or n8n "catch webhook" step and you are done.
  2. Polling the REST API. Some no-code platforms prefer to pull. GET /v1/alerts?since=<timestamp> returns everything new since your last poll.

Real-time webhooks are lower-latency, cheaper on task quota, and do not miss events between polls. Use polling only when a platform cannot receive an inbound webhook.


Which events you can subscribe to

A webhook destination subscribes to one or more of these event types:

EventFires when
cert.expiring_30dA monitored certificate crosses 30 days to expiry
cert.expiring_7dA monitored certificate crosses 7 days to expiry
cert.renewedA previously-expiring certificate is observed renewed
dns.changedA monitored DNS record drifts from its baseline
incident.createdA status-page incident is opened
incident.resolvedA status-page incident is resolved
alert.firedAny monitoring alert fires (SSL, DNS, uptime, vendor, and more)
alert.suppressedAn alert is suppressed (e.g. inside a maintenance window)

alert.fired is the broadest hook — subscribe to it alone if you just want "tell me the moment anything needs attention."


Setting up a real-time webhook

1. Create the catch URL on your automation platform

Create the inbound step first so you have a URL to register:

  • Zapier — new Zap, trigger app Webhooks by Zapier → Catch Hook. Copy the custom webhook URL.
  • Make — new scenario, module Webhooks → Custom webhook. Add it and copy the address.
  • n8n — add a Webhook node, set it to POST, and copy the production URL.

2. Register the destination in Merlonix

Either add it in the app (open Settings → Webhooks → Add destination) or call the API:

POST /v1/webhooks
Authorization: Bearer <your-api-token>
Content-Type: application/json

{
  "name": "Zapier — alerts",
  "url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
  "events": ["alert.fired", "cert.expiring_7d", "incident.created"]
}

The response includes the destination's signing secret in full — store it, it is what you use to verify signatures (see below). The URL must be a public HTTPS address; private, loopback, and cloud-metadata addresses are rejected.

3. Send a test delivery

Fire a test so your platform's step sees a real sample payload to map fields from:

POST /v1/webhooks/{id}/test
Authorization: Bearer <your-api-token>

Then finish building the Zap / scenario / workflow against the fields in the received payload.


The payload

Every delivery is a POST with this JSON body:

{
  "event": "cert.expiring_7d",
  "created_at": "2026-07-09T14:03:11.482Z",
  "data": {
    "...": "event-specific fields"
  }
}

And these headers:

HeaderValue
X-Merlonix-EventThe event type, e.g. alert.fired
X-Merlonix-DeliveryA unique delivery id (use it to dedupe)
X-Merlonix-Signaturet=<unix_ts>,v1=<hmac_hex>
User-AgentMerlonix-Webhooks/1.0

For most no-code recipes you can consume the payload directly. If you want to be certain a request genuinely came from Merlonix (recommended for anything that changes data), verify the signature.

Verifying the signature

The signature is Stripe-style: v1 is HMAC-SHA256(secret, "<t>.<raw_request_body>"), hex-encoded, where <t> is the t= value in the header.

import crypto from 'node:crypto';

function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${parts.t}.${rawBody}`)
    .digest('hex');
  // constant-time compare
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1 ?? '');
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300; // reject stale
  return fresh && a.length === b.length && crypto.timingSafeEqual(a, b);
}

In Make or n8n, run this in a code/function module. Zapier's Catch Hook does not expose the raw body byte-for-byte, so for signature verification prefer a Code by Zapier step or the polling path instead.

Delivery guarantees

  • Retries: one immediate attempt, then up to six retries at 1m, 5m, 30m, 2h, 6h, and 24h. Return any 2xx to acknowledge; a non-2xx or timeout (10s) schedules the next retry.
  • Auto-disable: a destination that exhausts 20 deliveries in a row is disabled to stop hammering a broken endpoint — re-enable it from Settings → Webhooks once it is fixed.
  • Ordering: deliveries are independent; do not assume strict order. Use created_at and X-Merlonix-Delivery to order and dedupe.

Recipe: Zapier

  1. Trigger: Webhooks by Zapier → Catch Hook → copy the URL.
  2. Register the URL in Merlonix (step 2 above) for the events you care about.
  3. Fire a test delivery so Zapier captures a sample.
  4. Action: anything — Google Sheets (append row), Jira/Trello (create issue), Slack, Notion, Airtable, Twilio. Map the payload's event, created_at, and data.* fields.

Optional filter step: only continue when event is alert.fired and the alert severity is critical, so low-priority notices don't create tickets.

Recipe: Make (Integromat)

  1. Add Webhooks → Custom webhook, copy the address, register it in Merlonix.
  2. Run Determine data structure and send a Merlonix test delivery so Make learns the schema.
  3. Chain modules: a Router on event type, then per-branch actions (a Data Store log for dns.changed, a PagerDuty incident for incident.created, etc.).
  4. Add a Set variable / Code module first if you want signature verification.

Recipe: n8n

  1. Webhook node, method POST, copy the production URL, register it in Merlonix.
  2. A Function node verifies the signature (paste the snippet above; n8n exposes the raw body).
  3. Switch node on {{$json.event}} routes each event type to its own downstream nodes.

Polling alternative

If a platform cannot receive an inbound webhook, poll for new alerts on a schedule:

GET /v1/alerts?since=2026-07-09T00:00:00Z&limit=50
Authorization: Bearer <your-api-token>
  • Store the newest fired_at (or created_at) you have seen and pass it as since next run to fetch only new rows.
  • Dedupe on each alert's id — Zapier's polling triggers do this automatically when you return the id as the dedupe key.
  • Poll no more often than your plan's rate limit allows (see API Integration Reference → Rate limits). Every 5–15 minutes is plenty for alert-driven workflows.

What you can build

A few honest examples using only shipped capabilities:

  • Alert log — append every alert.fired to a Google Sheet or Airtable base for an auditable client-facing record.
  • Ticketing — open a Jira/Linear/Trello card on incident.created, and close or comment on incident.resolved.
  • Renewal reminders — on cert.expiring_30d, create a task for the client or the person who owns that domain's DNS.
  • Escalation — route alert.fired where severity is critical to PagerDuty or Opsgenie. (Merlonix also has native PagerDuty and Opsgenie alert channels if you would rather skip the middleware.)
  • Change record — log every dns.changed to your change-management system so DNS drift is documented, not just noticed.

Next: the full endpoint reference — request formats, every field, and pagination — is in the API Integration Reference. To route alerts without any middleware, see Alert Channels (Slack, PagerDuty, Opsgenie, Teams, Telegram, SMS, and generic webhooks are built in).