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

# Socket messages

> Every message on a socket session's connection, in both directions, and its payload.

> [!NOTE]
>
> This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.

This connection delivers live updates of the AI chat for the apps a white-label session can watch. It uses Socket.IO, not a raw WebSocket. Connect with `io(socket_url, { path: socket_path, transports: ["websocket"], auth: { session_token } })`, using the values your server received from `POST /api/v1/socket-sessions`. Then send `join` for each app to receive the app's snapshot, followed by live events.

Available only to white-label workspaces on the Builder plan or higher, with live AI chat updates turned on. Ask your onboarding contact to turn them on for your workspace.

Send the session token in the Socket.IO CONNECT `auth` as `session_token`. A refused connection is a `connect_error` with `message: "connection_denied"` and `data: { retryable }`. If `retryable` is true, retry with backoff. Otherwise, ask your server for a new session.

One connection per session carries the events of every app it joins. In an event's `data`, a missing field is unchanged and an explicit `null` clears it. The `app.snapshot` event is the exception, since it replaces the app's state.

## Event format

Every event the server sends is an object with two fields:

**room** `string | null` *required*

The app the event belongs to, as `/apps/{app_id}`. It is `null` for `session.ended`, which concerns the whole session.

**data** `object` *required*

The event's payload. Its fields depend on the event.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "path": "/sign-in",
    "force": false,
    "branch_id": null
  }
}
```

## Events from the server

### `message.updated`

A chat message was added or replaced. Replace the message with the same `id`.

**`data` fields**

**message** `object` *required*

The message in full, as it now reads.

**child attributes**

**id** `string | null`

ID of the message. An update carries the whole message again under the same ID.

**role** `'user' | 'assistant' | 'system' | null`

Who sent the message. The value is `user` for a message a person sent and `assistant` for the AI's reply. Messages with the `system` role are never sent.

**content** `string | null`

Text of the message. Attachments and structured content are left out.

**tool\_calls** `object[] | null`

The tool calls the AI made in this message, in order. Each is updated in place as it progresses.

Every shape has these fields:

**child attributes**

**id** `string | null`

ID of the call. Every update to the call carries the same ID.

**requires\_user\_input** `boolean | null`

Whether the call has paused for the user's answer or approval. The value becomes `true` once it pauses and stays `true` after the user answers, so read `status` to know whether it's still waiting.

**auto\_approved** `boolean | null`

Whether the call skipped its approval because the app has Auto approve on. The value is `true` when the call needed approval but ran at once. It never paused, and its result is real.

**status** `'running' | 'success' | 'error' | 'stopped' | 'waiting_for_user_input' | null`

State of the call. The value is `running` while the tool works, `success` or `error` once it finished, `stopped` when the user stopped the turn, or `waiting_for_user_input` while it waits for the user's answer or approval.

**mutation\_applied** `boolean | null`

Whether the call changed the app or its data. `false` means it finished without changing anything. `null` means the tool did not report it, so whether it changed anything is unknown.

**waiting\_on** `object | null`

What kind of answer the call waits for, while `status` is `waiting_for_user_input`.

**child attributes**

**kind** `'choice' | 'input' | 'approval'`

What the call needs from the user. The value is `choice` to pick among options, `input` to supply values, or `approval` to approve or reject.

**approval** `object | null`

Why the call waits for approval, from the check that paused it. Present only while `status` is `waiting_for_user_input`.

One of these shapes, told apart by `guard`:

**backend\_function\_entity\_delete**

Waiting for approval because testing a backend function would delete records from an entity.

**guard** `'backend_function_entity_delete'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**function\_name** `string`

Backend function under test.

**method** `string`

Entity method the function calls.

**inspection\_failed** `boolean`

The check could not verify the function's source.

**bash\_approval**

Waiting for approval because the AI wants to run a shell command that needs a review first. The command itself is not published.

**guard** `'bash_approval'` *required*

The check that paused the call.

**entity\_rls\_guard**

Waiting for approval because the AI wants to change who can read or write an entity's records.

**guard** `'entity_rls_guard'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**entity\_name** `string`

Entity whose access rules change.

**change\_type** `string`

How the access rules change.

**changed\_ops** `string[]`

Access operations whose rules change.

**exec\_tool\_entity\_mutation**

Waiting for approval because the AI's code would update or delete records in an entity.

**guard** `'exec_tool_entity_mutation'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**method** `string`

Entity method the code calls, such as `delete`.

**summary** `string`

The agent's summary of what the code does.

**exec\_tool\_github\_repo\_write**

Waiting for approval because the AI's code would write to a GitHub repository.

**guard** `'exec_tool_github_repo_write'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**summary** `string`

The agent's summary of what the code does.

**exec\_tool\_invite\_user**

Waiting for approval because the AI's code would invite someone to the app by email.

**guard** `'exec_tool_invite_user'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**summary** `string`

The agent's summary of what the code does.

**exec\_tool\_send\_email**

Waiting for approval because the AI's code would send an email.

**guard** `'exec_tool_send_email'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**summary** `string`

The agent's summary of what the code does.

**exec\_tool\_send\_sms**

Waiting for approval because the AI's code would send a text message.

**guard** `'exec_tool_send_sms'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**summary** `string`

The agent's summary of what the code does.

**any other approval**

Waiting for approval from a check that publishes only its name.

**guard** `string` *required*

The check that paused the call.

Any value not matched by the other shapes.

Each shape adds its own fields, told apart by `name`:

**ask\_clarifying\_questions**

The AI asks the user questions before it goes on. The call waits until the user answers.

**name** `'ask_clarifying_questions'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**questions** `object[]`

Questions presented to the user.

**child attributes**

**question** `string`

Visible question text.

**type** `string`

Question category, such as `text`.

**description** `string`

Supporting text.

**multi\_select** `boolean`

More than one answer may be selected.

**covers** `string`

Plan section the question covers.

**options** `(string | object)[]`

Selectable options. A bare string is its label.

**child attributes**

**label** `string`

Visible option label.

**user\_input** `object | null`

The user's answer to the call, once given, for tools that take one.

**child attributes**

**answers** `object[]`

Answers supplied to the question card.

**child attributes**

**question\_index** `integer`

Zero-based question index.

**selected\_label** `string`

Label selected for a single-select question.

**selected\_labels** `string[]`

Labels selected for a multi-select question.

**custom\_text** `string`

Free-text answer. Structural filtering does not redact prose.

**ask\_plan\_questions**

The AI asks the user questions that shape the plan, in plan mode. The call waits until the user answers.

**name** `'ask_plan_questions'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**questions** `object[]`

Questions presented to the user.

**child attributes**

**question** `string`

Visible question text.

**type** `string`

Question category, such as `text`.

**description** `string`

Supporting text.

**multi\_select** `boolean`

More than one answer may be selected.

**covers** `string`

Plan section the question covers.

**options** `(string | object)[]`

Selectable options. A bare string is its label.

**child attributes**

**label** `string`

Visible option label.

**user\_input** `object | null`

The user's answer to the call, once given, for tools that take one.

**child attributes**

**answers** `object[]`

Answers supplied to the question card.

**child attributes**

**question\_index** `integer`

Zero-based question index.

**selected\_label** `string`

Label selected for a single-select question.

**selected\_labels** `string[]`

Labels selected for a multi-select question.

**custom\_text** `string`

Free-text answer. Structural filtering does not redact prose.

**bash**

The AI runs a shell command in the app's sandbox.

**name** `'bash'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Commands and output are never included.

**create\_entity\_records**

The AI adds records to one of the app's entities.

**name** `'create_entity_records'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**entity\_name** `string`

Entity type. Records and query values are never included.

**record\_count** `integer`

Number of records created.

**delete\_entities**

The AI deletes records from one of the app's entities.

**name** `'delete_entities'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**summary** `string`

The agent's summary of the change. Queries and record values are never included.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**entity\_name** `string`

Entity type. Records and query values are never included.

**delete\_file**

The AI deletes a file from the app.

**name** `'delete_file'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**edit\_repo\_file**

The AI edits a file in the imported repository.

**name** `'edit_repo_file'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**exec\_tool**

The AI runs code against the app's data and integrations.

**name** `'exec_tool'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Code and output are never included.

**writes\_entities** `boolean`

The code changed entity data, so refresh the preview.

**find\_replace**

The AI edits files by replacing text in them.

**name** `'find_replace'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**generate\_game\_background**

The AI generates a background image for a game. An `image.resolved` event follows when it is ready.

**name** `'generate_game_background'` *required*

The tool that was called.

**results** `string | null`

The tool's result, narrowed to what this tool publishes. Absent while the call waits for approval.

**generate\_game\_image**

The AI generates an image asset for a game. An `image.resolved` event follows when it is ready.

**name** `'generate_game_image'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**aspect\_ratio** `string`

Requested aspect ratio, such as `1:1`.

**results** `string | null`

The tool's result, narrowed to what this tool publishes. Absent while the call waits for approval.

**generate\_image**

The AI generates an image for the app. An `image.resolved` event follows when it is ready.

**name** `'generate_image'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**label** `string`

Visible media label.

**aspect\_ratio** `string`

Requested aspect ratio, such as `16:9`.

**results** `object | null`

The tool's result, narrowed to what this tool publishes. Absent while the call waits for approval.

**child attributes**

**placeholder\_url** `string`

Placeholder URL, used to associate an `image.resolved` event with this tool.

**status** `'pending' | 'completed' | 'failed'`

Current generation status.

**image\_url** `string | null`

Generated image URL, once available.

**generate\_prd**

The AI writes down the plan it settled with the user. In plan mode this call carries the plan itself.

**name** `'generate_prd'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**app\_name** `string`

App or feature name.

**intent\_and\_goal** `string`

What is being built and why.

**audience\_and\_roles** `string`

Who uses it and their roles.

**core\_flows** `string[]`

End-to-end user flows.

**technical\_requirements** `string`

Specific technical requirements.

**design\_preferences** `string`

Design preferences.

**prd\_type** `string`

Build or plan declaration, when the AI asks for one.

**store\_platform** `string`

Store platform settled in planning, for e-commerce plans.

**game\_engine** `string`

Engine settled in planning, for game plans.

**generate\_video**

The AI generates a video for the app.

**name** `'generate_video'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**label** `string`

Visible media label.

**aspect\_ratio** `string`

Requested aspect ratio, such as `16:9`.

**results** `string | null`

The tool's result, narrowed to what this tool publishes. Absent while the call waits for approval.

**install\_npm\_package**

The AI installs or removes npm packages in the app.

**name** `'install_npm_package'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**packages** `object[]`

Requested package operations.

**child attributes**

**name** `string`

Package name.

**action** `string`

Requested operation, such as `install`.

**preview\_execute\_code**

The AI runs code inside the app preview to inspect it.

**name** `'preview_execute_code'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Code and output are never included.

**writes\_entities** `boolean`

The code changed entity data, so refresh the preview.

**preview\_screenshot**

The AI takes a screenshot of the app preview to check its work.

**name** `'preview_screenshot'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Commands and output are never included.

**read\_only\_exec\_tool**

The AI runs code that only reads the app's data.

**name** `'read_only_exec_tool'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Code and output are never included.

**writes\_entities** `boolean`

The code changed entity data, so refresh the preview.

**read\_repo\_file**

The AI reads a file in the imported repository.

**name** `'read_repo_file'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**run\_shell\_command**

The AI runs a shell command in the imported repository's sandbox.

**name** `'run_shell_command'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Commands and output are never included.

**set\_secrets**

The AI asks the user for secret values, such as API keys. The call waits until the user supplies them.

**name** `'set_secrets'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**secrets\_schema** `object[]`

Requested secrets.

**child attributes**

**secretName** `string`

Requested secret name.

**description** `string`

Where to obtain it.

**update\_entities**

The AI updates records in one of the app's entities.

**name** `'update_entities'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**summary** `string`

The agent's summary of the change. Queries and record values are never included.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**entity\_name** `string`

Entity type. Records and query values are never included.

**update\_plan**

The AI adds settled points to the plan.

**name** `'update_plan'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**updates** `object[]`

Plan updates in their emitted order.

**child attributes**

**action** `string`

Update action.

**section** `string`

Plan section key.

**section\_label** `string`

User-facing section label.

**text** `string`

Plan point.

**sections\_with\_enough** `string[]`

Base plan sections the AI considers sufficiently specified.

**write\_file**

The AI writes a file in the app.

**name** `'write_file'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**write\_repo\_file**

The AI writes a file in the imported repository.

**name** `'write_repo_file'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**any other tool call**

A call to any other tool. Only its name and progress are published.

**name** `string` *required*

The tool that was called.

Any value not matched by the other shapes.

**checkpoint\_id** `string | null`

ID of the checkpoint tied to the message. On a message a person sent it holds the app before the turn, on the AI's final reply the app after it. Absent when the turn made no checkpoint.

**metadata** `object | null`

When the message was created.

**child attributes**

**created\_date** `string\<date-time\> | null`

Time the message was created, as a UTC timestamp in ISO 8601 format.

**additional\_message\_params** `object | null`

Flags on the message, such as plan mode. Only the flags listed here are published.

**child attributes**

**client\_creation\_id** `string`

Identifier the sending client attached, to match its optimistic message.

**plan\_mode** `boolean`

The message was sent in plan mode.

**plan\_approved** `boolean`

The message approves a plan.

**skip\_ai\_response** `boolean`

The message expects no AI reply.

**system\_message\_type** `string`

System message category.

**conversation\_id** `string | null`

ID of the conversation the message belongs to. Each branch has its own conversation, so a viewer showing one branch can drop another branch's messages.

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "message": {
      "id": "c4f2a8e1-6b3d-4f9a-8e2c-1d7b5a9f3e60",
      "role": "assistant",
      "content": "I added a sign-in page with email and Google.",
      "tool_calls": [
        {
          "id": "toolu_01HXq8",
          "name": "write_file",
          "requires_user_input": false,
          "auto_approved": false,
          "status": "success",
          "mutation_applied": null,
          "display": {
            "file_paths": [
              "src/pages/SignIn.jsx"
            ]
          }
        }
      ],
      "checkpoint_id": "68f1c2d4e7b91d003c45a1f9",
      "metadata": {
        "created_date": "2026-10-10T09:23:41"
      }
    },
    "conversation_id": "68f1c2d4e7b91d003c45a1f2",
    "branch_id": null
  }
}
```

### `message.removed`

A chat message was removed or hidden. An `id` the viewer never saw is a no-op.

**`data` fields**

**message\_id** `string` *required*

ID of the removed message.

**conversation\_id** `string | null`

ID of the conversation the message belongs to. Each branch has its own conversation, so a viewer showing one branch can drop another branch's messages.

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "message_id": "c4f2a8e1-6b3d-4f9a-8e2c-1d7b5a9f3e60",
    "conversation_id": "68f1c2d4e7b91d003c45a1f2",
    "branch_id": null
  }
}
```

### `app.status_changed`

The AI started, finished, or failed a turn. Null status clears it.

**`data` fields**

**status** `object | null` *required*

The new status, or `null` when the status was cleared.

**child attributes**

**state** `'ready' | 'processing' | 'error' | null`

Where the app is in its build lifecycle. Ready means idle with no build in progress, processing means the app is being generated or modified, and error means the last build failed. This tracks building, not publishing.

**turn\_id** `string | null`

ID of the user message whose turn the status belongs to.

**last\_updated\_date** `string\<date-time\> | null`

Time the status was last updated, as a UTC timestamp in ISO 8601 format.

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "status": {
      "state": "processing",
      "turn_id": "c4f2a8e1-6b3d-4f9a-8e2c-1d7b5a9f3e60",
      "last_updated_date": "2026-10-10T09:23:41Z"
    },
    "branch_id": null
  }
}
```

### `preview.reload_requested`

Reload the app preview.

**`data` fields**

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "branch_id": null
  }
}
```

### `preview.navigation_requested`

Show this page of the app in the preview.

**`data` fields**

**path** `string` *required*

Path of the page to show, relative to the app's root, such as `/settings`.

**force** `boolean` *required*

Navigate even when the user has moved away from the page.

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "path": "/sign-in",
    "force": false,
    "branch_id": null
  }
}
```

### `queue.updated`

The whole prompt queue, after any change.

**`data` fields**

**items** `object[] | null`

Queued prompts, in the order they will run.

**child attributes**

**id** `string | null`

ID of the queued prompt.

**content** `string | null`

Text of the prompt.

**branch\_id** `string | null`

ID of the branch the prompt runs on, or `null` for the main branch.

**created\_at** `string | null`

Time the prompt was queued, as a UTC timestamp in ISO 8601 format.

**is\_paused** `boolean | null`

Whether the queue is paused, so queued prompts wait. A person can pause it, and Base44 pauses it while the AI waits for an answer.

**processed\_item\_id** `string | null`

ID of the queued prompt the AI just picked up to run. Absent when a prompt was added, removed, or cleared.

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "items": [
      {
        "id": "q_7d1e9c",
        "content": "Add a dark mode toggle to the header.",
        "branch_id": null,
        "created_at": "2026-10-10T09:24:05+00:00"
      }
    ],
    "is_paused": false,
    "branch_id": null
  }
}
```

### `task.progressed`

Progress of a long-running tool, by `tool_call_id`.

**`data` fields**

**tool\_call\_id** `string | null`

ID of the tool call that started the task.

**message\_id** `string | null`

ID of the message that holds that tool call.

**event\_type** `'task_started' | 'task_progress' | 'task_completed' | 'task_failed' | 'task_cancelled' | null`

Kind of progress update. The value is `task_started`, `task_progress`, `task_completed`, `task_failed`, or `task_cancelled`.

**progress** `object | null`

Progress so far.

**child attributes**

**current** `integer | null`

Items processed so far.

**total** `integer | null`

Items to process in all.

**percentage** `number | null`

Share of the work done, from 0 to 100.

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "tool_call_id": "toolu_01HXq8",
    "message_id": "c4f2a8e1-6b3d-4f9a-8e2c-1d7b5a9f3e60",
    "event_type": "task_progress",
    "progress": {
      "current": 250,
      "total": 1000,
      "percentage": 25
    },
    "branch_id": null
  }
}
```

### `image.resolved`

A generated image finished or failed. Replace its `placeholder_url` wherever it appears.

**`data` fields**

**status** `'pending' | 'completed' | 'failed' | null`

State of the image. The value is `pending` while the image generates, `completed` once `image_url` is ready, or `failed` when generation failed.

**placeholder\_url** `string | null`

Placeholder URL the app shows while the image generates. Match it to find where the image appears.

**image\_url** `string | null`

URL of the finished image, or `null` while it is pending or after it failed.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "status": "completed",
    "placeholder_url": "/__generating__/5e8b2f4a-1c3d-4e6f-9a7b-2d4c6e8f0a1b.png",
    "image_url": "https://media.base44.com/images/public/6a2024af837c7a06c83021c1/hero.png"
  }
}
```

### `conversation.changed`

The conversation was rewritten by an undo, restore, or sync. Rejoin the room for a fresh snapshot.

**`data` fields**

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "branch_id": null
  }
}
```

### `files.changed`

The app's files changed outside a chat turn.

**`data` fields**

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "branch_id": null
  }
}
```

### `branch.deleted`

A branch was deleted.

**`data` fields**

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "branch_id": "68f1c2d4e7b91d003c45a1fa"
  }
}
```

### `repository.changed`

The imported app's repository changed.

**`data` fields**

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "branch_id": null
  }
}
```

### `pull_request.changed`

The imported app's pull request changed.

**`data` fields**

**branch\_id** `string | null`

ID of the branch the change belongs to. Omitted or `null` means the main branch.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "branch_id": "68f1c2d4e7b91d003c45a1fa"
  }
}
```

### `session.ended`

The session ended because it expired, was revoked, or was taken by a newer socket. The socket disconnects next.

**`data` fields**

**reason** `'expired' | 'revoked' | 'replaced'` *required*

Why the session ended. When it's `expired`, ask your server for a new session. When it's `revoked`, your server or an admin ended it, so don't reconnect. When it's `replaced`, a newer socket took the session, so stop.

```json Example theme={null}
{
  "room": null,
  "data": {
    "reason": "revoked"
  }
}
```

### `room.access_denied`

A join was refused because the app is not on the session's allowlist, or the socket joins too often.

**`data` fields**

The `data` object is empty.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {}
}
```

### `room.access_revoked`

The app left the session's allowlist, or its workspace. Events for it stop. Do not rejoin.

**`data` fields**

The `data` object is empty.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {}
}
```

### `room.snapshot_unavailable`

The join held but its snapshot failed. Live events still arrive. Rejoin later for a snapshot.

**`data` fields**

The `data` object is empty.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {}
}
```

### `app.snapshot`

The app's current status and its last 50 public messages, after every join. Replace the app's state with it.

**`data` fields**

**status** `object | null` *required*

The app's build status, or `null` when none is recorded.

**child attributes**

**state** `'ready' | 'processing' | 'error' | null`

Where the app is in its build lifecycle. Ready means idle with no build in progress, processing means the app is being generated or modified, and error means the last build failed. This tracks building, not publishing.

**turn\_id** `string | null`

ID of the user message whose turn the status belongs to.

**last\_updated\_date** `string\<date-time\> | null`

Time the status was last updated, as a UTC timestamp in ISO 8601 format.

**messages** `object[]` *required*

The last 50 messages, oldest first.

**child attributes**

**id** `string | null`

ID of the message. An update carries the whole message again under the same ID.

**role** `'user' | 'assistant' | 'system' | null`

Who sent the message. The value is `user` for a message a person sent and `assistant` for the AI's reply. Messages with the `system` role are never sent.

**content** `string | null`

Text of the message. Attachments and structured content are left out.

**tool\_calls** `object[] | null`

The tool calls the AI made in this message, in order. Each is updated in place as it progresses.

Every shape has these fields:

**child attributes**

**id** `string | null`

ID of the call. Every update to the call carries the same ID.

**requires\_user\_input** `boolean | null`

Whether the call has paused for the user's answer or approval. The value becomes `true` once it pauses and stays `true` after the user answers, so read `status` to know whether it's still waiting.

**auto\_approved** `boolean | null`

Whether the call skipped its approval because the app has Auto approve on. The value is `true` when the call needed approval but ran at once. It never paused, and its result is real.

**status** `'running' | 'success' | 'error' | 'stopped' | 'waiting_for_user_input' | null`

State of the call. The value is `running` while the tool works, `success` or `error` once it finished, `stopped` when the user stopped the turn, or `waiting_for_user_input` while it waits for the user's answer or approval.

**mutation\_applied** `boolean | null`

Whether the call changed the app or its data. `false` means it finished without changing anything. `null` means the tool did not report it, so whether it changed anything is unknown.

**waiting\_on** `object | null`

What kind of answer the call waits for, while `status` is `waiting_for_user_input`.

**child attributes**

**kind** `'choice' | 'input' | 'approval'`

What the call needs from the user. The value is `choice` to pick among options, `input` to supply values, or `approval` to approve or reject.

**approval** `object | null`

Why the call waits for approval, from the check that paused it. Present only while `status` is `waiting_for_user_input`.

One of these shapes, told apart by `guard`:

**backend\_function\_entity\_delete**

Waiting for approval because testing a backend function would delete records from an entity.

**guard** `'backend_function_entity_delete'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**function\_name** `string`

Backend function under test.

**method** `string`

Entity method the function calls.

**inspection\_failed** `boolean`

The check could not verify the function's source.

**bash\_approval**

Waiting for approval because the AI wants to run a shell command that needs a review first. The command itself is not published.

**guard** `'bash_approval'` *required*

The check that paused the call.

**entity\_rls\_guard**

Waiting for approval because the AI wants to change who can read or write an entity's records.

**guard** `'entity_rls_guard'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**entity\_name** `string`

Entity whose access rules change.

**change\_type** `string`

How the access rules change.

**changed\_ops** `string[]`

Access operations whose rules change.

**exec\_tool\_entity\_mutation**

Waiting for approval because the AI's code would update or delete records in an entity.

**guard** `'exec_tool_entity_mutation'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**method** `string`

Entity method the code calls, such as `delete`.

**summary** `string`

The agent's summary of what the code does.

**exec\_tool\_github\_repo\_write**

Waiting for approval because the AI's code would write to a GitHub repository.

**guard** `'exec_tool_github_repo_write'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**summary** `string`

The agent's summary of what the code does.

**exec\_tool\_invite\_user**

Waiting for approval because the AI's code would invite someone to the app by email.

**guard** `'exec_tool_invite_user'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**summary** `string`

The agent's summary of what the code does.

**exec\_tool\_send\_email**

Waiting for approval because the AI's code would send an email.

**guard** `'exec_tool_send_email'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**summary** `string`

The agent's summary of what the code does.

**exec\_tool\_send\_sms**

Waiting for approval because the AI's code would send a text message.

**guard** `'exec_tool_send_sms'` *required*

The check that paused the call.

**reason** `string | null`

Why the call needs approval, as the check explained it.

**details** `object | null`

What the check found.

**child attributes**

**summary** `string`

The agent's summary of what the code does.

**any other approval**

Waiting for approval from a check that publishes only its name.

**guard** `string` *required*

The check that paused the call.

Any value not matched by the other shapes.

Each shape adds its own fields, told apart by `name`:

**ask\_clarifying\_questions**

The AI asks the user questions before it goes on. The call waits until the user answers.

**name** `'ask_clarifying_questions'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**questions** `object[]`

Questions presented to the user.

**child attributes**

**question** `string`

Visible question text.

**type** `string`

Question category, such as `text`.

**description** `string`

Supporting text.

**multi\_select** `boolean`

More than one answer may be selected.

**covers** `string`

Plan section the question covers.

**options** `(string | object)[]`

Selectable options. A bare string is its label.

**child attributes**

**label** `string`

Visible option label.

**user\_input** `object | null`

The user's answer to the call, once given, for tools that take one.

**child attributes**

**answers** `object[]`

Answers supplied to the question card.

**child attributes**

**question\_index** `integer`

Zero-based question index.

**selected\_label** `string`

Label selected for a single-select question.

**selected\_labels** `string[]`

Labels selected for a multi-select question.

**custom\_text** `string`

Free-text answer. Structural filtering does not redact prose.

**ask\_plan\_questions**

The AI asks the user questions that shape the plan, in plan mode. The call waits until the user answers.

**name** `'ask_plan_questions'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**questions** `object[]`

Questions presented to the user.

**child attributes**

**question** `string`

Visible question text.

**type** `string`

Question category, such as `text`.

**description** `string`

Supporting text.

**multi\_select** `boolean`

More than one answer may be selected.

**covers** `string`

Plan section the question covers.

**options** `(string | object)[]`

Selectable options. A bare string is its label.

**child attributes**

**label** `string`

Visible option label.

**user\_input** `object | null`

The user's answer to the call, once given, for tools that take one.

**child attributes**

**answers** `object[]`

Answers supplied to the question card.

**child attributes**

**question\_index** `integer`

Zero-based question index.

**selected\_label** `string`

Label selected for a single-select question.

**selected\_labels** `string[]`

Labels selected for a multi-select question.

**custom\_text** `string`

Free-text answer. Structural filtering does not redact prose.

**bash**

The AI runs a shell command in the app's sandbox.

**name** `'bash'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Commands and output are never included.

**create\_entity\_records**

The AI adds records to one of the app's entities.

**name** `'create_entity_records'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**entity\_name** `string`

Entity type. Records and query values are never included.

**record\_count** `integer`

Number of records created.

**delete\_entities**

The AI deletes records from one of the app's entities.

**name** `'delete_entities'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**summary** `string`

The agent's summary of the change. Queries and record values are never included.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**entity\_name** `string`

Entity type. Records and query values are never included.

**delete\_file**

The AI deletes a file from the app.

**name** `'delete_file'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**edit\_repo\_file**

The AI edits a file in the imported repository.

**name** `'edit_repo_file'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**exec\_tool**

The AI runs code against the app's data and integrations.

**name** `'exec_tool'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Code and output are never included.

**writes\_entities** `boolean`

The code changed entity data, so refresh the preview.

**find\_replace**

The AI edits files by replacing text in them.

**name** `'find_replace'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**generate\_game\_background**

The AI generates a background image for a game. An `image.resolved` event follows when it is ready.

**name** `'generate_game_background'` *required*

The tool that was called.

**results** `string | null`

The tool's result, narrowed to what this tool publishes. Absent while the call waits for approval.

**generate\_game\_image**

The AI generates an image asset for a game. An `image.resolved` event follows when it is ready.

**name** `'generate_game_image'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**aspect\_ratio** `string`

Requested aspect ratio, such as `1:1`.

**results** `string | null`

The tool's result, narrowed to what this tool publishes. Absent while the call waits for approval.

**generate\_image**

The AI generates an image for the app. An `image.resolved` event follows when it is ready.

**name** `'generate_image'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**label** `string`

Visible media label.

**aspect\_ratio** `string`

Requested aspect ratio, such as `16:9`.

**results** `object | null`

The tool's result, narrowed to what this tool publishes. Absent while the call waits for approval.

**child attributes**

**placeholder\_url** `string`

Placeholder URL, used to associate an `image.resolved` event with this tool.

**status** `'pending' | 'completed' | 'failed'`

Current generation status.

**image\_url** `string | null`

Generated image URL, once available.

**generate\_prd**

The AI writes down the plan it settled with the user. In plan mode this call carries the plan itself.

**name** `'generate_prd'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**app\_name** `string`

App or feature name.

**intent\_and\_goal** `string`

What is being built and why.

**audience\_and\_roles** `string`

Who uses it and their roles.

**core\_flows** `string[]`

End-to-end user flows.

**technical\_requirements** `string`

Specific technical requirements.

**design\_preferences** `string`

Design preferences.

**prd\_type** `string`

Build or plan declaration, when the AI asks for one.

**store\_platform** `string`

Store platform settled in planning, for e-commerce plans.

**game\_engine** `string`

Engine settled in planning, for game plans.

**generate\_video**

The AI generates a video for the app.

**name** `'generate_video'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**label** `string`

Visible media label.

**aspect\_ratio** `string`

Requested aspect ratio, such as `16:9`.

**results** `string | null`

The tool's result, narrowed to what this tool publishes. Absent while the call waits for approval.

**install\_npm\_package**

The AI installs or removes npm packages in the app.

**name** `'install_npm_package'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**packages** `object[]`

Requested package operations.

**child attributes**

**name** `string`

Package name.

**action** `string`

Requested operation, such as `install`.

**preview\_execute\_code**

The AI runs code inside the app preview to inspect it.

**name** `'preview_execute_code'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Code and output are never included.

**writes\_entities** `boolean`

The code changed entity data, so refresh the preview.

**preview\_screenshot**

The AI takes a screenshot of the app preview to check its work.

**name** `'preview_screenshot'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Commands and output are never included.

**read\_only\_exec\_tool**

The AI runs code that only reads the app's data.

**name** `'read_only_exec_tool'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Code and output are never included.

**writes\_entities** `boolean`

The code changed entity data, so refresh the preview.

**read\_repo\_file**

The AI reads a file in the imported repository.

**name** `'read_repo_file'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**run\_shell\_command**

The AI runs a shell command in the imported repository's sandbox.

**name** `'run_shell_command'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**summary** `string`

Reviewed activity summary. Commands and output are never included.

**set\_secrets**

The AI asks the user for secret values, such as API keys. The call waits until the user supplies them.

**name** `'set_secrets'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**secrets\_schema** `object[]`

Requested secrets.

**child attributes**

**secretName** `string`

Requested secret name.

**description** `string`

Where to obtain it.

**update\_entities**

The AI updates records in one of the app's entities.

**name** `'update_entities'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**summary** `string`

The agent's summary of the change. Queries and record values are never included.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**entity\_name** `string`

Entity type. Records and query values are never included.

**update\_plan**

The AI adds settled points to the plan.

**name** `'update_plan'` *required*

The tool that was called.

**arguments** `object | null`

What the AI asked the tool to do, narrowed to what this tool publishes.

**child attributes**

**updates** `object[]`

Plan updates in their emitted order.

**child attributes**

**action** `string`

Update action.

**section** `string`

Plan section key.

**section\_label** `string`

User-facing section label.

**text** `string`

Plan point.

**sections\_with\_enough** `string[]`

Base plan sections the AI considers sufficiently specified.

**write\_file**

The AI writes a file in the app.

**name** `'write_file'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**write\_repo\_file**

The AI writes a file in the imported repository.

**name** `'write_repo_file'` *required*

The tool that was called.

**display** `object | null`

What the tool touched, for showing its progress. Never file contents or commands.

**child attributes**

**file\_paths** `string[]`

Changed file paths. Source bodies and diffs are never included.

**content\_empty** `boolean`

A write intentionally used empty content.

**any other tool call**

A call to any other tool. Only its name and progress are published.

**name** `string` *required*

The tool that was called.

Any value not matched by the other shapes.

**checkpoint\_id** `string | null`

ID of the checkpoint tied to the message. On a message a person sent it holds the app before the turn, on the AI's final reply the app after it. Absent when the turn made no checkpoint.

**metadata** `object | null`

When the message was created.

**child attributes**

**created\_date** `string\<date-time\> | null`

Time the message was created, as a UTC timestamp in ISO 8601 format.

**additional\_message\_params** `object | null`

Flags on the message, such as plan mode. Only the flags listed here are published.

**child attributes**

**client\_creation\_id** `string`

Identifier the sending client attached, to match its optimistic message.

**plan\_mode** `boolean`

The message was sent in plan mode.

**plan\_approved** `boolean`

The message approves a plan.

**skip\_ai\_response** `boolean`

The message expects no AI reply.

**system\_message\_type** `string`

System message category.

**queue** `object` *required*

The main branch's prompt queue.

**child attributes**

**items** `object[] | null`

Queued prompts, in the order they will run.

**child attributes**

**id** `string | null`

ID of the queued prompt.

**content** `string | null`

Text of the prompt.

**branch\_id** `string | null`

ID of the branch the prompt runs on, or `null` for the main branch.

**created\_at** `string | null`

Time the prompt was queued, as a UTC timestamp in ISO 8601 format.

**is\_paused** `boolean | null`

Whether the queue is paused, so queued prompts wait. A person can pause it, and Base44 pauses it while the AI waits for an answer.

```json Example theme={null}
{
  "room": "/apps/6a2024af837c7a06c83021c1",
  "data": {
    "status": {
      "state": "ready",
      "turn_id": "c4f2a8e1-6b3d-4f9a-8e2c-1d7b5a9f3e60",
      "last_updated_date": "2026-10-10T09:23:41Z"
    },
    "messages": [
      {
        "id": "c4f2a8e1-6b3d-4f9a-8e2c-1d7b5a9f3e60",
        "role": "assistant",
        "content": "I added a sign-in page with email and Google.",
        "tool_calls": [
          {
            "id": "toolu_01HXq8",
            "name": "write_file",
            "requires_user_input": false,
            "auto_approved": false,
            "status": "success",
            "mutation_applied": null,
            "display": {
              "file_paths": [
                "src/pages/SignIn.jsx"
              ]
            }
          }
        ],
        "checkpoint_id": "68f1c2d4e7b91d003c45a1f9",
        "metadata": {
          "created_date": "2026-10-10T09:23:41"
        }
      }
    ],
    "queue": {
      "items": [
        {
          "id": "q_7d1e9c",
          "content": "Add a dark mode toggle to the header.",
          "branch_id": null,
          "created_at": "2026-10-10T09:24:05+00:00"
        }
      ],
      "is_paused": false
    }
  }
}
```

## Messages from the browser

### `join`

Join an app's room, once per app after every connect. An `app.snapshot` follows, then its live events. Refused with `room.access_denied` when the app is not on the session's allowlist, or past 30 joins a minute.

The payload is a `string`, not an object. Pattern: `^/apps/[0-9a-f]{24}$`

```json Example theme={null}
"/apps/6a2024af837c7a06c83021c1"
```

### `leave`

Leave an app's room. Its events stop.

The payload is a `string`, not an object. Pattern: `^/apps/[0-9a-f]{24}$`

```json Example theme={null}
"/apps/6a2024af837c7a06c83021c1"
```


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