When it fires
Either:- an
X-Kash-Signatureheader was sent and did not verify, or - the key is configured to require signed requests and the request carried no
X-Kash-Signatureheader.
X-Kash-Signature skips the check. Once the header is present, it must verify.
Why it happens
- The body changed in transit (a proxy re-encoded the JSON, or an HTTP client normalised whitespace).
- The timestamp is outside the ±5 minute tolerance (clock skew).
- The signature was computed over the wrong input. Common mistakes: signing the full URL instead of the path, or omitting the leading slash.
- The wrong secret was used, for example your webhook secret instead of the API key.
How to fix
- Signing input:
${unixMillis}.${UPPERCASE_METHOD}.${pathWithLeadingSlash}.${rawBody}. Use the raw body bytes you send, not re-serialised JSON. The path excludes the query string. - Key the HMAC-SHA256 with the API key itself (the same value you send in
X-API-Key). - Header format:
X-Kash-Signature: t=<unixMillis>,v1=<hexHmacSha256>. - Keep your clock in sync (NTP).
- Read the
detailfield. It says which check failed: a malformed header, a missingv1value, a timestamp outside the tolerance, or a signature that does not match.
Related codes
API_KEY_MISSING/API_KEY_INVALID— earlier failure points