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

# Settings & device events

> Events for camera startup, device availability and selection, and media send/receive settings.

These events fire when the camera starts or encounters an error, when input or output devices change, and when media send/receive settings are updated.

***

## started-camera

Fires when the local participant's camera starts. This happens as part of the standard join flow, or when explicitly calling [`startCamera()`](/reference/react-native/instance-methods/start-camera).

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

***

## camera-error

Fires when a camera or microphone error occurs. The `error.type` field categorizes the problem; `error.msg` is a human-readable description.

<Tip>
  For more on handling device errors, see the [device permissions guide](/docs/daily-js/guides/device-permissions).
</Tip>

<ResponseField name="action" type="string">
  Always `"camera-error"`.
</ResponseField>

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

<ResponseField name="error" type="object">
  Always contains `type` and `msg`. Some types include additional fields.

  <Expandable title="error.type values" defaultOpen="true">
    <ResponseField name="&#x22;not-found&#x22;" type="DailyCamDeviceNotFoundError">
      Camera and/or microphone not detected.

      * `missingMedia` — `Array<'video' | 'audio'>` — which devices were not found

      ```json theme={null}
      { "type": "not-found", "msg": "No device found.", "missingMedia": ["video", "audio"] }
      ```
    </ResponseField>

    <ResponseField name="&#x22;permissions&#x22;" type="DailyCamPermissionsError">
      User or browser blocked camera/microphone access.

      * `blockedBy` — `'user'` or `'browser'`
      * `blockedMedia` — `Array<'video' | 'audio'>` — which devices were blocked

      ```json theme={null}
      { "type": "permissions", "msg": "Permissions denied to the browser.", "blockedBy": "browser", "blockedMedia": ["video", "audio"] }
      ```
    </ResponseField>

    <ResponseField name="&#x22;cam-in-use&#x22; | &#x22;mic-in-use&#x22; | &#x22;cam-mic-in-use&#x22;" type="DailyCamInUseError">
      Camera and/or microphone in use by another application. Windows only.

      ```json theme={null}
      { "type": "cam-in-use", "msg": "Camera in use by another application." }
      ```
    </ResponseField>

    <ResponseField name="&#x22;constraints&#x22;" type="DailyCamConstraintsError">
      `getUserMedia()` was called with invalid or empty constraints.

      * `reason` — `'invalid'` or `'none-specified'`
      * `failedMedia` — `Array<'video' | 'audio'>` — which devices were affected

      ```json theme={null}
      { "type": "constraints", "msg": "Invalid constraints provided.", "reason": "invalid", "failedMedia": ["video"] }
      ```
    </ResponseField>

    <ResponseField name="&#x22;undefined-mediadevices&#x22;" type="DailyCamTypeError">
      `window.navigator.mediaDevices` is undefined. Most commonly caused by accessing the call over `http` instead of `https`.

      ```json theme={null}
      { "type": "undefined-mediadevices", "msg": "navigator.mediaDevices is undefined. Check url for https." }
      ```
    </ResponseField>

    <ResponseField name="&#x22;unknown&#x22;" type="DailyCamUnknownError">
      Uncategorized error. The original browser error message is in `msg`.

      ```json theme={null}
      { "type": "unknown", "msg": "Unknown device error (NotReadableError)" }
      ```
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="errorMsg" type="string | object" deprecated>
  Retained for backwards compatibility.
</ResponseField>

```javascript theme={null}
call.on('camera-error', ({ error }) => {
  if (error?.type === 'permissions') {
    showPermissionsPrompt(error.blockedBy);
  } else if (error?.type === 'not-found') {
    showNoDeviceMessage(error.missingMedia);
  } else {
    showGenericDeviceError(error?.msg);
  }
});
```

***

## available-devices-updated

Fires when a device becomes available or is removed — for example when a headset is connected or disconnected. See [`enumerateDevices()`](/reference/react-native/instance-methods/enumerate-devices) for details on the device properties returned.

<ResponseField name="action" type="string">
  Always `"available-devices-updated"`.
</ResponseField>

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

<ResponseField name="availableDevices" type="MediaDeviceInfo[]">
  An array of [`MediaDeviceInfo`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo) objects representing all devices currently available to the browser.
</ResponseField>

```json theme={null}
// Example event object
{
  "action": "available-devices-updated",
  "callClientId": "17225364729060.9442072768918943",
  "availableDevices": [
    { "deviceId": "abc123", "groupId": "", "kind": "videoinput", "label": "Front Camera" },
    { "deviceId": "def456", "groupId": "", "kind": "audioinput", "label": "Built-in Microphone" },
    { "deviceId": "ghi789", "groupId": "", "kind": "audiooutput", "label": "Built-in Speakers" }
  ]
}
```

***

## selected-devices-updated

Fires when the participant selects a new input or output device. Unlike [`available-devices-updated`](#available-devices-updated), which fires whenever the system device list changes, this event only fires when the participant has actively chosen a different device.

<ResponseField name="action" type="string">
  Always `"selected-devices-updated"`.
</ResponseField>

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

<ResponseField name="devices" type="object">
  Contains `camera`, `mic`, and `speaker` keys with [`MediaDeviceInfo`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo)-shaped objects for the newly selected devices.
</ResponseField>

```json theme={null}
// Example event object
{
  "action": "selected-devices-updated",
  "callClientId": "17225364729060.9442072768918943",
  "devices": {
    "camera": {},
    "mic": {},
    "speaker": { "deviceId": "deviceId", "kind": "audiooutput", "label": "label", "groupId": "groupId" }
  }
}
```

***

## input-settings-updated

Fires every time the input settings object changes. Includes all current input settings, even those that did not change. See [`updateInputSettings()`](/reference/react-native/instance-methods/update-input-settings) for details on the settings shape.

<ResponseField name="action" type="string">
  Always `"input-settings-updated"`.
</ResponseField>

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

<ResponseField name="inputSettings" type="object">
  The full current input settings object, including `video` and `audio` keys with their `settings` and `processor` sub-objects.
</ResponseField>

```json theme={null}
// Example event object
{
  "action": "input-settings-updated",
  "callClientId": "17225364729060.9442072768918943",
  "inputSettings": {
    "video": {
      "settings": { "frameRate": 15 },
      "processor": { "type": "background-blur", "config": { "strength": 0.2 } }
    },
    "audio": {
      "settings": { "deviceId": "default", "echoCancellation": false },
      "processor": { "type": "noise-cancellation" }
    }
  }
}
```

***

## send-settings-updated

Fires when the call's send settings change. Includes the full current send settings object.

<ResponseField name="action" type="string">
  Always `"send-settings-updated"`.
</ResponseField>

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

<ResponseField name="sendSettings" type="DailySendSettings">
  The full current send settings object. See [`updateSendSettings()`](/reference/react-native/instance-methods/update-send-settings) for the shape.
</ResponseField>

```json theme={null}
// Example event object
{
  "action": "send-settings-updated",
  "callClientId": "17225364729060.9442072768918943",
  "sendSettings": {
    "video": "default"
  }
}
```

***

## receive-settings-updated

Fires when the call's receive settings change. Includes the full current receive settings object.

<ResponseField name="action" type="string">
  Always `"receive-settings-updated"`.
</ResponseField>

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

<ResponseField name="receiveSettings" type="DailyReceiveSettings">
  The full current receive settings object. See [`updateReceiveSettings()`](/reference/react-native/instance-methods/update-receive-settings) for the shape.
</ResponseField>

```json theme={null}
// Example event object
{
  "action": "receive-settings-updated",
  "callClientId": "17225364729060.9442072768918943",
  "receiveSettings": {
    "base": { "video": { "layer": 2 } }
  }
}
```

## See also

<CardGroup>
  <Card title="Methods" icon="code" iconType="solid">
    * [startCamera()](/reference/react-native/instance-methods/start-camera)
    * [enumerateDevices()](/reference/react-native/instance-methods/enumerate-devices)
    * [updateInputSettings()](/reference/react-native/instance-methods/update-input-settings)
    * [updateSendSettings()](/reference/react-native/instance-methods/update-send-settings)
    * [updateReceiveSettings()](/reference/react-native/instance-methods/update-receive-settings)
  </Card>

  <Card title="Guides" icon="book-open" iconType="solid">
    * [Audio and video](/docs/daily-js/guides/audio-video)
    * [Device permissions](/docs/daily-js/guides/device-permissions)
  </Card>
</CardGroup>
