Guide d'intégration n8n
Réponse rapide : utilisez le nœud déclencheur Webhook de n8n pour recevoir les événements report.completed de Surmado. Faites pointer le webhook_url de Surmado vers l’URL du webhook n8n, filtrez sur event et report.product, puis transmettez le payload à Google Sheets, Slack, Postgres ou toute autre intégration. n8n auto-hébergé est gratuit ; n8n Cloud coûte $20/mois.
Temps de lecture : 16 minutes
Prérequis
- Une instance n8n (auto-hébergée via Docker, ou n8n Cloud)
- Une clé d’API Surmado (
sur_live_...) : créez-la sur app.surmado.com → Settings → API Keys - Une URL publique pour votre webhook n8n (n8n Cloud s’en charge ; en auto-hébergé, il faut un domaine ou un tunnel)
Pourquoi n8n
- Auto-hébergeable : votre workflow tourne sur votre propre infrastructure (Docker, Kubernetes, serveur dédié)
- Open source : inspectez chaque nœud, étendez n8n avec du code personnalisé
- Pas de facturation à la tâche : exécutions illimitées en auto-hébergé (seul le coût du serveur s’applique)
- Plus de 400 nœuds intégrés : Notion, Google Sheets, Slack, Airtable, PostgreSQL, HTTP Request, Code, etc.
- Coffre d’identifiants : enregistrez votre clé d’API Surmado une seule fois et réutilisez-la dans tous vos workflows
Démarrage rapide : auto-hébergement via Docker
docker volume create n8n_data
docker run -d --name n8n \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
-e N8N_HOST="n8n.yourdomain.com" \
-e WEBHOOK_URL="https://n8n.yourdomain.com/" \
n8nio/n8n
Placez ensuite n8n.yourdomain.com derrière un reverse proxy (Caddy, Nginx ou Traefik) vers http://localhost:5678, pour que Surmado puisse joindre votre point d’accès webhook en HTTPS.
Enregistrer votre clé d’API Surmado
Dans n8n, allez dans Credentials → New → Header Auth (ou utilisez l’identifiant intégré du nœud générique HTTP Request) :
- Name:
Surmado API - Header name:
Authorization - Header value:
Bearer sur_live_YOUR_API_KEY
Référencez cet identifiant dans tout nœud HTTP Request qui appelle api.surmado.com.
Le schéma d’intégration
- Un nœud déclencheur Webhook. n8n vous donne une URL du type
https://n8n.yourdomain.com/webhook/abc123. - Configurez Surmado pour envoyer (POST) les rapports terminés à cette URL via
webhook_urlà la création d’un rapport. - Un nœud IF pour filtrer sur
eventetreport.product. - (Facultatif) Un nœud HTTP Request pour appeler
GET /v1/reports/{{ $json.report.id }}et obtenir des données plus détaillées. - Des nœuds de destination : Google Sheets, Slack, Notion, Postgres, etc.
Exemple de payload reçu par le nœud Webhook
{
"event": "report.completed",
"timestamp": "2026-04-15T12:00:00+00:00",
"report": {
"id": "rpt_abc123xyz",
"token": "SIG-2026-04-A1B2C",
"product": "signal",
"status": "completed",
"tier": "basic",
"data_url": "https://api.surmado.com/v1/reports/rpt_abc123xyz",
"pdf_url": "https://api.surmado.com/v1/reports/view/VIEW_TOKEN",
"summary": {
"business_name": "Acme Coffee Roasters",
"presence_score": 34.2,
"authority_score": 42.7,
"competitive_rank": 4,
"top_competitor": "Blue Bottle"
}
}
}
Rapports Strategy (
"product": "solutions") : ils arrivent sans objetsummary, uniquement avecreport.tokenetreport.pdf_url.
Workflow 1 : AI Visibility vers Google Sheets
Nœud 1 : déclencheur Webhook
- HTTP method: POST
- Path:
surmado-signal(n8n générerahttps://n8n.yourdomain.com/webhook/surmado-signal) - Response mode: Immediately (renvoie 200 OK dès que n8n reçoit la requête)
Transmettez cette URL à Surmado :
curl -X POST https://api.surmado.com/v1/reports/signal \
-H "Authorization: Bearer sur_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"brand_slug": "acme_corp",
"url": "https://acme.com",
"email": "founder@acme.com",
"industry": "B2B SaaS",
"location": "United States",
"persona": "Small business owners",
"pain_points": "Losing track of customer conversations",
"brand_details": "Simple CRM with email integration",
"direct_competitors": "HubSpot, Pipedrive",
"webhook_url": "https://n8n.yourdomain.com/webhook/surmado-signal"
}'
Cliquez sur Listen for test event dans le nœud Webhook, puis lancez un rapport pour que n8n capture la structure du payload.
Nœud 2 : IF
Condition 1: {{ $json.event }} equals report.completed
Condition 2: {{ $json.report.product }} equals signal
Combine: AND
Nœud 3 : Google Sheets, Append row
Operation: Append Spreadsheet / Sheet: votre feuille de suivi
Correspondance des colonnes :
- Date:
{{ $json.timestamp }} - Token:
{{ $json.report.token }} - Business:
{{ $json.report.summary.business_name }} - Presence Score:
{{ $json.report.summary.presence_score }} - Authority Score:
{{ $json.report.summary.authority_score }} - Competitive Rank:
{{ $json.report.summary.competitive_rank }} - Top Competitor:
{{ $json.report.summary.top_competitor }}
Activez le workflow. Chaque rapport AI Visibility terminé est désormais suivi.
Workflow 2 : Site Audit avec alerte Slack conditionnelle
Webhook → IF (report.product = scan) → Google Sheets (toujours) → IF (report.summary.performance_score < 70) → Slack.
Message Slack :
:warning: Performance regression on {{ $json.report.summary.business_name }}
Performance: {{ $json.report.summary.performance_score }} (below 70 threshold)
SEO: {{ $json.report.summary.seo_score }}
Accessibility: {{ $json.report.summary.accessibility_score }}
Critical issues: {{ $json.report.summary.critical_issues_count }}
View report: {{ $json.report.pdf_url }}
Workflow 3 : synthèse PDF Strategy
Strategy n’inclut pas de résumé. Schéma :
- Webhook → IF (
report.product = solutions) → Send Email (Gmail, SMTP, SendGrid).
Corps de l’e-mail :
<p>Strategy report <code>{{ $json.report.token }}</code> is ready.</p>
<p><a href="{{ $json.report.pdf_url }}">View the full report (PDF)</a></p>
Récupérer des données plus détaillées via l’API REST
Le résumé du webhook couvre la plupart des besoins. Pour la variance par plateforme, les problèmes page par page ou le détail des lacunes de contenu, ajoutez un nœud HTTP Request après le filtre :
Nœud : HTTP Request
- Method: GET
- URL:
https://api.surmado.com/v1/reports/{{ $json.report.id }} - Authentication: predefined credential → Surmado API (le Header Auth créé plus haut)
- Response format: JSON
Les nœuds suivants peuvent alors référencer {{ $json.public_intelligence.data.platform_variance.chatgpt.presence_score }}, {{ $json.public_intelligence.data.audit_data.enrichment.content_gaps.executive_summary }}, etc.
Vérification de la signature du webhook
En production, vérifiez l’en-tête X-Surmado-Signature avant de faire confiance au payload. Surmado signe les webhooks avec HMAC-SHA256 sur une représentation JSON canonicalisée.
Nœud Function : vérifier la signature
const crypto = require('crypto');
const secret = $env.SURMADO_WEBHOOK_SECRET;
const signature = $('Webhook').first().json.headers['x-surmado-signature'];
const body = $('Webhook').first().json.body;
function canonicalize(value) {
if (value === null || typeof value !== 'object') return JSON.stringify(value);
if (Array.isArray(value)) return '[' + value.map(canonicalize).join(',') + ']';
const keys = Object.keys(value).sort();
return '{' + keys.map(k => JSON.stringify(k) + ':' + canonicalize(value[k])).join(',') + '}';
}
function asciiEscape(str) {
return str.replace(/[\u0080-\uffff]/g, c =>
'\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4)
);
}
const canonical = asciiEscape(canonicalize(body));
const expected = crypto.createHmac('sha256', secret).update(canonical).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(signature, 'hex'))) {
throw new Error('Invalid webhook signature');
}
return [{ json: body }];
Enchaînement : Webhook → Function (vérification) → IF (filtre) → nœuds de destination.
Formats de token
- AI Visibility :
SIG-YYYY-MM-XXXXX(regex :SIG-\d{4}-\d{2}-[A-Z0-9]{5}) - Site Audit :
SCN-YYYY-MM-XXXXX(regex :SCN-\d{4}-\d{2}-[A-Z0-9]{5}) - Strategy :
SOL-YYYY-MM-XXXXX(regex :SOL-\d{4}-\d{2}-[A-Z0-9]{5})
Les tokens n’expirent pas. Les URL de téléchargement signées de l’API REST sont valables environ 15 minutes ; les liens magiques pdf_url des webhooks sont valables environ 30 jours.
Schémas avancés
Router par produit avec Switch
Utilisez un nœud Switch sur $json.report.product avec des cas pour signal, scan et solutions. Chaque cas mène à un workflow propre au produit. Une seule URL de webhook gère tous les types de rapport.
Conserver dans Postgres pour une analyse chronologique
Ajoutez après le filtre IF un nœud Postgres qui insère (INSERT) (timestamp, token, report_id, product, business_name, presence_score, authority_score, ...) dans une table de rapports. Interrogez-la ensuite avec Grafana ou Metabase pour obtenir des courbes de tendance.
Routage multi-clients pour agences
Utilisez un Data store (ou une base externe) qui associe business_name / brand_slug à la configuration du client (quel canal Slack, quel onglet de feuille, etc.). Faites la recherche pour chaque rapport et routez dynamiquement.
Dépannage
Le webhook ne se déclenche pas : activez le workflow (n8n ne traite les webhooks que lorsque le workflow est actif, pas pendant les tests). Vérifiez que webhook_url a bien été indiqué à la création du rapport. Utilisez webhook.site comme URL de test pour vérifier que Surmado envoie le payload attendu.
Le nœud HTTP Request renvoie 401 : l’identifiant n’est pas rattaché, ou la clé n’a pas le préfixe Bearer . La valeur complète de l’en-tête doit être Bearer sur_live_....
Les champs sont vides en aval : vérifiez le type de produit. Les webhooks Strategy n’incluent pas report.summary ; seuls report.token et report.pdf_url sont renseignés.
Webhook auto-hébergé injoignable : Surmado exige HTTPS. Si vous exécutez n8n sur localhost, utilisez un tunnel (ngrok, Cloudflare Tunnel) ou déployez derrière un reverse proxy avec un certificat TLS valide.
La vérification de signature échoue avec des caractères non ASCII : la fonction canonicalize ci-dessus les gère. Si vous avez écrit la vôtre, assurez-vous d’échapper les caractères non ASCII en ASCII pour correspondre à la sortie de json.dumps(..., ensure_ascii=True) de Python, utilisée par Surmado.
À lire aussi : Guide d’intégration de l’API | Données structurées et Intelligence Tokens | Intégration Zapier | Intégration Make | Intégration Notion