Meet us at Money 20/20 in Amsterdam

Unified API Webhook Security: Authenticating Webhooks

Webhook security is where unified API integrations either earn enterprise trust or quietly lose it. In our first webhooks article we mapped the fragmented landscape of webhooks across ERP and accounting systems. This follow-up is the developer's guide to the other half: how Maesn authenticates every webhook so you can prove it came from us, why accounting webhook signature verification matters at scale, and exactly how to implement it.

Author Image

Dr. Themo Voswinckel

June 2, 2026

Unified API Webhook Security: Authenticating ERP & Accounting Webhooks

Key Takeaways

  • Every event is signed. All webhook events delivered to your callback URL include an X-MAESN-SIGNATURE header containing an HMAC-SHA256 signature — the foundation of webhook security across the Maesn Unified API.
  • Verification is three steps. Read the header, compute HMAC-SHA256 over the raw request body using your webhook secret, and compare. A match confirms authenticity and integrity.
  • The raw body is non-negotiable. Sign the exact bytes you received, before any JSON parsing. Re-serialized JSON will not match.
  • One model for every system. Webhook authentication and webhook signature verification work identically whether the event is native or a Maesn synthetic webhook.
  • Security by design. Signed events sit alongside Maesn's ping-and-pull payloads and no-storage architecture as one coherent, compliance-first security posture.

In Short: How Maesn Secures Unified Webhooks

Maesn signs every webhook event with an HMAC-SHA256 signature delivered in the X-MAESN-SIGNATURE header. To verify it, recompute the HMAC over the raw request body using your webhook secret and compare the result to the header value — a match proves the event is authentic and unaltered. The same signature model applies to every connected ERP and accounting system, whether the event comes from a native or a synthetic webhook.

Unified Webhooks Cover Every Accounting and ERP System — Native or Synthetic

Maesn delivers a single, unified webhook for every connected accounting and ERP system, regardless of whether the underlying platform offers native webhooks. If you have read the landscape article, skip ahead. For everyone else: webhook support across ERP and accounting software is wildly inconsistent — some systems offer native, user-based webhooks, many offer none at all, payload styles differ, and object coverage has gaps.

Maesn collapses this fragmentation into one model. Subscriptions are created per customer, events follow one consistent structure, and the same security-first ping-and-pull pattern applies across the board. For systems without native webhooks — or with limited object coverage — Maesn emits synthetic webhooks, monitoring the source via polling and delivering the result as a unified event. From your application's point of view, a native webhook from Xero and a synthetic webhook for an object QuickBooks never exposed look identical.

A typical event body looks like this:

{
    "eventType": "CREATED",
    "filterDate": "2023-10-01T00:00:00Z",
    "resource": "INVOICE",
    "resourceId": "bca91f06-0414-4b24-81fa-8489105afceb"
}

In keeping with ping-and-pull, the event tells you what changed, not the full record — you fetch the details with a follow-up API call when you need them. That keeps payloads small, keeps sensitive data off the wire, and keeps the contract identical across every system. But a unified, well-structured event is only enterprise-ready if you can trust where it came from. That is the job of authentication.

An Unauthenticated Webhook Endpoint Is an Open Door

An unauthenticated callback URL will process any request that reaches it, including forged ones. A callback URL has to be publicly reachable — that is the whole point, since Maesn POSTs to it from the outside. The catch is that anyone else who learns or guesses that URL can POST to it too.

Without verification, your endpoint cannot distinguish a genuine Maesn event from a fabricated one. An attacker who knows the URL can forge an event — "invoice paid," "customer updated" — and your integration will act on it. Even an honest misconfiguration, like another service pointed at your endpoint, can inject events you never intended to process. In ERP and accounting workflows, where an event can trigger a payment, a booking, or a downstream sync, acting on an unverified request is not a risk worth taking.

A Signature Turns "Probably Us" Into "Provably Us"

Maesn makes every legitimate event carry cryptographic proof of origin that an attacker cannot reproduce. Each event is signed with a secret only you and Maesn know, so your endpoint can verify authenticity before it processes anything.

Maesn Authenticates Every Webhook Event with HMAC-SHA256

Maesn signs every webhook event with an HMAC-SHA256 signature delivered in the X-MAESN-SIGNATURE header. When you create a webhook, Maesn returns a webhook secret — keep it safe, because it is the shared key behind every signature and anyone who has it can forge events.

The signature is a keyed hash computed over the event body using your webhook secret. HMAC gives you two guarantees in one value:

  • Authenticity — only a party holding the secret could have produced the signature, so a valid signature means the event genuinely came from Maesn.
  • Integrity — the signature is bound to the exact body. Change a single byte of the payload and the signature no longer matches, so you know the event was not altered in transit.

Because the secret never travels with the request, an attacker who intercepts or guesses your callback URL still cannot generate a valid signature. This is the core of ERP webhook authentication on the Maesn Unified API.

Verify a Maesn Webhook Signature in Three Steps

Accounting webhook signature verification on your side takes three steps:

  1. Read the signature from the X-MAESN-SIGNATURE header.
  2. Compute the HMAC-SHA256 of the raw request body using your webhook secret.
  3. Compare the value you computed with the value from the header. If they are equal, the event is authentic.

In Node.js:

const crypto = require('crypto');

const expectedSig = crypto
  .createHmac('sha256', Buffer.from(secret, 'hex'))
  .update(body)
  .digest('hex');

const isValid = expectedSig === headerSig;

Two details trip people up. First, the secret is hex-encoded, so decode it with Buffer.from(secret, 'hex') rather than passing the string directly — the wrong key bytes produce a signature that never matches. Second, update(body) must receive the raw payload, which brings us to the single most common mistake.

Always Verify Against the Raw Body, Not the Parsed JSON

The signature is computed over the exact bytes Maesn sent, so you must verify against those exact bytes. The moment you parse the body into a JSON object and re-serialize it, you risk changing them — key ordering, whitespace, and number formatting can all shift — and your recomputed signature will not match a valid event.

Most frameworks parse the request body automatically, which means the raw bytes may already be gone by the time your handler runs. Capture the raw body before any JSON middleware touches it, verify the signature against those bytes, and only then parse. In Express, configure your body parser to retain the raw buffer for the webhook route. Verify first, parse second.

Harden Your Handler With Two Receiver-Side Practices

Signature verification is the core control; two standard practices on your end make the integration more robust. They live entirely in your handler and complement the signature check rather than replacing it:

  • Compare in constant time. A plain === comparison can, in principle, leak information through timing. Once you have both hex strings, a constant-time comparison such as crypto.timingSafeEqual is a small, free hardening step.
  • Make processing idempotent. Networks retry, and the same event may arrive more than once. Keying your processing on resourceId and the event type — so handling the same event twice is harmless — protects you from duplicate side effects like double bookings.

Webhook Authentication, Ping-and-Pull and No-Storage Form One Security Posture

Signed events are one layer of a security model Maesn applies end to end, not an isolated feature. Ping-and-pull means the webhook carries identifiers, not business data — so even a delivered event exposes very little. The HMAC signature means you can trust every event before acting on it. And Maesn's no-storage architecture means the platform routing those events never retains a copy of your customers' data in the first place.

Taken together — signed delivery, minimal payloads, no shadow copies, EU-only hosting, ISO 27001 and GDPR compliance — security is an architectural property of the system, not something layered on afterward. For teams that have to answer "how is this secured?" to auditors and customers, the answer is the same at every layer.

One Signature Model Secures Every ERP and Accounting Integration

The same verification routine works for every connected system, which is where unified API webhook security pays off. Native webhook implementations across ERP and accounting platforms handle authentication very differently — different headers, different schemes, different secret-handling rules, and in many cases nothing at all. Maintaining a separate verification routine per system is exactly the fragmentation Maesn removes.

With Maesn, every event — from a system with mature native webhooks, from a system with none, or generated as a synthetic webhook through polling — arrives with an X-MAESN-SIGNATURE header you verify the same way. Customer-based webhooks are currently supported across systems including Business Central, Exact Online, FreshBooks, Lexware Office, Moneybird, Qonto, QuickBooks, weclapp and Xero, with synthetic webhooks extending unified, signed delivery to the rest.

Write Your Verification Once, Trust Every System

You implement signature verification a single time, and it then applies to every connected system and every future one you add — no per-system authentication logic, no special cases. That is what makes secure webhooks practical across a multi-system accounting integration.

Ready to build on it? See the Webhooks documentation for the full setup and verification reference, or book a demo to see Unified Webhooks in action.

About the author

Themo is CEO and Co-Founder of Maesn. With years in strategy consulting — spanning requirements engineering for complex software landscapes, ERP and accounting software selections, and end-to-end integration projects — he holds a Dr.-Ing. with a focus on ERP-to-SaaS transformation. He co-founded Maesn to make system integration effortless.

Dr. Themo Voswinckel

Co-Founder

Frequently asked
questions

You have more questions? We are looking forward hearing from you - book a meeting now!

How do I secure webhooks from a unified API like Maesn?

Verify the signature on every incoming event. Maesn signs each webhook with an HMAC-SHA256 signature in the X-MAESN-SIGNATURE header; recompute the HMAC over the raw request body with your webhook secret and compare. Processing only verified events is the foundation of webhook security across a unified API.

How does Maesn handle ERP webhook authentication across different systems?

Identically for every system. Whether an event comes from a system with native webhooks or from a Maesn synthetic webhook, it arrives with the same X-MAESN-SIGNATURE header and is verified the same way — so you write your ERP webhook authentication logic once.

How do I perform accounting webhook signature verification?

Read the signature from the X-MAESN-SIGNATURE header, compute the HMAC-SHA256 of the raw request body using your webhook secret, and compare the two values. A match confirms the event is authentic and was not altered in transit.

Where do I get the webhook secret?

The secret is returned when you create the webhook. Store it securely — it is the shared key used to generate and verify every signature, so anyone with it could forge events.

Why must I use the raw request body?

The signature is computed over the exact bytes Maesn sends. Parsing the body to JSON and re-serializing it can change those bytes (ordering, whitespace, number formatting), so a signature recomputed from parsed JSON may not match a valid event. Capture and verify the raw body before parsing.

Are events from systems without native webhooks signed too?

Yes. For systems without native webhook support, Maesn emits synthetic webhooks delivered in the same unified format and carrying the same X-MAESN-SIGNATURE header, so your verification logic is identical across every system.

Does signature verification replace transport security?

No, they complement each other. All communication with Maesn uses HTTPS, which protects data in transit; the signature additionally proves the origin and integrity of each individual event at your endpoint.

Kickstart your Integration Journey now