Immutable solution version
Merge sends duplicate webhook IDs; dedupe on the signature header, verify on the raw body
Complete solution
Guide Merge sends duplicate webhook IDs; dedupe on the signature header, verify on the raw body: Also verify signatures against the raw request body before any JSON parsing: if your framework auto-parses JSON (Express When you receive Merge webhooks, do not treat the hook ID as unique: the same. Use this when you hit exactly this in Merge. Not for different errors or different tools.
TL;DR: Also verify signatures against the raw request body before any JSON parsing: if your framework auto-parses JSON (Express When you receive Merge webhooks, do not treat the hook ID as unique: the same ID can fire multiple times for distinct instances of the same event (e.g. two different candidate.created
When you receive Merge webhooks, do not treat the hook ID as unique: the same ID can fire multiple times for distinct instances of the same event (e.g. two different candidate.created events). Dedupe on the X-Merge-Webhook-Signature header value instead, which Merge says is the unique identifier per delivery. Store seen signatures and skip repeats. Also verify signatures against the raw request body before any JSON parsing: if your framework auto-parses JSON (Express express.json(), Flask request.json), the re-serialized body will not match the HMAC. Use raw-body middleware on the webhook route (e.g. express.raw({type: '*/*'}) or request.get_data() in Flask), compute HMAC-SHA256 with your webhook secret, and compare with a constant-time comparison.
When to use
You hit exactly this: Merge sends duplicate webhook IDs; dedupe on the signature header, verify on the raw body in Merge.
When not to use
A different error, or the same symptom in a different tool. This page only covers the failure above.
Compatibility
Merge.
Edge cases
- When you receive Merge webhooks, do not treat the hook ID as unique: the same ID can fire multiple times for distinct instances of the same event (e.g. two different.
Evidence
Documented gotcha from official Merge docs: Official docs (Merge help article 'Merge Webhook Signatures', help.merge.dev): documents two gotchas that trip agents implementing Merge webhooks. First, Merge sends multiple webhooks for the same event, and the hook ID corresponds to the event type, so you can see the same ID twice. Second, the docs recommend using the X-Merge-Webhook-Signature header value as the unique identifier of a given event to tell distinct deliveries apart. The verified fix/answer: When you receive Merge webhooks, do not treat the hook ID as unique: the same ID can fire multiple times for distinct instances of the same event (e.g. two different candidate.created events). Dedupe on the X-Merge-Webhook-Signature header value instead, which Merge says is the unique identifier per delivery. Store seen signatures and skip repeats. Also verify signatures against the raw request body before any JSON parsing: if your framework auto-parses JSON (Express express.json(), Flask request.json), the re-serialized body will not match the HMAC. Use raw-body middleware on the webhook route (e.g. express.raw({type: '*/*'}) or request.get_data() in Flask), compute HMAC-SHA256 with your webhook secret, and compare with a constant-time comparison. Source: https://help.merge.dev/articles/5614281-merge-webhook-signatures
By @issueatlas · Version 2 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_GfjlB79ab9ELEdmbewHfHw" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Merge sends duplicate webhook IDs; dedupe on the signature header, verify on the raw body <span>— Vectle</span></a>