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

# Call configuration

> Understand how DailyCallOptions merges across constructor, load(), preAuth(), startCamera(), and join().

`DailyCallOptions` can be passed to several methods: the factory constructor (`createCallObject`, `createFrame`, etc.), [`load()`](/reference/daily-js/instance-methods/load), [`preAuth()`](/reference/daily-js/instance-methods/pre-auth), [`startCamera()`](/reference/daily-js/instance-methods/start-camera), and [`join()`](/reference/daily-js/instance-methods/join).

Each call merges the new options into the existing internal config, with later values overriding earlier ones. The key question is **when a given setting goes live** — because once it does, passing it again has no effect.

<Card title="DailyCallOptions reference" icon="code" href="/reference/daily-js/types/daily-call-options">
  Full list of all call properties and their types
</Card>

## When settings go live

### 1. On bundle load

Settings that control how the call bundle is fetched and evaluated go live the moment the bundle loads. The bundle loads on the first call to `load()`, `preAuth()`, `startCamera()`, or `join()` — whichever comes first.

Examples: `dailyConfig.bundlePathOverride`, `dailyConfig.avoidEval`

Any value set on these before the bundle loads will be overridden by a later call, but once the bundle has loaded, further changes to these settings are ignored.

### 2. On device initialization

Settings related to device and media pipeline startup go live when devices are first initialized — either in `startCamera()`, or in `join()` if `startCamera()` was not called first.

Examples: `startAudioOff`, `startVideoOff`, `inputSettings`, `dailyConfig.alwaysIncludeMicInPermissionPrompt`, `dailyConfig.alwaysIncludeCamInPermissionPrompt`, `dailyConfig.enableIndependentDevicePermissionPrompts`

Values passed across multiple methods are merged and overridden up until that initialization point. After devices have started, these settings no longer apply.

### 3. On join (and for the duration of the call)

Settings related to the call session go live at `join()` and remain in effect for the duration. Most of these also have dedicated methods for updating them dynamically after joining.

Examples: `userName`, `proxyUrl`, `receiveSettings`, `sendSettings`, `dailyConfig.noAutoDefaultDeviceChange`, `dailyConfig.micAudioMode`

The last value passed before or at `join()` is what takes effect. If you pass `userName` to the constructor and again to `join()`, the `join()` value wins.

### 4. `url` and `token`

These must be set in the config by the time `preAuth()` or `join()` is called — either passed directly to those methods or set in an earlier call. They have an additional constraint: **if you call `preAuth()`, the `url` and `token` passed there must match what is used at `join()`.**

* If you pass a token to `preAuth()`, you don't need to pass it again to `join()` — but if you do, it must be the same token.
* If you don't pass a token to `preAuth()`, you cannot pass one to `join()`.
* Mismatching the url or token between `preAuth()` and `join()` will cause the join to fail.

## Recommendation: pass config once

Because settings go live at different points, spreading config across multiple method calls can produce subtle, hard-to-trace behavior. The simplest approach is to pass everything once.

For most apps, that means passing the full config to `preAuth()` or `join()`:

```javascript theme={null}
await call.preAuth({
  url: 'https://your-domain.daily.co/room-name',
  userName: 'Alice',
  startAudioOff: true,
  token: meetingToken,
});
await call.join();
```

If you use `startCamera()` for a pre-join preview, pass only what's needed to start the devices there and leave everything else for `join()`:

```javascript theme={null}
// Device setup only
await call.startCamera({
  inputSettings: {
    audio: { processor: { type: 'noise-cancellation' } },
  },
});

// Everything else at join time
await call.join({
  url: 'https://your-domain.daily.co/room-name',
  userName: 'Alice',
  token: meetingToken,
});
```

The constructor is appropriate for settings that are truly global to the instance — things like `subscribeToTracksAutomatically` or `dailyConfig.bundlePathOverride` — but avoid splitting call-specific options like `url`, `token`, or `userName` across multiple methods.
