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

> ## Agent Instructions
> Internal links on these pages omit the .md extension. Append .md to a docs page URL, or send an Accept: text/markdown header, to get that page as markdown.

# Live updates

> Show a build as it happens, over a live connection from the builder's browser, without polling.

Live updates stream a build to the builder's browser as it happens, including each message, tool call, status change, and preview reload, so you don't have to poll. Your server opens a short-lived session for the apps a page shows, and the browser connects with it through the [Platform SDK](/developers/references/platform-sdk/overview). Everything that changes the app still goes from your server to the [Apps API](/developers/references/apps-api/get-started/overview), since the live connection is read-only.

<Warning>
  Live updates are in beta and need the [Builder plan or higher](/Account-and-billing/Billing-and-plans). Ask your onboarding contact to turn them on for your workspace. Until they're on, [poll for the build's state](/developers/white-label/the-build-turn).
</Warning>

From opening a page to the first live events:

```mermaid theme={null}
sequenceDiagram
    participant B as Builder's browser
    participant S as Your server
    participant API as Base44 Apps API
    participant L as Base44 live updates
    B->>S: Open a page for an app
    S->>L: POST /api/v1/socket-sessions
    L-->>S: session_id, session_token, socket_url, socket_path
    S-->>B: session_token, socket_url, socket_path
    B->>L: Connect and subscribe to the app
    L-->>B: Snapshot: status and last 50 messages
    B->>S: Send a prompt
    S->>API: Send chat message
    L-->>B: message.updated, app.status_changed, ...
```

## Set up live updates

<Tip>
  **Before you begin:** Create a [workspace API key](/Enterprise/workspace-secrets) with the **Watch app builder updates** permission, and give it access to every app your builders can watch. Choose **All current and future apps** so you don't have to update the key when you add an app. Keep this key on your server.
</Tip>

<Steps>
  <Step title="Open a session">
    Add an endpoint on your server that the browser calls when it needs live updates for specific apps. Check that the signed-in builder has access to each of those apps. Then use [Create socket session](/api-reference/create-socket-session) to open a short-lived session that lets the browser watch those apps:

    ```typescript theme={null}
    // For example, POST /api/chat-socket-session on your server
    export async function openChatSession(appIds: string[]) {
      await checkBuilderAccess(appIds); // your own access check
      const response = await fetch("https://app.base44.com/api/v1/socket-sessions", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.BASE44_WORKSPACE_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ app_ids: appIds }),
      });
      if (response.status !== 201) throw new Error(`Couldn't open a session: ${response.status}`);

      const { session_id, session_token, socket_url, socket_path } = await response.json();
      await saveSession(session_id); // stays on your server
      return { session_token, socket_url, socket_path };
    }
    ```

    The response carries `session_id`, `session_token`, `socket_url`, and `socket_path`. Return `session_token`, `socket_url`, and `socket_path` to the browser, and keep `session_id` on your server.

    A session watches up to eight apps for one hour, and `expires_in` gives that time in seconds. Sessions are never extended, so open a new one on every call and don't return a cached token.
  </Step>

  <Step title="Connect from the browser">
    The browser connects with the session your endpoint returns, using the Platform SDK. Install `@base44/platform`, create a client with `createPlatformClient()`, and call `client.chat.init()` once per page.

    In the options, pass a `getSession()` function that calls the endpoint you added in the previous step and returns its JSON. The SDK connects to the `socket_url` and `socket_path` in that JSON.

    Then subscribe to each app you want to watch, connect, and clean up when the page closes:

    ```typescript theme={null}
    import { createPlatformClient } from "@base44/platform";

    const client = createPlatformClient();
    const chat = client.chat.init({
      async getSession() {
        const response = await fetch("/api/chat-socket-session", { method: "POST" });
        if (!response.ok) throw new Error("Couldn't open a session");
        return response.json(); // { session_token, socket_url, socket_path }
      },
      onError: (error) => showConnectionError(error.code),
    });

    const subscription = chat.subscribe("6a2024af837c7a06c83021c1", {
      onSnapshot: (snapshot) => showApp(snapshot),
      onEvent: (event) => applyEvent(event),
      onError: (error) => showAppError(error.code),
    });
    await chat.connect();

    // When the page closes
    subscription.unsubscribe();
    chat.close();
    ```

    Each browser tab needs its own session. A second connection with the same token replaces the first, so don't share a token between tabs. If the connection drops, the SDK retries five times and rejoins every active subscription with a fresh snapshot. The SDK calls `getSession()` again when the session expires or Base44 rejects its token. For every option and method, see the [client reference](/developers/references/platform-sdk/docs/functions/createPlatformClient).
  </Step>

  <Step title="Apply snapshots and events">
    When you subscribe to an app, `onSnapshot()` receives the app's current state first, including the build status, the last 50 messages, and the prompt queue. Then `onEvent()` receives each live event, in order.

    Follow these rules when you apply a snapshot or an event:

    * **Replace:** Replace what you hold for the app with the snapshot, including the build status, the messages, and the prompt queue. To show older history, load it with [Read conversation messages](/api-reference/read-conversation-messages).
    * **Missing isn't empty:** If an event leaves out a field, keep the value you have. If an event sets a field to `null`, clear it.
    * **Branches:** An event with a `branch_id` belongs to that branch. An event with no `branch_id`, or with `branch_id` set to `null`, belongs to the main branch.

    <Note>
      **Live messages and HTTP messages are different shapes.** The transcript from [Read conversation messages](/api-reference/read-conversation-messages) carries the AI's raw tool calls. Live messages carry only the fields listed in [Socket messages](/developers/references/apps-api/sections/socket-messages). Map the HTTP messages into the live shape so one set of components renders both.
    </Note>

    Look up any event and its fields in [Socket messages](/developers/references/apps-api/sections/socket-messages). If an error comes back, [`PlatformSocketError`](/developers/references/platform-sdk/docs/interfaces/chat#platformsocketerror) explains each code and what to do about it.
  </Step>
</Steps>

## Change a session's apps

You can change which apps a session watches at any time from your server. Using the `session_id` you kept in the first step, call [Add app to session](/api-reference/add-app-to-session) to add an app or [Remove app from session](/api-reference/remove-app-from-session) to remove one. After you remove an app, a connected browser stops receiving its updates right away. When the page closes, call [End socket session](/api-reference/end-socket-session) from your server to end the session and disconnect the browser.

## Answer questions

During a build, the AI sometimes pauses to ask a question. The question arrives as a tool call in `message.updated`, with `status` set to `waiting_for_user_input`. Show the question in the browser. Your server then sends the answer with [Submit tool-call input](/api-reference/submit-tool-call-input), the same call you use in [the build turn](/developers/white-label/the-build-turn).

## See also

* [Socket sessions](/developers/references/apps-api/sections/socket-sessions): The endpoints that open, change, and end a session
* [Socket messages](/developers/references/apps-api/sections/socket-messages): Every message on the connection and the fields it carries
* [`PlatformSocketError`](/developers/references/platform-sdk/docs/interfaces/chat#platformsocketerror): What each error code means, and what to do about it
* [The build turn](/developers/white-label/the-build-turn): The calls that create, answer, and ship an app
* [Tenancy and credentials](/developers/white-label/tenancy-and-credentials): What reaches the browser, and what stays on your server


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.