n8n Vercel Webhook Setup
This document describes the manual steps to wire up the n8n workflow that receives
Vercel deployment events and stores them in the p24_vercel_deployments Supabase table.
Overview
Vercel deployment event
→ POST to n8n webhook (vps-h1)
→ parse payload
→ upsert into p24_vercel_deployments (Supabase)
→ Grafana dashboard shows deployment history
The Prometheus exporter (vercel-exporter:9202) polls the Vercel API directly for
real-time state metrics. The n8n webhook handles the historical record.
Step 1 — Create the n8n workflow
- Open n8n at
https://n8n.vps-h1.infra.zintegrowana.online - Create a new workflow named “vercel-deploy-recorder”
- Add the following nodes in sequence:
Node 1: Webhook trigger
- Type: Webhook
- HTTP Method:
POST - Path:
vercel-deploy - Authentication: None (Vercel sends a shared secret header — handled in node 2)
- Respond: Immediately with
{ "status": "ok" }
The webhook URL will be:
https://n8n.vps-h1.infra.zintegrowana.online/webhook/vercel-deploy
Node 2: Set — parse payload
- Type: Set
- Map the following fields from
{{ $json.body.deployment }}:
deployment_id → {{ $json.body.deployment.id }}
project → {{ $json.body.projectMeta.name }}
branch → {{ $json.body.deployment.meta.githubCommitRef }}
commit_sha → {{ $json.body.deployment.meta.githubCommitSha }}
commit_message → {{ $json.body.deployment.meta.githubCommitMessage }}
author → {{ $json.body.deployment.meta.githubCommitAuthorName }}
state → {{ $json.body.deployment.readyState }}
target → {{ $json.body.deployment.target }}
build_duration → {{ Math.round(($json.body.deployment.buildingAt && $json.body.deployment.ready) ? ($json.body.deployment.ready - $json.body.deployment.buildingAt) / 1000 : null) }}
Note:
readyStatevalues from Vercel:READY,ERROR,BUILDING,CANCELED,QUEUED
Node 3: Supabase upsert
- Type: HTTP Request (or Supabase node if installed)
- Method:
POST - URL:
https://mwkqmgadqnkkihjdeqsi.supabase.co/rest/v1/p24_vercel_deployments - Headers:
apikey: <SUPABASE_SERVICE_KEY> Authorization: Bearer <SUPABASE_SERVICE_KEY> Content-Type: application/json Prefer: resolution=merge-duplicates - Body (JSON):
{ "deployment_id": "{{ $json.deployment_id }}", "project": "{{ $json.project }}", "branch": "{{ $json.branch }}", "commit_sha": "{{ $json.commit_sha }}", "commit_message": "{{ $json.commit_message }}", "author": "{{ $json.author }}", "state": "{{ $json.state }}", "target": "{{ $json.target }}", "build_duration": {{ $json.build_duration }} } - The
Prefer: resolution=merge-duplicatesheader performs an upsert ondeployment_id.
- Activate the workflow.
Step 2 — Register the webhook in Vercel
- Open Vercel Dashboard → select project
et-operational-platform - Go to Settings → Git → Deploy Hooks section (or Settings → Webhooks — location varies by Vercel plan)
- Add a new webhook:
- URL:
https://n8n.vps-h1.infra.zintegrowana.online/webhook/vercel-deploy - Events: check
deployment(fires on every deployment state change)
- URL:
- Click Save.
Vercel will send a test payload — verify in n8n execution history that it arrived
and a row was inserted in p24_vercel_deployments.
Step 3 — Add VERCEL_TOKEN to monitoring .env
On the IONOS VPS, add to /opt/p24-infra/monitoring/.env:
VERCEL_TOKEN=<your-vercel-api-token>
VERCEL_PROJECTS=et-operational-platformGet the token from: https://vercel.com/account/tokens
Then restart the vercel-exporter container:
cd /opt/p24-infra/monitoring
docker compose up -d vercel-exporterVerify metrics are being collected:
curl http://localhost:9202/metrics | grep vercel_deployment_stateStep 4 — Verify Prometheus scraping
# Hot-reload Prometheus config
curl -X POST http://localhost:9090/-/reload
# Check target is UP
curl -s http://localhost:9090/api/v1/targets | python3 -m json.tool | grep -A5 vercelStep 5 — Verify Grafana dashboard
- Open Grafana → search for “Vercel Deployments” dashboard
- Panel 1 (Production State): should show green READY if latest production deploy succeeded
- Panel 3 (Last Production Deploy): shows “No data” until n8n workflow fires once
- Panel 6 (Deployment History): shows “No data” until n8n workflow fires once
Trigger a test deployment in Vercel to populate Supabase-backed panels.
Vercel webhook payload structure
Reference payload (simplified):
{
"type": "deployment",
"payload": {
"deployment": {
"id": "dpl_abc123",
"readyState": "READY",
"target": "production",
"buildingAt": 1700000000000,
"ready": 1700000120000,
"meta": {
"githubCommitRef": "main",
"githubCommitSha": "abc123def456",
"githubCommitMessage": "feat: add feature",
"githubCommitAuthorName": "Developer Name"
}
},
"projectMeta": {
"name": "et-operational-platform"
}
}
}Note: The exact payload structure may vary. Check n8n execution logs after the first real event and adjust field paths in Node 2 if needed.
Troubleshooting
| Issue | Check |
|---|---|
| n8n webhook not receiving events | Verify Vercel webhook URL in project settings; check n8n is accessible publicly |
| Supabase upsert fails with 401 | Verify SUPABASE_SERVICE_KEY in n8n node headers |
vercel_deployment_state missing in Prometheus | Check vercel-exporter container logs; verify VERCEL_TOKEN is set |
| Grafana shows “No data” for Prometheus panels | Wait for first poll (5 min interval); check Prometheus target state |
HU/SP Report Email Webhook
Handles inspection-report PDFs generated by et-operational-platform.
et-operational-platform (Vercel)
→ POST /webhook/hu-sp-report (n8n vps-h1)
→ validate X-Webhook-Secret header
→ send email to ecotrans.automation@gmail.com
→ return {ok:true}
Workflow
n8n ID: OWAeV4xvGEh1BmGH (hu-sp-report-email)
Webhook URL: https://n8n.vps-h1.infra.zintegrowana.online/webhook/hu-sp-report
Workflow JSON: infra-src/n8n-workflows/hu-sp-report-email_OWAeV4xvGEh1BmGH.json
Nodes:
Webhook— receives POST at/webhook/hu-sp-reportValidate Secret— Code node: checksX-Webhook-Secretheader againstN8N_HU_SP_REPORT_SECRETenv var; throwsError('Unauthorized')on mismatchSend Report Email—emailSendvia SMTP (SMTP accountcredential); sends toecotrans.automation@gmail.comwith subjectHU/SP Report: {title}and clickablefile_urllinkRespond OK— returns{"ok":true}with HTTP 200
Webhook payload shape
{
"report_id": "<uuid>",
"title": "HU/SP 2026-05-19",
"description": "...",
"file_url": "https://s3.eu-central-1.wasabisys.com/...?X-Amz-...",
"generated_at": "2026-05-19T06:00:00Z"
}Required env vars
| Variable | Where set | Purpose |
|---|---|---|
N8N_HU_SP_REPORT_SECRET | hostinger/docker-compose.yml + /root/.env on vps-h1 | Shared secret validated by the workflow |
Must also be set in Vercel Dashboard as N8N_HU_SP_REPORT_WEBHOOK_URL (the URL) and N8N_HU_SP_REPORT_SECRET (the secret) for et-operational-platform.
Activation
The workflow is active on vps-h1 n8n. If the n8n container is restarted without N8N_HU_SP_REPORT_SECRET in the environment, the Code node will throw on every request — set the env var in /root/.env before restart.
Manual test
# Valid request — should return {ok:true} and trigger email
curl -X POST https://n8n.vps-h1.infra.zintegrowana.online/webhook/hu-sp-report \
-H "Content-Type: application/json" \
-H "X-Webhook-Secret: <your-secret>" \
-d '{
"report_id": "test-001",
"title": "HU/SP Test 2026-05-24",
"description": "Manual test run.",
"file_url": "https://example.com/test.pdf",
"generated_at": "2026-05-24T12:00:00Z"
}'
# Invalid secret — should fail with workflow error (n8n returns 500 when Code node throws)
curl -X POST https://n8n.vps-h1.infra.zintegrowana.online/webhook/hu-sp-report \
-H "Content-Type: application/json" \
-H "X-Webhook-Secret: wrong-secret" \
-d '{"title":"test"}'Troubleshooting
| Issue | Check |
|---|---|
N8N_HU_SP_REPORT_SECRET env var not set error in execution | Add N8N_HU_SP_REPORT_SECRET to /root/.env on vps-h1 and restart n8n |
Unauthorized: invalid X-Webhook-Secret error | Secret mismatch — verify the secret in Vercel env vars matches /root/.env |
| Email not received | Check SMTP account in n8n credentials; check spam folder |
| Workflow not active | Re-activate via n8n UI or API: POST /api/v1/workflows/OWAeV4xvGEh1BmGH/activate |