Quickstart

From an empty project to a persisted, reported conversation in the dashboard.

This walks through the shortest path: an anonymous session, the AI SDK runtime, and the assistant-ui components. The other guides swap the runtime; the cloud side stays the same.

Create a project

Sign in at cloud.assistant-ui.com, create a project, and open Settings › Telemetry. Copy the Frontend API URL, https://proj-<id>.assistant-api.com. Create an API key under Settings › API keys only when your server needs one: for user tokens, trace exports, scores or the project read API. Nothing in this quickstart does.

Configure the environment

.env.local
NEXT_PUBLIC_ASSISTANT_BASE_URL=https://proj-<id>.assistant-api.com
OPENAI_API_KEY=sk-…

With NEXT_PUBLIC_ASSISTANT_BASE_URL set, the React runtimes create an anonymous cloud client on their own when you pass no cloud. The other platforms construct the client explicitly, as the next step shows, and name the server that hosts the chat route, because it is not on the app's own origin.

Allow anonymous sessions and your origin

Anonymous sessions are off until you turn them on in Settings › Access. While you are there, add your development origin, for example http://localhost:3000, to the allowed origins; an empty list allows every origin, which is fine for a first run.

Install and wire the runtime

npm install @assistant-ui/react @assistant-ui/ai-sdk ai @ai-sdk/openai
app/chat/page.tsx
"use client";

import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { useChatRuntime } from "@assistant-ui/ai-sdk";
import { ThreadList } from "@/components/assistant-ui/elements/thread-list.aui";
import { Thread } from "@/components/assistant-ui/elements/thread.aui";

export default function ChatPage() {
  const runtime = useChatRuntime();

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      <div className="grid h-dvh grid-cols-[240px_1fr]">
        <ThreadList />
        <Thread />
      </div>
    </AssistantRuntimeProvider>
  );
}

useChatRuntime() reads the base URL from the environment and sends chat requests to /api/chat, the AI SDK route you already have.

Report model and usage

The browser cannot see which model answered or how many tokens it used. Add a messageMetadata callback to your route so the run report carries them:

app/api/chat/route.ts
import { convertToModelMessages, streamText } from "ai";
import { openai } from "@ai-sdk/openai";

export async function POST(req: Request) {
  const { messages } = await req.json();
  const model = openai("gpt-5.6-luna");
  const result = streamText({
    model,
    messages: await convertToModelMessages(messages),
  });

  return result.toUIMessageStreamResponse({
    messageMetadata: ({ part }) => {
      if (part.type === "finish") {
        return { usage: part.totalUsage, finishReason: part.finishReason };
      }
      if (part.type === "finish-step") {
        return { modelId: part.response.modelId, provider: model.provider };
      }
      return undefined;
    },
  });
}

Send a message and look

Send a message. Within a moment the thread appears under Threads with an automatic title, the response under Runs with its duration, tokens, model and cost, and the send under Engagement. The Overview updates with the day's figures.

Next