diff --git a/examples/conversational-ai/talk-to-santa/README.md b/examples/conversational-ai/talk-to-santa/README.md
index e215bc4..445650d 100644
--- a/examples/conversational-ai/talk-to-santa/README.md
+++ b/examples/conversational-ai/talk-to-santa/README.md
@@ -1,36 +1 @@
-This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
-
-## Getting Started
-
-First, run the development server:
-
-```bash
-npm run dev
-# or
-yarn dev
-# or
-pnpm dev
-# or
-bun dev
-```
-
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
-
-You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
-
-This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
-
-## Learn More
-
-To learn more about Next.js, take a look at the following resources:
-
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
-
-You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
-
-## Deploy on Vercel
-
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
-
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
+# 🎄 Talk to Santa
diff --git a/examples/conversational-ai/talk-to-santa/app/(main)/actions/actions.ts b/examples/conversational-ai/talk-to-santa/app/(main)/actions/actions.ts
new file mode 100644
index 0000000..8e30a84
--- /dev/null
+++ b/examples/conversational-ai/talk-to-santa/app/(main)/actions/actions.ts
@@ -0,0 +1,62 @@
+"use server";
+
+import { actionClient } from "@/app/(main)/actions/safe-action";
+import { z } from "zod";
+import { ElevenLabsClient } from "elevenlabs";
+
+export const getAgentSignedUrl = actionClient
+ .schema(z.object({}))
+ .action(async () => {
+ const agentId = process.env.AGENT_ID;
+ const apiKey = process.env.XI_API_KEY;
+
+ if (!agentId || !apiKey) {
+ throw new Error("Environment variables are not set");
+ }
+
+ const elevenlabs = new ElevenLabsClient({
+ apiKey: apiKey,
+ });
+
+ try {
+ const { signed_url: signedUrl } =
+ await elevenlabs.conversationalAi.getSignedUrl({
+ agent_id: agentId,
+ });
+
+ if (!signedUrl) {
+ throw new Error("Failed to get signed URL");
+ }
+
+ return { signedUrl };
+ } catch (error) {
+ throw new Error(`Failed to get signed URL: ${error}`);
+ }
+ });
+
+export const getAgentConversation = actionClient
+ .schema(
+ z.object({
+ conversationId: z.string(),
+ })
+ )
+ .action(async ({ parsedInput: { conversationId } }) => {
+ const apiKey = process.env.XI_API_KEY;
+
+ if (!apiKey) {
+ throw new Error("XI_API_KEY is not set");
+ }
+
+ const elevenlabs = new ElevenLabsClient({
+ apiKey: apiKey,
+ });
+
+ try {
+ const conversation = await elevenlabs.conversationalAi.getConversation(
+ conversationId
+ );
+ return { conversation };
+ } catch (error) {
+ throw new Error(`Failed to get conversation: ${error}`);
+ }
+ });
diff --git a/examples/conversational-ai/talk-to-santa/app/(main)/actions/safe-action.tsx b/examples/conversational-ai/talk-to-santa/app/(main)/actions/safe-action.tsx
new file mode 100644
index 0000000..22510a1
--- /dev/null
+++ b/examples/conversational-ai/talk-to-santa/app/(main)/actions/safe-action.tsx
@@ -0,0 +1,20 @@
+import {
+ DEFAULT_SERVER_ERROR_MESSAGE,
+ createSafeActionClient,
+ } from "next-safe-action";
+ import { headers } from "next/headers";
+
+ export const actionClient = createSafeActionClient({
+ handleServerError(e) {
+ if (e instanceof Error) {
+ return e.message;
+ }
+
+ return DEFAULT_SERVER_ERROR_MESSAGE;
+ },
+ }).use(async ({ next }) => {
+ // forward the user's ip address to context (for rate limiting)
+ const ip = (await headers()).get("x-forwarded-for") ?? "127.0.0.1";
+ return next({ ctx: { ip } });
+ });
+
\ No newline at end of file
diff --git a/examples/conversational-ai/talk-to-santa/app/(main)/layout.tsx b/examples/conversational-ai/talk-to-santa/app/(main)/layout.tsx
new file mode 100644
index 0000000..70cd62f
--- /dev/null
+++ b/examples/conversational-ai/talk-to-santa/app/(main)/layout.tsx
@@ -0,0 +1,39 @@
+import { Logo } from "@/components/logo/index";
+import { ChristmasCountdown } from "@/components/christmas-countdown";
+import { Snowfall } from "@/components/snowfall";
+import { MusicPlayer } from "@/components/music-player";
+
+export default function Layout({
+ children,
+}: Readonly<{
+ children: React.ReactNode;
+}>) {
+ return (
+