---
title: "Webhook Signature Verifier: Check HMAC SHA256 Online"
description: "Verify an HMAC SHA256 webhook signature in your browser with the Web Crypto API. Nothing is uploaded. Includes code for Node, Python and Go."
url: https://kairopost.com/tools/webhook-signature-verifier
---

# Webhook signature verifier

Check an HMAC SHA256 webhook signature: compute it over the exact signed payload with your secret, encode it like the sender and compare in constant time. Every step is shown.

- Runs in your browser
- Nothing uploaded
- No sign up

Live. Everything runs on your device. Nothing is uploaded

## How to verify a webhook signature

The console opens with a valid request. Change one character in the body and watch stage five fail.

1. ### # 1 choose the scheme: Pick the Kairo Post preset, a generic preset, or set the scheme yourself.
2. ### # 2 paste the secret: Enter a test secret and say whether it is text, hex or base64.
3. ### # 3 paste the headers: Paste the request headers as Name: value lines.
4. ### # 4 paste the raw body: Paste the body exactly as it arrived, before any JSON parsing.
5. ### # 5 read the pipeline: Follow the five stages; on a mismatch the tool names the likely cause.

## Why webhook signatures need a constant time comparison

`==` stops at the first differing byte, so a guess that starts right takes slightly longer to reject. Measured often enough, that rebuilds a signature one character at a time.

Use this, not ==

- Node `crypto.timingSafeEqual`
- Python `hmac.compare_digest`
- Go `hmac.Equal`

Node's version throws on different lengths, so check length first. Length is not secret.

## Webhook verification code for Node, Python and Go

Each example reads the raw body, rejects stale timestamps and compares in constant time before parsing anything.

Another sender? Change three things

1. 1 Signed string `often just {body}`
2. 2 Encoding `digest("base64") or b64encode`
3. 3 Prefix `sha256=, v1= or none`

## Common webhook signature failures

Nearly every failed check is one of these. The console tests several for you on a mismatch.

| failure | symptom | fix |
| --- | --- | --- |
| Parsed body, not raw | Always mismatches | Verify raw bytes before any JSON middleware. |
| Wrong output encoding | Twice as long, or has + and / | SHA256 hex is 64 characters; base64 is 44. |
| Secret decoded wrongly | Mismatch with the right secret | Decode a hex secret to bytes first. |
| Missing or extra prefix | Everything after the prefix matches | Add or strip v1= or sha256= before comparing. |
| Trailing newline | Only pasted or logged bodies fail | Test with the body from the request, not a log. |
| Clock skew | Valid, rejected as stale | Use network time; allow a window both ways. |
| Header renamed by a proxy | Signature header is empty | Log the header names your app receives. |
| Wrong character encoding | Fails only with accents or emoji | Verify bytes; decode UTF-8 afterwards. |

## Webhook replay protection with timestamps

A valid signature proves who sent a request, not that it is new. A captured request would verify again.

- ### Sign the timestamp: Then changing it breaks the signature, and keeping it ages the request out. Check both directions.
- ### Store delivery ids: Keep every accepted id for at least the window and skip repeats. Retries become harmless too.

## How Kairo Post signs its webhooks

Kairo Post can send signed events, such as a finished publish or an approval request, to an HTTPS endpoint you control. This is what our delivery code does.

**Algorithm**

HMAC SHA256

**Key**

32 random bytes, shown once as 64 hex characters

**Signed payload**

{id}.{timestamp}.{body}

**Signature header**

Kairo-Webhook-Signature: v1=<64 hex>

**Delivery id**

Kairo-Webhook-Id: a UUID

**Timestamp**

Kairo-Webhook-Timestamp: Unix seconds

**Key id**

Kairo-Webhook-Key-Id: which secret signed it

**Other headers**

Content-Type: application/json, User-Agent: KairoPost-Webhooks/1.0

### Delivery rules

- Public HTTPS on port 443: No credentials or query string in the URL.
- Bodies up to 16 KB: Our reference verifier allows 300 seconds of clock difference.
- Any 2xx is delivered: Redirects are never followed; 10 second timeout.
- New endpoints start switched off: Install the secret first. Rotating switches it off and cancels queued deliveries.

Retries on 408, 425, 429, 5xx · up to 8 attempts

1. 30s
2. 2m
3. 10m
4. 1h
5. 6h
6. 12h
7. 24h

A Retry-After header can lengthen a wait, up to 24 hours.

[Read about the API and webhooks](https://kairopost.com/features/developers) [All tools](https://kairopost.com/tools)

## $ man webhook signatures

### How do I verify an HMAC SHA256 webhook signature?

Build the signed string the sender describes, compute HMAC SHA256 over it with the shared secret, encode it the same way (hex or base64), and compare with the signature header in constant time.

### Is it safe to paste my webhook secret here?

The tool runs in your browser with the Web Crypto API and sends nothing anywhere. Even so, use a test secret, and rotate any live secret you have pasted into a web page.

### Why does my signature not match?

Usually a parsed and reserialised body instead of raw bytes, hex versus base64, a hex secret read as text, a missing prefix such as sha256=, or a trailing newline.

### What is a constant time comparison?

One that takes the same time wherever the strings differ. A normal equality check stops at the first difference, which can leak how much of a guessed signature was right.

### Why do webhooks include a timestamp?

So receivers can reject old requests. When the timestamp is part of the signed payload, a captured request cannot be replayed later without failing the age check.

### How does Kairo Post sign webhooks?

HMAC SHA256 over id.timestamp.body with the endpoint secret decoded from hex, sent as v1= plus the hex digest in Kairo-Webhook-Signature, beside Kairo-Webhook-Id and Kairo-Webhook-Timestamp.

### Which algorithms does this tool support?

HMAC with SHA-256, SHA-384, SHA-512 and SHA-1, the hashes Web Crypto offers. SHA-1 is only there for old integrations. There is no sign up and no cost.

Building on X as well? Estimate API usage with the [X API cost calculator](https://kairopost.com/tools/x-api-cost-calculator).

Written by

Jonas Ben

, founder of Kairo Post. Updated

30 September 2026

.

## More tools

[All tools](https://kairopost.com/tools)

- [X API cost calculator Estimate API usage for your posting volume.](https://kairopost.com/tools/x-api-cost-calculator)
- [UTM link builder Tag links so you know which posts drive visits.](https://kairopost.com/tools/utm-builder)
- [X character counter Count characters exactly the way X does.](https://kairopost.com/tools/x-character-counter)

## Post at the right moment. Starting today.

Connect an account, describe your voice and let Kairo Post do the legwork.

[Get started](https://app.kairopost.com/signup) [See pricing](https://kairopost.com/pricing)
