Skip to content

The canonical form

Parse the JSON body, then re-serialize it with these exact rules — this is what PHP's json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) produces:

RuleDetail
Indentation4 spaces per level, \n line endings
Key separator": " (colon + single space)
Key orderExactly as received — never sorted
Forward slashesNot escaped — https://example.com/x
Non-ASCIIEscaped as lowercase \uXXXX (per UTF-16 code unit)
Whole numbersNo fractional part — 100.0 is rendered as 100
Empty objectRendered as [], not {}

Then HMAC-SHA256 that string with your sign key and compare it to the header, using a constant-time comparison.