# Events

> Device and call events in the Edesy browser calling SDK - ready, error, incoming, ringing, answered, ended, failed, mute, hold and dtmf.

Source: https://edesy.in/docs/webrtc/sdk/events

The Edesy SDK emits events on two objects. The `Device` from `connect()` reports registration and incoming calls: `ready`, `unregistered`, `error` and `incoming`. Each `Call` reports its progress and controls: `ringing`, `answered`, `ended`, `failed`, `mute`, `hold` and `dtmf`. Subscribe with `.on(event, callback)`, which returns the object so calls can be chained.

## Device events

| Event | Fires when | Callback argument |
|---|---|---|
| `ready` | The device is registered. A handler attached after `connect()` resolves runs straight away | none |
| `unregistered` | The registration ended | none |
| `error` | Registration failed or the connection reported an error | error details |
| `incoming` | A call is sent to this device | `Call` |

## Call events

| Event | Fires when | Callback argument |
|---|---|---|
| `ringing` | The far end is ringing | none |
| `answered` | The call is answered | none |
| `ended` | The call ends after it was set up | end details |
| `failed` | The call could not be set up | failure details |
| `mute` | Mute changes after `toggleMute()` | mute state |
| `hold` | Hold changes after `toggleHold()` | hold state |
| `dtmf` | A DTMF digit is sent or received on the call | digit details |

## Example: a call status line

```js
const call = device
  .call("919876543210")
  .on("ringing", () => setStatus("Ringing..."))
  .on("answered", () => { setStatus("In call"); startTimer(); })
  .on("ended", () => { setStatus("Call ended"); stopTimer(); })
  .on("failed", () => setStatus("Call failed"))
  .on("mute", (muted) => setMuteIcon(muted))
  .on("hold", (held) => setHoldIcon(held));
```

## Event order on a normal call

1. `ringing` when the phone starts to ring.
2. `answered` when the person picks up.
3. `ended` when either side hangs up.

A call that never connects (busy, invalid number, network error) fires `failed` instead of `ended`.

## FAQ

### Should I listen for both `ended` and `failed`?

Yes. A call ends with exactly one of them, so reset your UI in both handlers.

### Can I add more than one handler for the same event?

Yes. Each `.on()` adds a handler, and they run in the order you added them.

### What if my handler throws?

The SDK catches errors thrown inside handlers so one bad handler does not stop the others.

### How do I detect a lost connection?

Listen for `error` and `unregistered` on the device, then mint a new token and call `connect()` again.

### Is there an event for the call duration?

No. Start a timer on `answered` and stop it on `ended`. Call history in the portal shows durations.

### Do events fire for incoming calls too?

Yes. The `Call` object passed to `incoming` emits the same call events.
