# Voice JavaScript SDK: Twilio.Device

The `Device` object is available when you've included the Voice JavaScript SDK in your application. It represents a softphone that communicates with Twilio to facilitate inbound and outbound audio connections.

For the full API reference, view the [autogenerated documentation on GitHub](https://twilio.github.io/twilio-voice.js/classes/Device.html).

> \[!NOTE]
>
> Throughout this page, you will see `device` with a lowercase "d" and `Device` with an uppercase "D".
>
> `Device` refers to the `Device` object provided by the SDK.
>
> `device` represents an **instance** of a `Device`, created with the `new` keyword:
>
> ```javascript
> const device = new Device(token);
> ```

## Table of Contents

* [Instantiate a Device](/docs/voice/sdks/javascript/twiliodevice#instantiate-a-device)
* [DeviceOptions](/docs/voice/sdks/javascript/twiliodevice#deviceoptions)
* [Methods](/docs/voice/sdks/javascript/twiliodevice#methods)
* [Events](/docs/voice/sdks/javascript/twiliodevice#events)
* [Accessors](/docs/voice/sdks/javascript/twiliodevice#accessors)
* [Static Methods](/docs/voice/sdks/javascript/twiliodevice#static-methods)
* [Static Properties](/docs/voice/sdks/javascript/twiliodevice#static-properties)
* [Static Accessors](/docs/voice/sdks/javascript/twiliodevice#static-accessors)

## Instantiate a Device

A new instance of a `Device` should be constructed by using the `new` keyword and passing an [Access Token](/docs/iam/access-tokens) as the first argument. The constructor also takes an optional second argument, `DeviceOptions`.

No signaling channel will be opened when instantiating a new `Device`. The signaling WebSocket will be opened when either `device.register()` or `device.connect()` are called.

> \[!WARNING]
>
> The maximum number of characters for the `identity` provided in the Access Token is 121. The `identity` may only contain alpha-numeric and underscore characters. Other characters, including spaces, or exceeding the maximum number of characters, will result in not being able to place or receive calls.

### Instantiate a Device without DeviceOptions

```javascript
const device = new Device(token);
```

The `DeviceOptions` parameter is **optional**. The `Device` instance's options can be updated after instantiation using the `device.updateOptions()` method.

### Instantiate a Device with DeviceOptions

Examples of using `DeviceOptions` to specify an [Edge location](/docs/voice/sdks/javascript/edges):

```javascript
// Instantiate the device with a specified edge location
const device = new Device(token, { edge: 'ashburn'});

// Instantiate the device with a specified edge and auto-fallback functionality
const device = new Device(token, { edge: ['ashburn', 'sydney'] });
```

To see all of the possible properties, see the [DeviceOptions section](/docs/voice/sdks/javascript/twiliodevice#deviceoptions) below.

## DeviceOptions

The `Device` instance can be configured using the `DeviceOptions` parameter in two ways: during instantiation with the `new` keyword or by calling `device.updateOptions()`.

```javascript
const deviceOptions = {
  edge: 'ashburn',
}

// pass the options object as the second argument in Device constructor
const device = new Device(token, deviceOptions);

// or

// use the updateOptions method after instantiating the device
const device = new Device(token);
device.updateOptions(deviceOptions);
```

`DeviceOptions` is a JavaScript object with the properties listed in the table below. All properties are optional.

| Options Property                                                                  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **allowIncomingWhileBusy** *Boolean* <br /><br /> default: `false`                | Whether the `Device` instance should raise the ['incoming' event](/docs/voice/sdks/javascript/twiliodevice#incoming-event) when a new call invite is received while already on an active call.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| **appName** *string*                                                              | A name for the application that is instantiating the `Device` instance. This is used to improve logging in [Insights](/docs/voice/voice-insights).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| **appVersion** *string*                                                           | A version for the application that is instantiating the `Device` instance. This is used to improve logging in [Insights](/docs/voice/voice-insights).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| **closeProtection** *Boolean or string* <br /><br /> default: `false`             | Setting this property to `true` will enable a dialog prompt with the text `"A call is currently in progress. Leaving or reloading the page will end the call."` when closing a page which has an active connection. Setting the property to a `string` will create a custom message prompt with that `string`. If custom text is not supported by the browser, Twilio will display the browser's default dialog.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| **codecPreferences** *string\[]* <br /><br /> default:`["pcmu", "opus"]`          | An array of codec names ordered from most-preferred to least-preferred. Opus and PCMU are the two codecs currently supported by Twilio Voice JS SDK. Opus can provide better quality for lower bandwidth, particularly noticeable in poor network conditions. Examples: `["opus", "pcmu"]`, `["pcmu"]`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| **disableAudioContextSounds** *Boolean*                                           | Whether [AudioContext](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext) sounds should be disabled. Useful for troubleshooting sound issues that may be caused by AudioContext-specific sounds. If set to `true`, the `Device` instance will fall back to [HTMLAudioElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLAudioElement) sounds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **dscp** *Boolean*                                                                | Whether to use googDscp in RTC constraints                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **edge** *string\[] or string* <br /><br /> default: `"roaming"`                  | The [Edge location](/docs/global-infrastructure/edge-locations) to connect to. If using an array of edges, sort by highest priority to lowest priority. The array will be used to provide auto [fallback functionality](/docs/voice/sdks/javascript/edges#edge-fallback). Check the `Device` instance's current edge using the `device.edge` read-only property. If the `Device` instance is offline, the edge will be `null`. See the [Edges documentation](/docs/voice/sdks/javascript/edges) for more details.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| **enableImprovedSignalingErrorPrecision** *Boolean* <br /><br /> default: `false` | When set to `true`, some errors that would have been described with a generic error code are now described with a more precise error code. Please see this [section](/docs/voice/sdks/javascript/twiliodevice#improved-signaling-errors) for more details.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **enumerateDevices** *function*                                                   | Pass a custom enumerateDevices function to override what Twilio uses when requesting a list of available media input and output devices.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| **forceAggressiveIceNomination** *Boolean* <br /><br /> default: `false`          | Experimental feature. Sets whether the `Device` instance should use [ICE Aggressive nomination](https://datatracker.ietf.org/doc/html/rfc5245#section-8.1.1.2). If your deployment is on devices with one network interface and your Round Trip Time (RTT) to Twilio's Servers is typically greater than 96 milliseconds, this feature may help reduce call connect time. As this is an experimental feature, we don't recommend enabling this until after testing it thoroughly in your deployment.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **getUserMedia** *function*                                                       | Pass a custom getUserMedia function to override what Twilio uses to create an input MediaStream.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| **logLevel** *number or string*                                                   | The Voice JavaScript SDK exposes a [loglevel](https://github.com/pimterry/loglevel)-based logger to allow for runtime logging configuration. Possible values include any of the following numbers: 0 = trace, 1 = debug, 2 = info, 3 = warn, 4 = error, 5 = silent Or any of the following strings: 'trace', 'debug', 'info', 'warn', 'error', 'silent' 'TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'SILENT' See the [loglevel docs](https://www.npmjs.com/package/loglevel) for more information.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| **maxAverageBitrate** *number*                                                    | Max average bitrate to better control how much bandwidth your VoIP application should use. See [RFC-7587 section 7.1](https://tools.ietf.org/html/draft-ietf-payload-rtp-opus-11#section-7.1). Only applicable when using `Opus` codec. By default, the Opus codec is set up with a transmission rate of around 32 kbps (40-50kbps on the wire). Max Average Bitrate can be set to as low as `6000` bps and as high as `510000` bps. Values outside this range are ignored and the default Opus operation mode is used. Lowering the max average bitrate impacts audio quality. The recommended bitrate for speech is between `8000` and `40000` bps. If you set `maxAverageBitrate` to `0`, the setting is not used.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| **maxCallSignalingTimeoutMs** *number* <br /><br /> default: `0`                  | The maximum duration in milliseconds the Twilio.Device will attempt to reconnect to the most-recently-used edge in the event of a signaling connectivity loss. After the provided time has passed during reconnection attempts, the Twilio.Device will then use edge fallback. **The default value of `0` means that signaling reconnection may not occur**, since a change of edge during a reconnection attempt will cause a Call to fail. Since the Twilio.Device will only attempt to reestablish connectivity for up to 30 seconds, the maximum value you would want to use here is `30000` milliseconds. Read more about edge fallback and signaling reconnection on the [Edge Locations page](/docs/voice/sdks/javascript/edges#edge-fallback-and-signaling-reconnection). **Note:** Setting this option to a value greater than zero means Twilio will not terminate the call until the timeout has expired. Please take this into consideration if your application contains webhooks that relies on [call status callbacks](/docs/voice/twiml#callstatus-values).                                                                                                                                                                                                                                                          |
| **MediaStream** *function*                                                        | Overrides the native [MediaStream](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream) API. This override is for redirection technologies like [Citrix HDX](https://www.citrix.com/solutions/vdi-and-daas/hdx/what-is-hdx.html). See [WebRTC API Overrides](/docs/voice/sdks/javascript/best-practices#webrtc-api-overrides) for an example.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| **RTCPeerConnection** *function*                                                  | Overrides the native RTCPeerConnection class. By default, the SDK will use the `unified-plan` SDP format if the browser supports it. Unexpected behavior may happen if the `RTCPeerConnection` parameter uses an SDP format that is different than what the SDK uses. For example, if the browser supports `unified-plan` and the `RTCPeerConnection` parameter uses `plan-b` by default, the SDK will use `unified-plan` which will cause conflicts with the usage of the `RTCPeerConnection`. In order to avoid this issue, you need to explicitly set the SDP format that you want the SDK to use with the `RTCPeerConnection` via [Device.ConnectOptions.rtcConfiguration](/docs/voice/sdks/javascript/twiliodevice#connectoptions) for outgoing calls. Or [Call.AcceptOptions.rtcConfiguration](/docs/voice/sdks/javascript/twiliocall#callacceptacceptoptions) for incoming calls. See the example below. Assuming the `RTCPeerConnection` you provided uses `plan-b` by default, the following code sets the SDP format to `unified-plan` instead.`// Outgoing calls const call = await device.connect({ rtcConfiguration: { sdpSemantics: 'unified-plan' } // Other options }); // Incoming calls device.on('incoming', call => { call.accept({ rtcConfiguration: { sdpSemantics: 'unified-plan' } // Other options }); });` |
| **sounds** *object*                                                               | A JavaScript object with key/value pairs of sound names (as the key) and URLs (as the value). See the [deviceOptions.sounds properties section below](/docs/voice/sdks/javascript/twiliodevice#deviceoptionssounds-properties-and-default-sounds) for all available properties (keys for the deviceOptions.sounds object) and the default sounds provided by the SDK. **Note:** The incoming ringtone will loop for at least two seconds and as long as the incoming call is pending. All other sounds will play once; DTMF tones will be cut short if they exceed one second, while outgoing and disconnect sounds will be cut short if they exceed three seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| **tokenRefreshMs** *number* <br /><br /> default: `10000`                         | The number of milliseconds before the AccessToken's expiry that the Twilio.Device will emit the `'tokenWillExpire'` event. The default is 10 seconds (10000 milliseconds).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |

**Example:**

Specify an [Edge location](/docs/global-infrastructure/edge-locations) using `DeviceOptions`

```javascript
// pass options object during device instantiation
const device = new Device(token, { edge: 'ashburn' });

// or

// pass options object using the updateOptions method
const device = new Device(token);
device.updateOptions({ edge: 'ashburn' });
```

**Example:**

Specify an [Edge location](/docs/global-infrastructure/edge-locations) and custom sounds

```javascript
const deviceOptions = {
  edge: 'ashburn',
  sounds: {
    incoming: 'http://example.com/incoming.mp3',
    outgoing: 'http://example.com/outgoing.mp3',
    dtmf8: 'http://example.com/8_button.mp3'
  }
}


// pass options object during device instantiation
const device = new Device(token, deviceOptions);

// or

// pass options object using the updateOptions method
const device = new Device(token);
device.updateOptions(deviceOptions);
```

### deviceOptions.sounds properties and default sounds

The available properties on the `deviceOptions.sounds` object are listed in the left column of the table below. In the right column, there are audio players to hear the default sounds provided by the Voice JavaScript SDK.

| deviceOptions.sounds property | Default sound                                                                                                                                  |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| incoming                      | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/incoming.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/incoming.mp3)     |
| outgoing                      | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/outgoing.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/outgoing.mp3)     |
| disconnect                    | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/disconnect.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/disconnect.mp3) |
| dtmf1                         | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-1.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-1.mp3)         |
| dtmf2                         | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-2.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-2.mp3)         |
| dtmf3                         | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-3.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-3.mp3)         |
| dtmf4                         | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-4.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-4.mp3)         |
| dtmf5                         | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-5.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-5.mp3)         |
| dtmf6                         | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-6.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-6.mp3)         |
| dtmf7                         | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-7.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-7.mp3)         |
| dtmf8                         | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-8.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-8.mp3)         |
| dtmf9                         | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-9.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-9.mp3)         |
| dtmf0                         | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-0.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-0.mp3)         |
| dtmfs (star)                  | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-star.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-star.mp3)   |
| dtmfh (hash)                  | [https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-hash.mp3](https://sdk.twilio.com/js/client/sounds/releases/1.0.0/dtmf-hash.mp3)   |

### Improved Signaling Errors

When `deviceOptions.enableImprovedSignalingErrorPrecision` is set to `true`, the following errors that would have been described with a generic error code are now described with a more precise error code. With this feature, the following errors now have their own error codes. Please see this [page](/docs/api/errors) for more details about each error.

**Device Error Changes**

```js
const device = new Device(token, {
  enableImprovedSignalingErrorPrecision: true,
});
device.on('error', (deviceError) => {
  // the following table describes how deviceError will change with this feature flag
});
```

| Device Error Name                                                | Flag Enabled | Flag Disabled |
| ---------------------------------------------------------------- | ------------ | ------------- |
| `GeneralErrors.ApplicationNotFoundError`                         | `31001`      | `53000`       |
| `GeneralErrors.ConnectionDeclinedError`                          | `31002`      | `53000`       |
| `GeneralErrors.ConnectionTimeoutError`                           | `31003`      | `53000`       |
| `MalformedRequestErrors.MissingParameterArrayError`              | `31101`      | `53000`       |
| `MalformedRequestErrors.AuthorizationTokenMissingError`          | `31102`      | `53000`       |
| `MalformedRequestErrors.MaxParameterLengthExceededError`         | `31103`      | `53000`       |
| `MalformedRequestErrors.InvalidBridgeTokenError`                 | `31104`      | `53000`       |
| `MalformedRequestErrors.InvalidClientNameError`                  | `31105`      | `53000`       |
| `MalformedRequestErrors.ReconnectParameterInvalidError`          | `31107`      | `53000`       |
| `SignatureValidationErrors.AccessTokenSignatureValidationFailed` | `31202`      | `53000`       |
| `AuthorizationErrors.NoValidAccountError`                        | `31203`      | `53000`       |
| `AuthorizationErrors.JWTTokenExpirationTooLongError`             | `31207`      | `53000`       |
| `ClientErrors.NotFound`                                          | `31404`      | `53000`       |
| `ClientErrors.TemporarilyUnavilable`                             | `31480`      | `53000`       |
| `ClientErrors.BusyHere`                                          | `31486`      | `53000`       |
| `SIPServerErrors.Decline`                                        | `31603`      | `53000`       |

**Call Error Changes**

```js
const device = new Device(token, {
  enableImprovedSignalingErrorPrecision: true,
});
const call = device.connect(...);
call.on('error', (callError) => {
  // the following table describes how callError will change with this feature flag
});
```

| Call Error Name                            | Flag Enabled | Flag Disabled |
| ------------------------------------------ | ------------ | ------------- |
| `GeneralErrors.ConnectionDeclinedError`    | `31002`      | `31005`       |
| `AuthorizationErrors.InvalidJWTTokenError` | `31204`      | `31005`       |
| `AuthorizationErrors.JWTTokenExpiredError` | `31205`      | `31005`       |

## Methods

This section contains descriptions of the methods available on a `Device` instance.

| [device.addListener()](/docs/voice/sdks/javascript/twiliodevice#deviceaddlistenereventname-listener) [device.connect()](/docs/voice/sdks/javascript/twiliodevice#deviceconnectconnectoptions) [device.destroy()](/docs/voice/sdks/javascript/twiliodevice#devicedestroy) [device.disconnectAll()](/docs/voice/sdks/javascript/twiliodevice#devicedisconnectall) [device.emit()](/docs/voice/sdks/javascript/twiliodevice#deviceemiteventname-args) [device.eventNames()](/docs/voice/sdks/javascript/twiliodevice#deviceeventnames) [device.getMaxListeners()](/docs/voice/sdks/javascript/twiliodevice#devicegetmaxlisteners) [device.listenerCount()](/docs/voice/sdks/javascript/twiliodevice#devicelistenercounteventname) | [device.listeners()](/docs/voice/sdks/javascript/twiliodevice#devicelistenerseventname) [device.off()](/docs/voice/sdks/javascript/twiliodevice#deviceoffeventname-listener) [device.on()](/docs/voice/sdks/javascript/twiliodevice#deviceoneventname-listener) [device.once()](/docs/voice/sdks/javascript/twiliodevice#deviceonceeventname-listener) [device.prependListener()](/docs/voice/sdks/javascript/twiliodevice#deviceprependlistenereventname-listener) [device.prependOnceListener()](/docs/voice/sdks/javascript/twiliodevice#deviceprependoncelistenereventname-listener) [device.rawListeners()](/docs/voice/sdks/javascript/twiliodevice#devicerawlistenerseventname) [device.register()](/docs/voice/sdks/javascript/twiliodevice#deviceregister) | [device.removeAllListeners()](/docs/voice/sdks/javascript/twiliodevice#deviceremovealllistenerseventnames) [device.removeListener()](/docs/voice/sdks/javascript/twiliodevice) [device.setMaxListeners()](/docs/voice/sdks/javascript/twiliodevice#devicesetmaxlistenersnumber) [device.unregister()](/docs/voice/sdks/javascript/twiliodevice#deviceunregister) [device.updateOptions()](/docs/voice/sdks/javascript/twiliodevice#deviceupdateoptionsoptions) [device.updateToken()](/docs/voice/sdks/javascript/twiliodevice#deviceupdatetokentoken) |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

### device.addListener(eventName, listener)

Add an event listener to the `Device` instance. This is an alias for `device.on()`.

See the [Events section](/docs/voice/sdks/javascript/twiliodevice#events) of this page to see the full list of events emitted by a `Device` instance.

| Parameter     | Data Type            | Description                                                                       |
| ------------- | -------------------- | --------------------------------------------------------------------------------- |
| **eventName** | *string* or *symbol* | The event emitted by the `Device` instance that will call the `listener` function |
| **listener**  | *function*           | The function that will be called when the specified event is emitted              |

**Example:**

If you want to know when your `Device` instance is ready to receive incoming calls, listen for the `'registered'` event.

```javascript
const device = new Device(token);

device.addListener('registered', device => {
  console.log('The device is ready to receive incoming calls.')
});
```

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_on_eventname_listener) for more information.

### device.connect(ConnectOptions)

Attempts a new connection to the [Twilio application](/docs/usage/api/applications) that you associated with the [Access Token](/docs/iam/access-tokens) used when instantiating the `Device` instance.

This method will return a Promise with a [Call object](/docs/voice/sdks/javascript/twiliocall). You should keep track of this `Call` object to monitor/modify the active call.

To end the call, you can use the `.disconnect()` method on the `Call` object or use the `device.disconnectAll()` method.

```javascript
const device = new Device(token);

let call = await device.connect({
  params: {
    To: '+15551234567'
  }
});
```

#### ConnectOptions

`device.connect()` takes an optional ConnectOptions argument. The ConnectOptions object is a JavaScript object with optional `params`, `connectToken`, `rtcConfiguration`, and `rtcConstraints` properties.

**Example:**

```javascript
const device = new Device(token);

let call = await device.connect({
  params: {
    To: "+15551234567"
    agent: "Smith",
    location: "Matrix"
  },
  rtcConstraints: {
    audio: true
  },
  rtcConfiguration: {
    iceServers: [{
      urls: "stunserver.example.com",
      username: "username@twilio.com",
      credential: "webrtcCredential"
    }]
  }
})
```

##### connectToken

The [call.connectToken](/docs/voice/sdks/javascript/twiliocall#callconnecttoken) allows for the manual reconnection to an existing call. This is applicable for calls that were previously received (incoming) or created (outgoing) from a `Device` instance. When a call is manually reconnected using the [call.connectToken](/docs/voice/sdks/javascript/twiliocall#callconnecttoken), its [call.direction](/docs/voice/sdks/javascript/twiliocall#calldirection) property is automatically set to `OUTGOING`.

> \[!WARNING]
>
> Only unanswered incoming calls can be manually reconnected at this time. Invoking this method to an already answered call may introduce unexpected behavior.

See [device's incoming event](/docs/voice/sdks/javascript/twiliodevice#incoming-event) for an example.

##### params

A JavaScript object containing key/value pairs to be sent to the Twilio application. These `params` will be passed to your application as `GET` or `POST` parameters.

> \[!WARNING]
>
> The total length of all `params` passed to `device.connect()` must not exceed 800 bytes. See [How to Share Information Between Your Applications](/docs/voice/how-share-information-between-your-applications) for more information.

> \[!WARNING]
>
> Your application should not assume that these parameters are safe since any user can call this function with whatever parameters they want.

For example, the following code will pass the `params` key/value pairs `agent=Smith` and `location=Matrix` to the [Twilio application](/docs/usage/api/applications) associated with this `Device` instance's [Access Token](/docs/iam/access-tokens).

```javascript
const device = new Device(token);

let call = await device.connect({
  params: {
    agent: "Smith",
    location: "Matrix"
  }
});
```

##### rtcConfiguration

An [RTCConfiguration](https://developer.mozilla.org/en-US/docs/Web/API/RTCConfiguration) dictionary to pass to the [RTCPeerConnection](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection) constructor. This allows you to configure the WebRTC connection between your local machine and the remote peer.

##### rtcConstraints

A [MediaStreamConstraints](https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints) dictionary to pass to [getUserMedia](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia) when making or accepting a Call. This allows you to configure the behavior of tracks returned in the [MediaStream](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream).

Each browser implements a different set of `MediaTrackConstraints`, so consult your browser's implementation of `getUserMedia` for more information.

### device.destroy()

Destroys the `Device` instance.

This method will disconnect all calls, unbind audio devices, destroy the stream (which causes the `unregistered` event to be emitted), and then the `Device` instance will emit the `destroyed` event. Then, all event listeners attached to the `Device` instance are cleaned up.

```javascript
const device = new Device(token);

device.destroy();
```

### device.disconnectAll()

Disconnect all `Calls` associated with the `Device` instance.

**Example:**

A user clicks on a **Hang Up** button in the browser, which calls `device.disconnectAll()` to end the current Call.

```javascript
const device = new Device(token);

// A click on a 'Hang Up' button calls this method
const hangupCall = () => {
 device.disconnectAll();
 console.log('The call has ended.');
}
```

### device.emit(eventName, ...args)

Calls each of the event listeners registered for the event named `eventName`. The listeners will be called in the order they were registered. Any arguments passed in after the `eventName` will be passed to the event listeners.

| Parameter     | Data Type            | Description                                                                        |
| ------------- | -------------------- | ---------------------------------------------------------------------------------- |
| **eventName** | *string* or *symbol* | The event emitted by the `Device` instance that will call the `listener` function  |
| **args**      | *any*                | The arguments that will be passed to the event listener(s) for the specified event |

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_emit_eventname_args) for more information.

### device.eventNames()

Returns an array of event names for which the `Device` instance has registered event listeners.

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_eventnames) for more information.

### device.getMaxListeners()

Returns the current maximum number of event listeners for the `Device` instance.

By default, the maximum number of listeners is 10, and is set by the static `Device.defaultMaxListeners` property or the dynamic `device.setMaxListeners(number)` method.

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_getmaxlisteners) for more information.

### device.listenerCount(eventName)

Returns the number of listeners listening to the event named `eventName` on the `Device` instance.

| Parameter     | Data Type            | Description                                                             |
| ------------- | -------------------- | ----------------------------------------------------------------------- |
| **eventName** | *string* or *symbol* | The name of the event for which you want to retrieve the listener count |

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_listenercount_eventname) for more information.

### device.listeners(eventName)

Returns an array of the listeners registered on the `Device` instance for the event named `eventName`.

| Parameter     | Data Type            | Description                                                        |
| ------------- | -------------------- | ------------------------------------------------------------------ |
| **eventName** | *string* or *symbol* | The name of the event for which you want to retrieve the listeners |

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_listeners_eventname) for more information.

### device.off(eventName, listener)

Removes the `listener` for the event named `eventName`. This is an alias for `device.removeListener()`.

```javascript
const device = new Device(token);

const handleSuccessfulRegistration = () => {
  console.log('The device is ready to receive incoming calls.')
}

device.on('registered', handleSuccessfulRegistration);

device.off('registered', handleSuccessfulRegistration);
```

See the [Node.js Event Docs](https://nodejs.org/api/events.html#events_emitter_removelistener_eventname_listener) for more information.

### device.on(eventName, listener)

Add an event listener to the `Device` instance. This is analogous to the `Device.addListener()` method.

See the [Events section](/docs/voice/sdks/javascript/twiliodevice#events) of this page to see the full list of events emitted by the `Device` instance.

| Parameter     | Data Type            | Description                                                                       |
| ------------- | -------------------- | --------------------------------------------------------------------------------- |
| **eventName** | *string* or *symbol* | The event emitted by the `Device` instance that will call the `listener` function |
| **listener**  | *function*           | The function that will be called when the specified event is emitted              |

**Example:**

If you want to know when your `Device` instance is ready to receive incoming calls, listen for the `'registered'` event.

```javascript
const device = new Device(token);

device.on('registered', device => {
  console.log('The device is ready to receive incoming calls.')
};
```

### device.once(eventName, listener)

Adds a one-time listener to the `Device` instance for the event named `eventName`.

| Parameter     | Data Type            | Description                                                                                                                            |
| ------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| **eventName** | *string* or *symbol* | The event emitted by the `Device` instance that will call the `listener` function                                                      |
| **listener**  | *function*           | The function that will be called when the specified event is emitted. The listener function will be removed and then invoked one time. |

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_once_eventname_listener) for more information.

### device.prependListener(eventName, listener)

Adds a listener function to the beginning of the listeners array for the event named `eventName`.

Calling this multiple times with the same `eventName` and `listener` arguments will add the listener again, meaning that the listener will be called multiple times when the specified event is emitted.

| Parameter     | Data Type            | Description                                                                                                                                                       |
| ------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **eventName** | *string* or *symbol* | The event emitted by the `Device` instance that will call the `listener` function                                                                                 |
| **listener**  | *function*           | The function that will be called when the specified event is emitted. The listener will be added to the beginning of the listeners array for the specified event. |

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_prependlistener_eventname_listener) for more information.

### device.prependOnceListener(eventName, listener)

Adds a one-time listener to the beginning of the listener array for the specified event.

| Parameter     | Data Type            | Description                                                                                                                                                |
| ------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **eventName** | *string* or *symbol* | The event emitted by the `Device` instance that will call the `listener` function                                                                          |
| **listener**  | *function*           | The function that will be called the next time the specified event is emitted. The listener will be removed from the listeners array before being invoked. |

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_prependoncelistener_eventname_listener) for more information.

### device.rawListeners(eventName)

Returns an array of the listeners associated with the event named `eventName`. This includes any wrappers.

| Parameter     | Data Type            | Description                                                                          |
| ------------- | -------------------- | ------------------------------------------------------------------------------------ |
| **eventName** | *string* or *symbol* | the event for which you want to retrieve the listeners array (includes any wrappers) |

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_rawlisteners_eventname) for more information.

### device.register()

Register the `Device` instance with Twilio, allowing it to receive incoming calls. This will open a signaling WebSocket, so the browser tab may show the 'recording' icon.

It's not necessary to call `device.register()` in order to make outgoing calls.

```javascript
const device = new Device(token);

const handleSuccessfulRegistration = () => {
  console.log('The device is ready to receive incoming calls.')
}

device.on('registered', handleSuccessfulRegistration);

device.register();
```

> \[!NOTE]
>
> Some browsers will throw errors on pages that play audio that isn't initiated by a user gesture. Twilio recommends calling `device.register()` in response to a user gesture, such as a click. One popular and intuitive way to implement this is to add a button that will call `device.register()`.

**Example:**

A user clicks on a **Start Device** button that will fire `device.register()` to enable the `Device` instance to receive incoming calls. Once registered, the `Device` instance will emit the `'registered'` event.

```javascript
const device = new Device(token);

// Listen for the 'registered' event
device.on('registered', () => {
  console.log('The device is ready to receive calls.')
})

// A 'Start Device' button click calls this method
const startDevice = () => {
  console.log('Registering the device to receive calls.');
  device.register();
}
```

### device.removeAllListeners(eventNames?)

Removes all listeners on the `Device` instance if no argument is passed. **This is not recommended.**

The optional `eventNames` parameter is an array of event name strings.

If `eventNames` argument is passed, only those listeners will be removed. This is only recommended for events and event listeners that you have added, not those created by the SDK.

```javascript
const device = new Device(token);

// removes all event listeners
device.removeListeners();

// removes the listeners for the "event1" and "event2" events
device.removeListeners(["event1", "event2"]);
```

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_removealllisteners_eventname) for more information.

### device.removeListener(eventName, listener)

Removes the listener specified by the `eventName` and `listener` arguments. This is analogous to `device.off()`.

```javascript
const device = new Device(token);

const handleSuccessfulRegistration = () => {
  console.log('The device is ready to receive incoming calls.')
}

device.on('registered', handleSuccessfulRegistration);

device.removeListener('registered', handleSuccessfulRegistration);
```

See the [Node.js Events Docs](https://nodejs.org/api/events.html#events_emitter_removelistener_eventname_listener) for more information.

### device.setMaxListeners(number)

Set the maximum number of event listeners allowed on this `Device` instance. The default maximum is 10.

Calling this method will change only the maximum allowed on this specific **instance** of a `Device`. If you want to change the maximum number of listeners allowed for **all** `Device` instances, consider setting the static `Device.defaultMaxListeners` property on the global `Device` object provided by the SDK.

**Note:** `device.setMaxListeners(number)` will have precedence over `Device.defaultMaxListeners`.

```javascript
const device = new Device(token);

device.setMaxListeners(20);
```

### device.unregister()

Unregister the `Device` instance with Twilio. This will prevent the `Device` instance from receiving incoming calls.

The `Device` instance will emit the 'unregistered' event when successfully unregistered with Twilio.

```javascript
const device = new Device(token);

// Listen for the 'unregistered' event
device.on('unregistered', () => {
  console.log('The device is no longer able to receive calls.')
})

const unregisterDevice = () => {
  console.log('Unregistering the device.');
  device.unregister();
}

```

### device.updateOptions(options)

Set the options used within the `Device` instance.

See the [DeviceOptions section](/docs/voice/sdks/javascript/twiliodevice#deviceoptions) above for the full list of available options.

**Example:**

Specify an [Edge location](/docs/voice/sdks/javascript/edges) and custom sounds

```javascript
const options = {
  edge: 'ashburn',
  sounds: {
    incoming: '',
    outgoing: '',
    dtmf8: ''
  }
}

const device = new Device(token);
device.updateOptions(options);
```

### device.updateToken(token)

Update the token used by this `Device` instance to connect to Twilio.

If the token expires, the `Device` instance will not be able to receive or make calls. It will also prevent statistics from being sent to [Voice Insights](/docs/voice/voice-insights).

It is recommended to call this API after `device.tokenWillExpire` event is emitted, and before or after a call to prevent a potential \~1s audio loss during the update process.

In the future, as Twilio explores signaling reconnection support, keeping this token updated will be important for automatically restoring connection to a `Call` or re-registering the `Device` instance.

**Example:**

```javascript
// time to live for the token, in milliseconds
const timeToLive = 600000; // 10 minutes
const refreshBuffer = 30000; // 30 seconds

const token = await getTokenViaAjax({ timeToLive });
const device = new Device(token);

setInterval(async () => {
  const newToken = await getTokenViaAjax({ timeToLive });
  device.updateToken(token);
}, timeToLive - refreshBuffer);
```

## Events

| [destroyed Event](/docs/voice/sdks/javascript/twiliodevice#destroyed-event) [error Event](/docs/voice/sdks/javascript/twiliodevice#error-event) [incoming Event](/docs/voice/sdks/javascript/twiliodevice#incoming-event) [registered Event](/docs/voice/sdks/javascript/twiliodevice#registered-event) | [registering Event](/docs/voice/sdks/javascript/twiliodevice#registering-event) [tokenWillExpire Event](/docs/voice/sdks/javascript/twiliodevice#tokenwillexpire-event) [unregistered Event](/docs/voice/sdks/javascript/twiliodevice#unregistered-event) |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

### destroyed Event

Emitted when the `Device` has been destroyed.

Listen for the `'destroyed'` event.

```javascript
const device = new Device(token);

device.on('destroyed', () => {
    // Do something
});
```

### error Event

Emitted when the `Device` instance receives an error.

The event listener will receive a `TwilioError` and when applicable, a reference to the `Call` object that was active when the error occurred. See the TwilioError section below for more information on the `TwilioError` object.

Listen for the `'error'` event.

```javascript
const device = new Device(token);

device.on('error', (twilioError, call) => {
 console.log('An error has occurred: ', twilioError);
});
```

**TwilioError**

The format of the `TwilioError` returned from the error event is a JavaScript object with the following properties:

| Property                              | Description                                                     |
| ------------------------------------- | --------------------------------------------------------------- |
| **causes** *string\[]*                | A list of possible causes for the error                         |
| **code** *number*                     | The numerical code associated with this error                   |
| **description** *string*              | A description of what the error means                           |
| **explanation** *string*              | An explanation of when the error may be observed                |
| **message** *string*                  | Any further information discovered and passed along at runtime. |
| **name** *string*                     | The name of this error                                          |
| **originalError** (optional) *string* | The original error received from the external system, if any    |
| **solutions** *string\[]*             | A list of potential solutions for the error                     |

See a list of common errors on the [Voice SDK Error Codes Page](/docs/voice/sdks/error-codes).

### incoming Event

Emitted when an incoming `Call` is received. An event listener will receive the `Call` object representing the incoming `Call`. You can interact with the call object using its public APIs, or you can forward it to a different `Device` using [device.connect()](/docs/voice/sdks/javascript/twiliodevice#deviceconnectconnectoptions) and [call.connectToken](/docs/voice/sdks/javascript/twiliocall#callconnecttoken), enabling your application to receive multiple incoming calls for the same identity.

**Important:** When forwarding a call, the token for the target `Device` instance needs to have the same identity as the token used in the `Device` that originally received the call. The target device instance must also have the same edge as the device that originally received the call.

```javascript
const receiverDevice = new Device(token, options);
await receiverDevice.register();

receiverDevice.on('incoming', (call) => {
  // Forward this call to a new Device instance using the call.connectToken string.
  forwardCall(call.connectToken, receiverDevice.edge);
});

// The forwardCall function may look something like the following.
async function forwardCall(connectToken, edge) {
  // For each incoming call, create a new Device object. This ensures individual
  // interaction with each call, without affecting other calls.
  // IMPORTANT: The token for this new device needs to have the same identity
  // as the token used in the receiverDevice.
  // The device must also be connected to the same edge as the receiverDevice.
  const options = { ..., edge };
  const device = new Device(token, options);
  const call = await device.connect({ connectToken });

  // Destroy the `Device` after the call is completed
  call.on('disconnect', () => device.destroy());
}
```

### registered Event

Emitted when the `Device` instance is registered and able to receive incoming calls.

Listen for the `'registered'` event.

```javascript
const device = new Device(token);

device.on('registered', () => {
    // Do something
});
```

### registering Event

Emitted when the `Device` instance is registering with Twilio to receive incoming calls.

Listen for the `'registering'` event.

```javascript
const device = new Device(token);

device.on('registering', () => {
    // Do something
});
```

### tokenWillExpire Event

Emitted when the `Device` instance's AccessToken is about to expire.

Use the `refreshTokenMs` property on the [DeviceOptions object](/docs/voice/sdks/javascript/twiliodevice#deviceoptions) to set a custom warning time. The default is 10 seconds (10000 milliseconds) prior to the AccessToken expiring.

Listen for the `'tokenWillExpire`' event.

You can use this event along with `device.updateToken()` to automatically retrieve a new AccessToken and update the AccessToken on the Device instance, as shown in the example below:

```javascript
device.on('tokenWillExpire', () => {
  const token = getNewTokenViaAjax();
  device.updateToken(token);
});
```

### unregistered Event

Emitted when the `Device` instance has unregistered with Twilio.

Listen for the `'unregistered'` event.

```javascript
const device = new Device(token);

device.on('unregistered', () =>
    // Do something
});
```

## Accessors

| [device.audio](/docs/voice/sdks/javascript/twiliodevice#deviceaudio) [device.calls](/docs/voice/sdks/javascript/twiliodevice#devicecalls) [device.edge](/docs/voice/sdks/javascript/twiliodevice#deviceedge) [device.home](/docs/voice/sdks/javascript/twiliodevice#devicehome) | [device.identity](/docs/voice/sdks/javascript/twiliodevice#deviceidentity) [device.isBusy](/docs/voice/sdks/javascript/twiliodevice#deviceisbusy) [device.state](/docs/voice/sdks/javascript/twiliodevice#devicestate) [device.token](/docs/voice/sdks/javascript/twiliodevice#devicetoken) |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

### device.audio

Return the [`AudioHelper`](https://twilio.github.io/twilio-voice.js/classes/AudioHelper.html) object used by the `Device` instance. See the [device.audio docs](/docs/voice/sdks/javascript/twiliodevice/device-audio) for more information.

### device.calls

Returns an array of `Call`s that this `Device` instance is maintaining.

Modifying one of these calls will have the same affect as modifying the same Call as it was returned by `device.on('incoming')` or `device.connect()`.

```javascript
const device = new Device(token);

// make an ougoing call
device.connect({ params: { To: "+15551234567" } });

console.log(device.calls);

// Prints:
// []
```

### device.edge

Returns the [Edge](/docs/voice/sdks/javascript/edges) value the `Device` instance is currently connected to. The value will be null when the `Device` instance is offline.

```javascript
const device = new Device(token);

device.on("registered", () => {
  console.log(device.edge);
});

device.register();

// Prints:
// ashburn
```

### device.home

Returns the home Twilio Region the `Device` instance is connected to as a string. The value will be `null` when the `Device` instance is offline.

```javascript
const device = new Device(token);

console.log(device.home);

// The default region for the JavaScript SDK is US-1

// Prints:
// 'us1'

```

### device.identity

Returns the `identity` string that is associated with the `Device` instance's current [AccessToken](/docs/iam/access-tokens).

This accessor is only populated when the `Device` instance has successfully registered with Twilio.

### device.isBusy

Returns a Boolean for whether the `Device` instance is currently on an active `Call`

```javascript
const device = new Device(token);

console.log(device.isBusy);

// Prints:
// false



// make an outgoing call
device.connect({ params: { To: "+15551234567" });

console.log(device.isBusy);

// Prints:
// true
```

### device.state

Returns the state of the `Device` instance

```javascript
const device = new Device(token);

console.log(device.state);

// Prints:
// unregistered
```

The possible `Device` instance states are:

* `unregistered` - The `Device` instance is not registered with Twilio and cannot accept incoming calls
* `registering` - The `Device` instance is registering with Twilio to accept incoming calls
* `registered` - The `Device` instance is registered with Twilio and can accept incoming calls
* `destroyed` - The `Device` instance has been destroyed and will not be able to make or receive new calls

Use event listeners on the `Device` instance to give the user feedback when the `Device` instance's state changes. See the [Best Practices Page](/docs/voice/sdks/javascript/best-practices#give-users-feedback-when-device-state-changes) for more information.

### device.token

Returns the token used by this `Device` instance

```javascript
const device = new Device(token);

console.log(device.token);

// Prints:
// eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp....
```

You can use the [JWT debugger](https://jwt.io/#debugger-io) to decode and inspect the token.

## Static Methods

Static methods should be called on the `Device` global object provided by the SDK.

### Device.runPreflight(token, options?)

Returns a `PreflightTest` object representing a test call to Twilio which provides information to help troubleshoot call related issues.

**Example:**

```javascript
const preflightTest = Device.runPreflight(token, options);
```

A `Twilio.PreflightTest` object represents a test call to Twilio which provides information to help troubleshoot call related issues. You never instantiate it directly, but it's returned when you call `Device.runPreflight(token, options)`.

See the [PreflightTest Page](/docs/voice/sdks/javascript/twiliopreflighttest) for more information.

## Static Properties

Static properties are those properties that only exist on the global `Device` object.

### Device.defaultMaxListeners

Use this to change the default maximum number of event listeners permitted on **all instances** of a `Device`.

```javascript
Device.defaultMaxListeners = 20;
```

If you need to change the maximum number of event listeners on a specific `Device` instance, call the `device.setMaxListeners(number)` method on that instance.

**Note:** `device.setMaxListeners(number)` will have precedence over `Device.defaultMaxListeners`.

## Static Accessors

Static accessors should be called on the `Device` global provided by the SDK.

### Device.isSupported

Returns a Boolean for whether or not this SDK is supported by the current browser

```javascript
console.log(Device.isSupported);

// Prints:
// true

```

### Device.packageName

Returns the package name of the SDK

```javascript
console.log(Device.packageName);

// Prints:
// @twilio/voice-sdk

```

### Device.version

Returns the current SDK version

```javascript
console.log(Device.version);

// Prints:
// 2.0.0
```
