--- title: Manually Verifying Webhook Signatures | PostGrid description: How to manually verify PostGrid webhook signatures using HMAC-SHA256 when receiving payloads as JSON rather than JWT. --- PostGrid supports sending webhook payloads in two separate formats: a [JSON web token](https://jwt.io/) (JWT) and regular JSON. Verifying the JWT with your webhook’s secret is [straightforward ](https://jwt.io/libraries)and automatically ensures that the payload was sent by PostGrid and is [recent enough](https://en.wikipedia.org/wiki/Replay_attack). However, you may prefer to receive the payload as JSON since this is typically easier to integrate into existing codebases/tools. If you choose to do this, it is up to you to verify the request is sent by PostGrid. You will have to: 1. Get the raw body of the request 2. Extract the signature header value 3. Calculate the HMAC of the raw body using the SHA-256 hash function and the secret; and 4. Compare the calculated HMAC with one sent in the `PostGrid-Signature` header, making sure that both values use the same encoding. ## Verifying the webhook signature PostGrid will make the request to your webhook endpoint with a `PostGrid-Signature` header. Here’s an example of what that will look like: ``` PostGrid-Signature: t=1718932335515,v1=e888f596cf2db26b2f58631cb28d620882022c5727a8f5a558f328f8d886e11d ``` This signature begins with the timestamp (unix milliseconds) that PostGrid made the request, and is followed by a hash-based message authentication code ([HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code)) using [SHA-256](https://en.wikipedia.org/wiki/SHA-2). **Step 1: Extract the timestamp and signatures from the header** 1. Split the header using the `,` character. This gets a list of elements consisting of the timestamp `t`, and the corresponding signature `v1`. 2. Split each element using the `=` character as the separator. This gives a prefix and value pair for both the timestamp, `t` and signature `v1`. **Step 2: Prepare the`signedPayload` string** The `signedPayload` string is created by concatenating - The timestamp, `t` (as a string) + - A period `.` + - The raw body of the request (JSON with no whitespace) **Step 3: Determine the expected signature** Compute the HMAC of the the`signedPayload` (message/**expected signature**) by using the SHA256 algorithm and secret key (*found in the ‘Additional Information’ of the ‘Webhook Details’ section in the dashboard*) **Step 4: Compare the signatures** Compare the signature, `v1` from the header, to the newly calculated **expected signature**. If they do not match the webhook event should be rejected. To prevent timing attacks, use a constant-time-string comparison to compare the expected signature with each of the received signatures.