# Quickstart
URL: /docs/cloud/quickstart

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

> For AI agents: a documentation index is available at [llms.txt](/llms.txt). Use `.md` for canonical markdown pages; `.mdx` is kept as a backwards-compatible alias on supported URL paths.

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.

1. ### Create a project

   Sign in at [cloud.assistant-ui.com](https://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.

2. ### Configure the environment

   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.

3. ### 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.

4. ### Install and wire the runtime

5. ### 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:

   ```
   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;
       },
     });
   }
   ```

6. ### 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

- Replace the anonymous session with your users' identities: [Authentication](/docs/cloud/authorization).
- Join your server's spans to the browser's report: [Traces](/docs/cloud/traces).
- Read what every field means: [Run reports](/docs/cloud/telemetry) and the [concepts](/docs/cloud#concepts).
- The working example: [with-cloud](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-cloud) on GitHub.