Build two-way automation pipelines between self-hosted n8n and Next.js 15 Route Handlers. Covers mutual HMAC authentication, payload schemas, and retries. This practical guide covers step-by-step setup, real-world code snippets, security hardening, and common production edge cases.
Executive Summary & Key Takeaway (AEO)
Connecting n8n to Next.js 15 Route Handlers enables powerful two-way event automation — allowing user events in a web application (like new signups or checkout conversions) to trigger complex multi-app workflows in n8n, while n8n posts processed results back to Next.js. Security is enforced through HMAC-SHA256 signature headers, preventing spoofing and unauthorized execution.
Architecture Flow
sequenceDiagram
participant User as Web Application User
participant NextJS as Next.js 15 Route Handler
participant n8n as Self-Hosted n8n Workflow
participant CRM as HubSpot / Slack / Database
User->>NextJS: Submits Order / Lead Form
NextJS->>n8n: POST /webhook/lead-created (with HMAC Signature)
n8n->>n8n: Verifies Signature Header
n8n->>CRM: Enriches Lead & Posts to Slack
n8n->>NextJS: POST /api/webhooks/n8n-response (Status: Enriched)
NextJS->>User: Displays Instant Confirmation
Step 1: Secure Next.js Webhook Receiver with HMAC Validation
Create app/api/webhooks/n8n/route.ts:
import { NextResponse } from 'next/server';
import crypto from 'crypto';
const N8N_SECRET = process.env.N8N_WEBHOOK_SECRET || 'your-production-secret-key-32chars';
export async function POST(req: Request) {
try {
const rawBody = await req.text();
const signature = req.headers.get('x-n8n-signature');
if (!signature) {
return NextResponse.json({ error: 'Missing signature header' }, { status: 401 });
}
// Compute expected HMAC SHA256 signature
const expectedSignature = crypto
.createHmac('sha256', N8N_SECRET)
.update(rawBody)
.digest('hex');
const isValid = crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
if (!isValid) {
return NextResponse.json({ error: 'Invalid HMAC signature' }, { status: 403 });
}
const payload = JSON.parse(rawBody);
// Process asynchronous business logic
console.log('n8n Webhook Verified:', payload.event, payload.data);
return NextResponse.json({ success: true, processedAt: new Date().toISOString() });
} catch (err) {
return NextResponse.json(
{ error: err instanceof Error ? err.message : 'Internal Server Error' },
{ status: 500 }
);
}
}
Step 2: Configuring the n8n HTTP Request Node
In your n8n workflow canvas:
- Add an HTTP Request node.
- Method:
POST. - URL:
https://blogs.devpatternlabs.com/api/webhooks/n8n. - Add a Code Node before the request to generate the HMAC header:
const crypto = require('crypto');
const secret = 'your-production-secret-key-32chars';
const payloadString = JSON.stringify($input.item.json);
const signature = crypto
.createHmac('sha256', secret)
.update(payloadString)
.digest('hex');
return {
json: {
...$input.item.json,
_headers: {
'x-n8n-signature': signature,
'content-type': 'application/json'
}
}
};
Related Automation Resources
Written by Dev Pattern LabsCore Engineering
Dev Pattern Labs is an engineering lab and digital consultancy specializing in custom Next.js web applications, WooCommerce REST API integrations, and workflow automation for growing businesses.
Recommended Companion Articles

Next.js 15 Stripe Subscriptions & Billing Customer Portal Guide
Build a SaaS subscription engine in Next.js 15 with Stripe Billing, Checkout Sessions, Customer Portal redirects, and webhook lifecycle event handlers.

n8n Self-Hosted Production Guide: Docker, PostgreSQL & SSL Setup
Deploy and configure a self-hosted n8n workflow automation engine using Docker Compose, PostgreSQL, Traefik reverse proxy, and automated SSL encryption.

Stripe Webhooks in Next.js 15: Payment Event Handling
Integrate Stripe webhooks with Next.js 15 App Router. Learn signature verification, raw body parsing, payment event handling, and Stripe CLI testing.
