SECRET can generate a valid signature.
How it works
Step by step
- Wavy Node builds a canonical message from: HTTP method, path, body, and timestamp
- Signs that message with HMAC-SHA256 using the shared SECRET
- Sends the request with two extra headers:
x-wavynode-hmac— the generated signaturex-wavynode-timestamp— the timestamp in milliseconds
- Your server receives the request
- Recalculates the signature using the same SECRET and request data
- If signatures match → the request is legitimate (200). If not → reject it (401)
The shared SECRET
The SECRET is a 32-character hex string that both sides know:| Location | How to configure |
|---|---|
| Wavy Node dashboard | Settings → Integración → Integration Secret |
Your server (.env) | SECRET=615d9b7ea991acfa33f823c374c3a062 |
Generate a new SECRET
Authentication headers
Every request from Wavy Node includes these headers:| Header | Type | Description |
|---|---|---|
x-wavynode-hmac | string | Base64 encoded HMAC-SHA256 signature of the canonical message |
x-wavynode-timestamp | string | Timestamp in milliseconds (epoch) |
Canonical message
The signature is not calculated on the raw request, but on a standardized canonical message. This ensures both sides build exactly the same string before signing. The canonical message is formed by concatenating these values separated by:::
- The uppercase HTTP method (
GET,POST, etc.) - The lowercase request path (e.g.,
/webhook) - The stringified request body with keys sorted alphabetically, or
{}if no body - The timestamp from the
x-wavynode-timestampheader
Using @wavynode/utils
The easiest way to verify requests is with the validateSignature function:
validateSignature parameters
validateSignature parameters
| Parameter | Type | Description |
|---|---|---|
method | string | The HTTP method of the request |
path | string | The path of the request |
body | object | The request body |
timestamp | number | The timestamp from the x-wavynode-timestamp header |
secret | string | Your integration’s secret from Settings → Integración in the dashboard |
timeTolerance | number | Time tolerance in milliseconds to prevent replay attacks (recommended: 300000) |
signature | string | The signature from the x-wavynode-hmac header |
formCanonicalMessage:
Manual authentication
If you are not using the@wavynode/utils package, you can implement the authentication logic yourself.
Create the HMAC signature
Create a
sha256 HMAC of the canonical string using your integration’s secret as the key. Base64 encode the result.Why is HMAC necessary?
Without HMAC authentication, anyone who knows your integration URL could:- Send fake webhooks simulating transactions that never happened
- Query user data without authorization
- Inject false notifications into your system