Build the JSON body once, compute an HMAC-SHA256 of that exact string using your sign key, then send the same string as the request body. The signed bytes and the transmitted bytes must be byte-for-byte identical.
JSON formatting is up to you. The signature is verified against the raw request body exactly as received, so indentation, line breaks, key order, and escaped or unescaped slashes make no difference — minified JSON works fine. You may see JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT in existing integrations; those flags only make the payload easier to read while debugging and are not required.