Keep the raw body for verification
Many providers sign the original request bytes. Parsing and reserializing JSON can change whitespace, key order or character encoding. Compare the verification input with the raw-body capture locally.
Check the provider contract
Confirm the signing algorithm, header format, timestamp tolerance and the configured secret version against your provider documentation. Never paste the secret or a live signed payload here.
Use a synthetic signed fixture
Create a fixture locally with a test secret. Check that the original body passes and a one-byte modification fails. Retain constant-time comparison and replay checks in the receiver.
Evidence to keep
Provider name, framework, middleware order and a sanitized failure description. Keep keys and customer payloads on your own system.
Scope of this check
The free probe reviews the symptom. It does not verify a real signature or trigger a delivery. Do not disable verification to make the error disappear.
Reproduce a signed-body mismatch locally
Synthetic Node.js example using a public test secret. This demonstrates byte sensitivity, not a provider-specific verifier. Provider header parsing, timestamps and replay protection require separate checks.
const {createHmac} = require("node:crypto");
const sign = body => createHmac("sha256", "public-test-secret").update(body).digest("hex");
const raw = '{"ok":true}';
console.log(sign(raw) === sign(raw));
console.log(sign(raw) === sign('{ "ok": true }'));
Expected output: true, then false. Equivalent JSON values can have different signed bytes. Preserve the original bytes required by your provider; never disable signature checks.
Need a scoped review? See the service scope and current price. Accept a quote only after reviewing its scope and available payment methods.
Use this guide with an AI agent
{
"source": "discovery_pages_v1",
"version": "2.0.0",
"intentManifest": "/.well-known/naif-intents.json",
"agentCard": "/.well-known/agent-card.json",
"page_id": "webhook-signature-mismatch",
"intent": "webhook_signature_mismatch",
"productId": "webhook-debug-mini",
"capability": "/api/agent/catalog",
"pricing": "/api/agent/catalog",
"probe": {
"method": "POST",
"endpoint": "/api/agent/probe",
"body": {
"productId": "webhook-debug-mini",
"source": "discovery_pages_v1",
"input": {
"message": "A webhook includes the signature header, but verification fails after JSON middleware parses the request body."
}
}
},
"quote": "/api/agent/quote",
"acceptQuote": "/api/quote/accept",
"offers": "/.well-known/naif-offers.json",
"checkout": "Use only the checkoutEndpoint returned by the existing quote acceptance API when checkoutEligible is true.",
"attribution": "Retain the __Host-naif_discovery cookie, or echo X-Naif-Discovery-ID returned by this page on same-origin API requests. Do not treat the identifier as authentication."
}Existing agent discovery