***

title: on
slug: /reference/python/relay/call/on
description: Register an event listener on a call.
max-toc-depth: 3
---------------------

For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

[events-section]: /docs/server-sdks/reference/python/relay/call#events

[relayevent]: /docs/server-sdks/reference/python/relay/events

Register a listener for events on this call. The handler is called each time
an event of the specified type is received. Handlers can be regular functions
or async coroutines.

## **Parameters**

<ParamField path="event_type" type="str" required={true} toc={true}>
  The event type string to listen for (e.g., `"calling.call.state"`,
  `"calling.call.play"`). See the [Events section][events-section]
  on the Call page for class-level events, or individual method pages for
  method-specific events.
</ParamField>

<ParamField path="handler" type="Callable[[RelayEvent], Any]" required={true} toc={true}>
  Function or coroutine to invoke when the event fires. Receives a
  [`RelayEvent`][relayevent] instance.
</ParamField>

## **Returns**

`None`

## **Example**

```python {10,15,21}
from signalwire.relay import RelayClient

client = RelayClient(
    project="your-project-id",
    token="your-api-token",
    host="your-space.signalwire.com",
    contexts=["default"],
)

@client.on_call
async def handle_call(call):
    await call.answer()

    # Register a listener for play events
    call.on("calling.call.play", lambda event: print(f"Play state: {event.params.get('state')}"))

    # Register a listener for state changes
    def on_state_change(event):
        print(f"Call state changed: {event.params.get('call_state')}")

    call.on("calling.call.state", on_state_change)

    action = await call.play([{"type": "tts", "text": "Hello!"}])
    await action.wait()

client.run()
```