This version (v1) will be removed by 31 March 2026.
Validating requests
All webhook requests from FreJun will contain two signature headers: frejun-signature and frejun-signature-slim. You can use either method to validate the authenticity of the request.
Method 1: Using frejun-signature
To ensure the request is genuinely from FreJun and has not been tampered with, you should verify this signature using the following steps:
-
Concatenate the following values in order to form a single string:
- The HTTP
Request Method(e.g.,POST) - The
Request URI(this is the callback URL you provided when creating the webhook. Make sure to pass the full URL, as it was registered, when creating the webhook) - The raw
Request Body(as received, without any modifications)
For example:
POSThttps://yourdomain.com/webhook-endpoint{"event":"call.completed", ...} - The HTTP
-
Create a UTF-8 encoded string from the concatenated result.
Example in Node.js:
// Assume you have these values from the incoming request
const method = "POST";
const requestUri = "https://yourdomain.com/webhook-endpoint"; // Your registered callback URL
const rawBody = `{"event":"call.completed", ...}`; // The raw request body as a string
// Concatenate in order: method + requestUri + rawBody
const concatenated = method + requestUri + rawBody;
// Convert to a UTF-8 encoded Buffer (for hashing in the next step)
const utf8Buffer = Buffer.from(concatenated, "utf8"); -
Generate an HMAC SHA-256 hash of this string using your app's
Client Secretas the key and Base64 encode the resulting hash.Example in Node.js:
const crypto = require("crypto");
const clientSecret = process.env.CLIENT_SECRET; // Your app's client secret
// Generate HMAC SHA-256 hash
const hmac = crypto.createHmac("sha256", clientSecret);
hmac.update(utf8Buffer);
const frejunSignature = hmac.digest('base64'); -
Compare the final value with the
frejun-signatureheader sent in the webhook request.- If they match, the request is valid and originated from FreJun.
- If they do not match, the request may have been tampered with or is not from FreJun.
Note:
- The
Request URIrefers to the exact callback URL you registered for the webhook, including any query parameters. - The
Request Bodyshould be used exactly as received, without any parsing or formatting changes, to ensure the signature matches.
Method 2: Using frejun-signature-slim
For a simpler validation approach, FreJun also provides the frejun-signature-slim header. This method uses only three values:
-
Concatenate the following values in order to form a single string:
- The HTTP
Request Method(e.g.,POST) - The
Request URI(the callback URL you registered) - The
call_idfrom the webhook payload
For example:
POSThttps://yourdomain.com/webhook-endpointcall_abc123xyz - The HTTP
-
Create a UTF-8 encoded string from the concatenated result.
Example in Node.js:
// Assume you have these values from the incoming request
const method = "POST";
const requestUri = "https://yourdomain.com/webhook-endpoint"; // Your registered callback URL
const payload = JSON.parse(rawBody); // Parse the body to extract call_id
const callId = payload.call_id;
// Concatenate in order: method + requestUri + callId
const concatenated = method + requestUri + callId;
// Convert to a UTF-8 encoded Buffer (for hashing in the next step)
const utf8Buffer = Buffer.from(concatenated, "utf8"); -
Generate an HMAC SHA-256 hash of this string using your app's
Client Secretas the key and Base64 encode the resulting hash.Example in Node.js:
const crypto = require("crypto");
const clientSecret = process.env.CLIENT_SECRET; // Your app's client secret
// Generate HMAC SHA-256 hash
const hmac = crypto.createHmac("sha256", clientSecret);
hmac.update(utf8Buffer);
const frejunSignatureSlim = hmac.digest('base64'); -
Compare the final value with the
frejun-signature-slimheader sent in the webhook request.- If they match, the request is valid and originated from FreJun.
- If they do not match, the request may have been tampered with or is not from FreJun.
Note: This method is lighter since it doesn't require hashing the entire request body, making it faster for large payloads.
This process helps you securely verify that incoming webhook requests are authentic and have not been altered.