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

  1. Open n8n at https://n8n.vps-h1.infra.zintegrowana.online
  2. Create a new workflow named “vercel-deploy-recorder”
  3. 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: readyState values 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-duplicates header performs an upsert on deployment_id.
  1. Activate the workflow.

Step 2 — Register the webhook in Vercel

  1. Open Vercel Dashboard → select project et-operational-platform
  2. Go to SettingsGitDeploy Hooks section (or SettingsWebhooks — location varies by Vercel plan)
  3. Add a new webhook:
    • URL: https://n8n.vps-h1.infra.zintegrowana.online/webhook/vercel-deploy
    • Events: check deployment (fires on every deployment state change)
  4. 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-platform

Get the token from: https://vercel.com/account/tokens

Then restart the vercel-exporter container:

cd /opt/p24-infra/monitoring
docker compose up -d vercel-exporter

Verify metrics are being collected:

curl http://localhost:9202/metrics | grep vercel_deployment_state

Step 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 vercel

Step 5 — Verify Grafana dashboard

  1. Open Grafana → search for “Vercel Deployments” dashboard
  2. Panel 1 (Production State): should show green READY if latest production deploy succeeded
  3. Panel 3 (Last Production Deploy): shows “No data” until n8n workflow fires once
  4. 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

IssueCheck
n8n webhook not receiving eventsVerify Vercel webhook URL in project settings; check n8n is accessible publicly
Supabase upsert fails with 401Verify SUPABASE_SERVICE_KEY in n8n node headers
vercel_deployment_state missing in PrometheusCheck vercel-exporter container logs; verify VERCEL_TOKEN is set
Grafana shows “No data” for Prometheus panelsWait 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:

  1. Webhook — receives POST at /webhook/hu-sp-report
  2. Validate Secret — Code node: checks X-Webhook-Secret header against N8N_HU_SP_REPORT_SECRET env var; throws Error('Unauthorized') on mismatch
  3. Send Report EmailemailSend via SMTP (SMTP account credential); sends to ecotrans.automation@gmail.com with subject HU/SP Report: {title} and clickable file_url link
  4. Respond 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

VariableWhere setPurpose
N8N_HU_SP_REPORT_SECREThostinger/docker-compose.yml + /root/.env on vps-h1Shared 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

IssueCheck
N8N_HU_SP_REPORT_SECRET env var not set error in executionAdd N8N_HU_SP_REPORT_SECRET to /root/.env on vps-h1 and restart n8n
Unauthorized: invalid X-Webhook-Secret errorSecret mismatch — verify the secret in Vercel env vars matches /root/.env
Email not receivedCheck SMTP account in n8n credentials; check spam folder
Workflow not activeRe-activate via n8n UI or API: POST /api/v1/workflows/OWAeV4xvGEh1BmGH/activate