If your project uses the Pages Router instead, create the handler at pages/api/webhook.ts:
import type { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const { type, call, timestamp } = req.body;
console.log(`Webhook received: ${type} at ${timestamp}`);
switch (type) {
case 'call-started':
console.log(`Call ${call.id} started with ${call.customer?.number}`);
break;
case 'speech-update':
console.log(`User said: ${req.body.transcript}`);
break;
case 'function-call': {
const { functionName, parameters } = req.body.functionCall;
const result = await processFunction(functionName, parameters);
return res.status(200).json({ result });
}
case 'call-ended':
console.log(`Call ended. Duration: ${call.duration}s`);
break;
default:
console.log(`Unhandled event type: ${type}`);
}
return res.status(200).json({ status: 'ok' });
}
async function processFunction(name: string, params: unknown) {
// Your custom function logic here
return { success: true };
}
Both routers follow the same shape: parse the body, switch on type, and return JSON with a result for function-call events (and an assistant object for assistant-request events) rather than a bare status code.