Next.js Webhook Setup
Instagram Webhook in Next.js (Route Handlers)
This is the clean Next.js way: create a single route handler that responds to GET verification and POST events.
Set this env var:
IG_WEBHOOK_VERIFY_TOKEN="your-secret-verify-token"
1) Create route handler
Create this file: app/api/webhooks/instagram/route.ts. Meta will call this endpoint for verification and events.
// app/api/webhooks/instagram/route.ts
import { NextRequest } from "next/server";
const VERIFY_TOKEN = process.env.IG_WEBHOOK_VERIFY_TOKEN!;
// GET = Verification request
export async function GET(req: NextRequest) {
const { searchParams } = new URL(req.url);
const mode = searchParams.get("hub.mode");
const token = searchParams.get("hub.verify_token");
const challenge = searchParams.get("hub.challenge");
if (mode === "subscribe" && token === VERIFY_TOKEN && challenge) {
return new Response(challenge, { status: 200 });
}
return new Response("Forbidden", { status: 403 });
}
// POST = Event notifications
export async function POST(req: NextRequest) {
const body = await req.json();
// Respond immediately
// (If you need heavy processing, push to a queue here.)
console.log("IG WEBHOOK EVENT:", JSON.stringify(body, null, 2));
return new Response("OK", { status: 200 });
}PRIVACY POLICY
privacy-policy/page.tsx
export default function PrivacyPolicyPage() {
return (
<div className="max-w-4xl mx-auto px-6 py-12 text-gray-900 leading-relaxed">
<h1 className="text-3xl font-bold mb-2">Privacy Policy</h1>
<p className="text-gray-500 mb-8">
Last updated: {new Date().toISOString().slice(0, 10)}
</p>
<Card title="Overview">
This application integrates with Instagram to enable messaging and
webhook-based event handling. We process only the data required to
provide the service and improve reliability.
</Card>
<Card title="Data We Collect">
<ul className="list-disc ml-6 space-y-2">
<li>Webhook event payloads sent by Meta/Instagram</li>
<li>Technical metadata for debugging and reliability</li>
</ul>
<p className="mt-4">
We do <strong>not</strong> sell your data.
</p>
</Card>
<Card title="How We Use Data">
<ul className="list-disc ml-6 space-y-2">
<li>Deliver messaging features</li>
<li>Monitor errors</li>
<li>Prevent abuse</li>
</ul>
</Card>
<Card title="Security">
We use HTTPS and restricted access controls. Do not share your access
tokens publicly.
</Card>
<Card title="Contact">
Email: <strong>support@yourdomain.com</strong>
</Card>
</div>
);
}
function Card({ title, children }: any) {
return (
<div className="border rounded-xl p-6 mb-6 shadow-sm">
<h2 className="text-xl font-semibold mb-3">{title}</h2>
{children}
</div>
);
}2) Put the callback URL in Meta dashboard
Use this as your Callback URL in the Webhooks settings:
https://your-domain.com/api/webhooks/instagramSet your Verify Token in the dashboard to match IG_WEBHOOK_VERIFY_TOKEN. When you click “Verify and Save”, Meta sends a GET request with the hub parameters, and your GET handler must echo back the challenge.
3) Message ID note (important)
You only get a message_id when you receive an incoming event (DM, comment, mention, etc.) through your webhook. That’s why webhooks are required for features like reactions (react/unreact needs a message id from an inbound payload).
Reference: Instagram Platform Webhooks docs + Meta Webhooks verification flow.