Connect Testivora with n8n
Catch Testivora events with n8n's Webhook node and trigger any workflow: Slack, Sheets, your CRM, anything. Works today — no native node required.
Create a Webhook node in n8n
New workflow → add a 'Webhook' node. Set HTTP Method to POST and copy the 'Production URL' (or the Test one while testing). Activate the workflow so the Production URL goes live.
Register the URL in Testivora
In Testivora go to Settings → Webhooks → New endpoint. Paste the n8n URL, pick the events you care about (or leave it on all) and save. You'll get a whsec_… secret to verify the signature (step 5, optional).
Send a test and inspect the payload
From Testivora hit 'Send test' on your endpoint. n8n will receive the event. Here's the payload shape — the testimonial lives under data:
{
"id": "evt_3hF2bQ...",
"object": "event",
"event": "testimonial.approved",
"version": "1.0",
"created": "2026-06-03T01:00:00.000Z",
"attempt": 1,
"data": {
"id": "j97...",
"type": "text",
"status": "approved",
"rating": 5,
"text": "Cerré 3 clientes en una semana.",
"author": { "name": "Ana López", "company": "Acme" }
}
}Use the fields in your nodes
In n8n the POST body arrives under $json.body. Reference fields with expressions:
{{ $json.body.event }} // testimonial.approved
{{ $json.body.data.author.name }} // Ana López
{{ $json.body.data.text }} // el testimonio
{{ $json.body.data.rating }} // 5Verify the signature (optional but recommended)
To make sure the POST came from Testivora, add a Code node that recomputes the HMAC-SHA256 of the Testivora-Signature header with your secret:
// n8n Code node (opcional) — verifica la firma
const crypto = require('crypto');
const secret = 'whsec_...'; // tu secret de Testivora
const header = $json.headers['testivora-signature']; // "t=...,v1=..."
const p = Object.fromEntries(header.split(',').map(s => s.split('=')));
const raw = JSON.stringify($json.body);
const expected = crypto.createHmac('sha256', secret)
.update(`${p.t}.${raw}`).digest('hex');
if (p.v1 !== expected) throw new Error('Firma inválida');
return $input.all();