Echo
Next.js SDK

Server

Echo's Next.js SDK server-side functionality.

Echo's Next.js SDK will handle all authentication logic out of the box.

Configure Echo with the Echo constructor.

src/echo/index.ts
import Echo from "@merit-systems/echo-next-sdk";

export const { 
    // Echo Auth Routes
    handlers, 

    // Server-side utils
    getUser, isSignedIn, 

    // AI Providers
    openai, anthropic, google 
} = Echo({
  appId: "ECHO_APP_ID",
});

By re-exporting the Echo constructor results, you can use throughout your server logic.

The Echo constructor takes the following configuration params.

PropTypeDefault
appId
string
-
basePath?
string
/api/echo

Handlers

import handlers from '@/echo';

export { GET, POST } = handlers;

Exporting these routes will expose default authentication routes which can be used from the client. In most cases your code will not need to touch these routes.

  • api/echo/signin
  • api/echo/callback
  • api/echo/refresh

Very important - When productionizing your application, you will need to append /api/echo/callback to your app's homepage route when inputting the correct authorized callback Url.

Server Utilities

import { getUser, isSignedIn } from "@/echo";

export default async function Page() {
    const signedIn = await isSignedIn();

    if (!signedIn) {
        return <SignIn />;
    } else {
        const user = await getUser();
        return <Dashboard user={user} />;
    }
}

AI Providers

Echo's Next.js SDK provides a thin wrapper around the Vercel AI SDK. Echo follows their recommended pattern with a small diff, to route through Echo instead of the model provider.

import { openai } from '@ai-sdk/openai';
import { openai } from "@/echo";
import { streamText, UIMessage, convertToModelMessages } from 'ai';

// Allow streaming responses up to 30 seconds
export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages }: { messages: UIMessage[] } = await req.json();

  const result = streamText({
    model: openai('gpt-5'),
    messages: convertToModelMessages(messages),
  });

  return result.toUIMessageStreamResponse();
}