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

# Callbacks and events

> Reference for the Akapulu React event stream and event payloads.

## Overview

The Akapulu React SDK exposes a normalized conversation event stream through `useAkapuluEvents(...)`.

This hook lets you react to conversation lifecycle changes, transcript updates, tool events, node changes, bot speaking state, and timeout events.

## Event handling

Use `useAkapuluEvents(listener)` anywhere under `AkapuluProvider`.

```tsx theme={null}
import { useAkapuluEvents } from "@akapulu/react";

function EventLogger() {
  useAkapuluEvents((event) => {
    if (event.type === "tool_event") {
      console.log(event.tool.functionName);
      return;
    }

    if (event.type === "transcript_updated") {
      console.log(event.transcript.text);
    }
  });

  return null;
}
```

## Hook signature

```ts theme={null}
useAkapuluEvents(listener: (event: AkapuluEvent) => void): void
```

<ParamField path="listener" type="(event: AkapuluEvent) => void" required>
  Listener invoked whenever the Akapulu session store emits a normalized event.
</ParamField>

## Main unions

### `SessionStatus`

```ts theme={null}
type SessionStatus =
  | "idle"
  | "connecting"
  | "connected"
  | "disconnecting"
  | "ended"
  | "error";
```

### `BotSpeakingState`

```ts theme={null}
type BotSpeakingState = "idle" | "speaking" | "listening";
```

### `ToolMessageType`

```ts theme={null}
type ToolMessageType = "RAG" | "vision" | "http";
```

### `TimeoutReason`

```ts theme={null}
type TimeoutReason = "duration_limit_reached" | "participant_join_timeout";
```

## Event types

### `status_changed`

<ParamField path="type" type="&#x22;status_changed&#x22;">
  Event discriminator.
</ParamField>

<ParamField path="status" type="&#x22;idle&#x22; | &#x22;connecting&#x22; | &#x22;connected&#x22; | &#x22;disconnecting&#x22; | &#x22;ended&#x22; | &#x22;error&#x22;">
  Current high-level session lifecycle state.
</ParamField>

### `bot_speaking_state_changed`

<ParamField path="type" type="&#x22;bot_speaking_state_changed&#x22;">
  Event discriminator.
</ParamField>

<ParamField path="speakingState" type="&#x22;idle&#x22; | &#x22;speaking&#x22; | &#x22;listening&#x22;">
  Current speaking or listening state for the bot participant.
</ParamField>

### `node_changed`

<ParamField path="type" type="&#x22;node_changed&#x22;">
  Event discriminator.
</ParamField>

<ParamField path="node" type="{ key: string; label: string } | null">
  Current scenario node, or `null` if no node is active.
</ParamField>

### `tool_event`

<ParamField path="type" type="&#x22;tool_event&#x22;">
  Event discriminator.
</ParamField>

<ParamField path="tool" type="NormalizedToolEvent">
  Normalized tool event payload.

  <Expandable title="NormalizedToolEvent" defaultOpen={true}>
    <ParamField path="messageType" type="&#x22;RAG&#x22; | &#x22;vision&#x22; | &#x22;http&#x22;">
      Tool message type.
    </ParamField>

    <ParamField path="functionName" type="string">
      Tool or function name.
    </ParamField>

    <ParamField path="summary" type="string">
      Human-readable summary for the tool event.
    </ParamField>

    <ParamField path="query" type="string | undefined">
      Query string for RAG events when present.
    </ParamField>

    <ParamField path="argsJson" type="string | undefined">
      Pretty JSON representation of HTTP tool arguments when present.
    </ParamField>

    <ParamField path="body" type="Record<string, unknown>">
      Raw body arguments for the tool event.
    </ParamField>

    <ParamField path="rawMessage" type="unknown">
      Underlying raw message before normalization.
    </ParamField>
  </Expandable>
</ParamField>

### `transcript_updated`

<ParamField path="type" type="&#x22;transcript_updated&#x22;">
  Event discriminator.
</ParamField>

<ParamField path="transcript" type="TranscriptEntry">
  Transcript row payload.

  <Expandable title="TranscriptEntry" defaultOpen={true}>
    <ParamField path="id" type="string">
      Stable transcript row identifier.
    </ParamField>

    <ParamField path="text" type="string">
      Transcript text.
    </ParamField>

    <ParamField path="speaker" type="&#x22;user&#x22; | &#x22;bot&#x22;">
      Speaker that produced the transcript row.
    </ParamField>

    <ParamField path="timestamp" type="string">
      Timestamp for the transcript row.
    </ParamField>

    <ParamField path="isFinal" type="boolean">
      Whether the transcript row is finalized.
    </ParamField>
  </Expandable>
</ParamField>

### `call_ready`

<ParamField path="type" type="&#x22;call_ready&#x22;">
  Event discriminator indicating the call reached ready state.
</ParamField>

### `timeout`

<ParamField path="type" type="&#x22;timeout&#x22;">
  Event discriminator.
</ParamField>

<ParamField path="reason" type="&#x22;duration_limit_reached&#x22; | &#x22;participant_join_timeout&#x22;">
  Timeout reason reported by the backend.
</ParamField>

## Related docs

* [React](/web-sdk/react-sdk)
* [React UI](/web-sdk/react-ui)
* [Customize Conversation UI](/guides/conversations/customize-conversation-ui)
