> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layercode.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get started with Next.js (backend)

> Implement the Layercode Webhook SSE API in your Next.js API Routes backend.

This guide shows you how to implement the Layercode [Webhook SSE API](/api-reference/webhook-sse-api) in a Next.js backend using the [Node.js Backend SDK](/sdk-reference/node-js-sdk). You'll learn how to set up a webhook endpoint that receives transcribed messages from the Layercode voice agent and streams the agent's responses back to the frontend, to be turned into speech and spoken back to the user.

**Example code:** <Icon icon="github" size={18} color="black" /> [layercodedev/example-fullstack-nextjs](https://github.com/layercodedev/example-fullstack-nextjs)

<Note>This backend example is part of a full-stack example that also includes a web voice agent React frontend. We recommend also reading the [Next.js frontend guide](/tutorials/next-js-frontend) to get the most out of this example.</Note>

## Prerequisites

* Node.js 18+
* [Next.js](https://nextjs.org/) (App Router recommended)
* A Layercode account and agent ([sign up here](https://dash.layercode.com))
* (Optional) An API key for your LLM provider (we recommend Google Gemini)

## Setup

Install dependencies:

```bash theme={null}
npm install @layercode/node-server-sdk @ai-sdk/google
```

Edit your .env environment variables. You'll need to add:

* `GOOGLE_GENERATIVE_AI_API_KEY` - Your Google AI API key
* `LAYERCODE_API_KEY` - Your Layercode API key found in the [Layercode dashboard settings](https://dash.layercode.com/settings)
* `LAYERCODE_WEBHOOK_SECRET` - Your Layercode agent's webhook secret, found in the [Layercode dashboard](https://dash.layercode.com) (go to your agent, click Edit in the Your Backend Box and copy the webhook secret shown)
* `NEXT_PUBLIC_LAYERCODE_AGENT_ID` - The Layercode agent ID for your voice agent. Find this ID in [Layercode dashboard](https://dash.layercode.com/)

## Create Your Next.js API Route

Here's a simplified example of the core functionality needed to implement the Layercode webhook endpoint. See the [GitHub repo](https://github.com/layercodedev/example-fullstack-nextjs) for the full example.

```ts app/api/agent/route.ts [expandable] theme={null}
export const maxDuration = 300; // We set a generous Vercel max function duration to allow for long running agents
export const dynamic = 'force-dynamic';

import { createGoogleGenerativeAI } from '@ai-sdk/google';
import { streamText, CoreMessage } from 'ai';
import { streamResponse, verifySignature } from '@layercode/node-server-sdk';

const google = createGoogleGenerativeAI({
  apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY,
});

const SYSTEM_PROMPT =
  "You are a helpful conversation assistant. You should respond to the user's message in a conversational manner. Your output will be spoken by a TTS model. You should respond in a way that is easy for the TTS model to speak and sound natural.";

// POST request handler for Layercode incoming webhook, per turn of the conversation
export const POST = async (request: Request) => {
  const requestBody = await request.json();
  const signature = request.headers.get('layercode-signature') || '';
  const secret = process.env.LAYERCODE_WEBHOOK_SECRET || '';
  const payload = JSON.stringify(requestBody);
  const isValid = verifySignature({ payload, signature, secret });

  if (!isValid) {
    console.error('Invalid signature', signature, secret, payload);
    return new Response('Unauthorized', { status: 401 });
  }

  return streamResponse(requestBody, async ({ stream }) => {
    const { textStream } = streamText({
      model: google('gemini-2.0-flash-001'),
      system: SYSTEM_PROMPT,
      messages: [{ role: 'user', content: [{ type: 'text', text }] }],
      onFinish: async ({ response }) => {
        stream.end(); // We must call stream.end() here to tell Layercode that the assistant's response has finished
      },
    });
    // Here we return the textStream chunks as SSE messages to Layercode, to be spoken to the user
    await stream.ttsTextStream(textStream);
  });
};
```

## How It Works

* **/api/agent webhook endpoint:** Receives POST requests from Layercode with the user's transcribed message, session, and turn info. The [webhook request is verified](/explanations/connect-backend#webhook-verification) as coming from Layercode.
* **LLM call:** Calls Google Gemini Flash 2.0 with the system prompt and user's new transcribed message.
* **SSE streaming:** As soon as the LLM starts generating a response, the backend streams the output back as SSE messages to Layercode, which converts it to speech and delivers it to the frontend for playback in realtime.

See the [GitHub repo](https://github.com/layercodedev/example-fullstack-nextjs) for the full example which includes conversation history, welcome message and more.

## Running Your Backend

Start your Next.js app:

```bash theme={null}
npm run dev
```

## Configure the Layercode Webhook endpoint

In the Layercode dashboard, go to your agent settings. Under **Your Backend**, click edit, and here you can set the URL of the webhook endpoint.

If running this example locally, setup a tunnel (we recommend cloudflared which is free for dev) to your localhost so the Layercode webhook can reach your backend. Follow our [tunnelling guide](/how-tos/tunnelling).

## Test Your Voice Agent

There are two ways to test your voice agent:

1. Use the Layercode playground tab, found in the agent in the [Layercode dashboard](https://dash.layercode.com).
2. As this example is a full-stack example, you can visit [http://localhost:3000](http://localhost:3000) in your browser and speak to the voice agent in your browser using the React frontend included.
