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

# Lifecycle events

> Events for the full call lifecycle — loading, joining, leaving, and destruction.

These events fire at key points in the call lifecycle — from the moment the call bundle starts loading through joining, leaving, and destroying the call instance.

***

## loading

<Badge color="green">{"✓"} Prebuilt</Badge> <Badge color="green">{"✓"} Custom</Badge>

Fires when the JavaScript bundle responsible for the call begins loading. This is the first event in the [`join()`](/reference/daily-js/instance-methods/join) sequence, or the [`load()`](/reference/daily-js/instance-methods/load) sequence if you invoke that directly.

```json theme={null}
// Example event object
{
  "action": "loading",
  "callClientId": "17225364729060.9442072768918943"
}
```

```javascript theme={null}
call.on('loading', () => {
  document.getElementById('status').textContent = 'Connecting…';
});
```

***

## loaded

<Badge color="green">{"✓"} Prebuilt</Badge> <Badge color="green">{"✓"} Custom</Badge>

Fires when the JavaScript bundle has finished loading. This occurs right before [`joining-meeting`](#joining-meeting) in the [`join()`](/reference/daily-js/instance-methods/join) sequence, or as the final event in the [`load()`](/reference/daily-js/instance-methods/load) sequence.

```json theme={null}
// Example event object
{
  "action": "loaded",
  "callClientId": "17225364729060.9442072768918943"
}
```

***

## load-attempt-failed

<Badge color="green">{"✓"} Prebuilt</Badge> <Badge color="green">{"✓"} Custom</Badge>

Fires when a single attempt to load the call bundle has failed. Daily retries a few times before emitting a fatal [`error`](/reference/daily-js/events/error-events#error) event.

<ResponseField name="action" type="string">
  Always `"load-attempt-failed"`.
</ResponseField>

<ResponseField name="callClientId" type="string">
  The ID of the call client instance that emitted this event.
</ResponseField>

<ResponseField name="errorMsg" type="string">
  A human-readable description of why the load attempt failed.
</ResponseField>

```json theme={null}
// Example event object
{
  "action": "load-attempt-failed",
  "errorMsg": "Timed out (>20000 ms) when loading call object bundle https://c.daily.co/static/call-machine-object-bundle.js",
  "callClientId": "17225364729060.9442072768918943"
}
```

***

## joining-meeting

<Badge color="green">{"✓"} Prebuilt</Badge> <Badge color="green">{"✓"} Custom</Badge>

Fires once the call bundle has loaded and the participant is actively connecting. This follows [`loaded`](#loaded) in a successful [`join()`](/reference/daily-js/instance-methods/join) sequence.

```json theme={null}
// Example event object
{
  "action": "joining-meeting",
  "callClientId": "17225364729060.9442072768918943"
}
```

***

## joined-meeting

<Badge color="green">{"✓"} Prebuilt</Badge> <Badge color="green">{"✓"} Custom</Badge>

Fires once the local participant has successfully joined the call.

<Note>
  The `participants` object in this event only includes the local participant. Remote participant information is sent in batches of 50 after this event fires via [`participant-joined`](/reference/daily-js/events/participant-events#participant-joined) events. To get a total count at join time, use [`participantCounts()`](/reference/daily-js/instance-methods/participant-counts).
</Note>

<ResponseField name="action" type="string">
  Always `"joined-meeting"`.
</ResponseField>

<ResponseField name="callClientId" type="string">
  The ID of the call client instance that emitted this event.
</ResponseField>

<ResponseField name="participants" type="object">
  Contains only the local participant at join time. See [`DailyParticipant`](/reference/daily-js/types/daily-participant) for the full shape.
</ResponseField>

```json theme={null}
// Example event object
{
  "action": "joined-meeting",
  "callClientId": "17225364729060.9442072768918943",
  "participants": {
    "local": {
      "session_id": "a64d30f4-5216-4481-a2ef-515d6dd7dfc6",
      "user_name": "A. User Name",
      "user_id": "user_123",
      "joined_at": "2023-06-01T18:55:54.941Z",
      "local": true,
      "owner": false,
      "networkQualityState": "good",
      "permissions": {
        "hasPresence": true,
        "canSend": true,
        "canReceive": { "base": true },
        "canAdmin": false
      },
      "will_eject_at": "1970-01-01T00:00:00.000Z",
      "tracks": {
        "audio": { "state": "playable" },
        "video": { "state": "playable" },
        "screenVideo": { "state": "off" },
        "screenAudio": { "state": "off" }
      },
      "record": false
    }
  }
}
```

```javascript theme={null}
call.on('joined-meeting', ({ participants }) => {
  const local = participants.local;
  console.log('Joined as', local.user_name || local.user_id);
  showCallUI();
});
```

***

## left-meeting

<Badge color="green">{"✓"} Prebuilt</Badge> <Badge color="green">{"✓"} Custom</Badge>

Fires once the local participant has left the call.

```json theme={null}
// Example event object
{
  "action": "left-meeting",
  "callClientId": "17225364729060.9442072768918943"
}
```

```javascript theme={null}
call.on('left-meeting', () => {
  showLobbyUI();
});
```

***

## call-instance-destroyed

<Badge color="green">{"✓"} Prebuilt</Badge> <Badge color="green">{"✓"} Custom</Badge>

Fires after [`destroy()`](/reference/daily-js/instance-methods/destroy) has been called and all resources have been freed. After this event, [`isDestroyed()`](/reference/daily-js/instance-methods/is-destroyed) returns `true`. Listen for this event if you store the call instance in multiple places, to ensure all references are cleared.

```json theme={null}
// Example event object
{
  "action": "call-instance-destroyed",
  "callClientId": "17225364729060.9442072768918943"
}
```

```javascript theme={null}
call.on('call-instance-destroyed', () => {
  callRef.current = null;
});
```

***

## access-state-updated

<Badge color="green">{"✓"} Prebuilt</Badge> <Badge color="green">{"✓"} Custom</Badge>

Fires when [`accessState()`](/reference/daily-js/instance-methods/access-state) changes — either the participant's access level changed, or an access request was made or resolved.

<ResponseField name="action" type="string">
  Always `"access-state-updated"`.
</ResponseField>

<ResponseField name="callClientId" type="string">
  The ID of the call client instance that emitted this event.
</ResponseField>

<ResponseField name="access" type="object">
  The current access state. The `level` field is one of `'none'`, `'lobby'`, or `'full'`.
</ResponseField>

<ResponseField name="awaitingAccess" type="object">
  Present when the participant has requested access that hasn't yet been granted or denied. Contains a `level` field for the requested access level.
</ResponseField>

```json theme={null}
// Example: participant has full access
{
  "action": "access-state-updated",
  "callClientId": "17225364729060.9442072768918943",
  "access": { "level": "full" }
}
```

```json theme={null}
// Example: participant is in the lobby, awaiting full access
{
  "action": "access-state-updated",
  "callClientId": "17225364729060.9442072768918943",
  "access": { "level": "lobby" },
  "awaitingAccess": { "level": "full" }
}
```

```javascript theme={null}
call.on('access-state-updated', ({ access }) => {
  if (access.level === 'lobby') {
    showWaitingRoomUI();
  } else if (access.level === 'full') {
    hideWaitingRoomUI();
  }
});
```

***

## See also

<CardGroup>
  <Card title="Methods" icon="code" iconType="solid">
    * [join()](/reference/daily-js/instance-methods/join)
    * [leave()](/reference/daily-js/instance-methods/leave)
    * [load()](/reference/daily-js/instance-methods/load)
    * [destroy()](/reference/daily-js/instance-methods/destroy)
    * [accessState()](/reference/daily-js/instance-methods/access-state)
  </Card>

  <Card title="Events" icon="bolt" iconType="solid">
    * [Participant events](/reference/daily-js/events/participant-events)
    * [Error events](/reference/daily-js/events/error-events)
  </Card>

  <Card title="Guides" icon="book-open" iconType="solid">
    * [Events](/docs/daily-js/concepts/events)
    * [Waiting room](/docs/daily-js/guides/waiting-room)
  </Card>
</CardGroup>
