Skip to content

signalwire.relay

signalwire.relay

SignalWire RELAY client — real-time call control over WebSocket.

CALL_STATE_CREATED = 'created' module-attribute

CALL_STATE_RINGING = 'ringing' module-attribute

CALL_STATE_ANSWERED = 'answered' module-attribute

CALL_STATE_ENDING = 'ending' module-attribute

CALL_STATE_ENDED = 'ended' module-attribute

CONNECT_STATE_CONNECTING = 'connecting' module-attribute

CONNECT_STATE_CONNECTED = 'connected' module-attribute

CONNECT_STATE_DISCONNECTED = 'disconnected' module-attribute

CONNECT_STATE_FAILED = 'failed' module-attribute

EVENT_CALL_STATE = 'calling.call.state' module-attribute

EVENT_CALL_RECEIVE = 'calling.call.receive' module-attribute

EVENT_CALL_PLAY = 'calling.call.play' module-attribute

EVENT_CALL_RECORD = 'calling.call.record' module-attribute

EVENT_CALL_COLLECT = 'calling.call.collect' module-attribute

EVENT_CALL_CONNECT = 'calling.call.connect' module-attribute

EVENT_CALL_DETECT = 'calling.call.detect' module-attribute

EVENT_CALL_FAX = 'calling.call.fax' module-attribute

EVENT_CALL_TAP = 'calling.call.tap' module-attribute

EVENT_CALL_STREAM = 'calling.call.stream' module-attribute

EVENT_CALL_SEND_DIGITS = 'calling.call.send_digits' module-attribute

EVENT_CALL_DIAL = 'calling.call.dial' module-attribute

EVENT_CALL_REFER = 'calling.call.refer' module-attribute

EVENT_CALL_DENOISE = 'calling.call.denoise' module-attribute

EVENT_CALL_PAY = 'calling.call.pay' module-attribute

EVENT_CALL_QUEUE = 'calling.call.queue' module-attribute

EVENT_CALL_ECHO = 'calling.call.echo' module-attribute

EVENT_CALL_TRANSCRIBE = 'calling.call.transcribe' module-attribute

EVENT_CONFERENCE = 'calling.conference' module-attribute

EVENT_CALLING_ERROR = 'calling.error' module-attribute

EVENT_MESSAGING_RECEIVE = 'messaging.receive' module-attribute

EVENT_MESSAGING_STATE = 'messaging.state' module-attribute

MESSAGE_STATE_QUEUED = 'queued' module-attribute

MESSAGE_STATE_INITIATED = 'initiated' module-attribute

MESSAGE_STATE_SENT = 'sent' module-attribute

MESSAGE_STATE_DELIVERED = 'delivered' module-attribute

MESSAGE_STATE_UNDELIVERED = 'undelivered' module-attribute

MESSAGE_STATE_FAILED = 'failed' module-attribute

MESSAGE_STATE_RECEIVED = 'received' module-attribute

__all__ = ['RelayClient', 'RelayError', 'Call', 'Action', 'PlayAction', 'RecordAction', 'DetectAction', 'CollectAction', 'StandaloneCollectAction', 'FaxAction', 'TapAction', 'StreamAction', 'PayAction', 'TranscribeAction', 'AIAction', 'Message', 'RelayEvent', 'CallStateEvent', 'CallReceiveEvent', 'PlayEvent', 'RecordEvent', 'CollectEvent', 'ConnectEvent', 'DetectEvent', 'FaxEvent', 'TapEvent', 'StreamEvent', 'SendDigitsEvent', 'DialEvent', 'ReferEvent', 'DenoiseEvent', 'PayEvent', 'QueueEvent', 'EchoEvent', 'TranscribeEvent', 'HoldEvent', 'ConferenceEvent', 'CallingErrorEvent', 'MessageReceiveEvent', 'MessageStateEvent', 'parse_event', 'CALL_STATE_CREATED', 'CALL_STATE_RINGING', 'CALL_STATE_ANSWERED', 'CALL_STATE_ENDING', 'CALL_STATE_ENDED', 'CONNECT_STATE_CONNECTING', 'CONNECT_STATE_CONNECTED', 'CONNECT_STATE_DISCONNECTED', 'CONNECT_STATE_FAILED', 'EVENT_CALL_STATE', 'EVENT_CALL_RECEIVE', 'EVENT_CALL_PLAY', 'EVENT_CALL_RECORD', 'EVENT_CALL_COLLECT', 'EVENT_CALL_CONNECT', 'EVENT_CALL_DETECT', 'EVENT_CALL_FAX', 'EVENT_CALL_TAP', 'EVENT_CALL_STREAM', 'EVENT_CALL_SEND_DIGITS', 'EVENT_CALL_DIAL', 'EVENT_CALL_REFER', 'EVENT_CALL_DENOISE', 'EVENT_CALL_PAY', 'EVENT_CALL_QUEUE', 'EVENT_CALL_ECHO', 'EVENT_CALL_TRANSCRIBE', 'EVENT_CONFERENCE', 'EVENT_CALLING_ERROR', 'EVENT_MESSAGING_RECEIVE', 'EVENT_MESSAGING_STATE', 'MESSAGE_STATE_QUEUED', 'MESSAGE_STATE_INITIATED', 'MESSAGE_STATE_SENT', 'MESSAGE_STATE_DELIVERED', 'MESSAGE_STATE_UNDELIVERED', 'MESSAGE_STATE_FAILED', 'MESSAGE_STATE_RECEIVED'] module-attribute

RelayClient

Manages a WebSocket connection to SignalWire RELAY.

Usage::

client = RelayClient(project="...", token="...", contexts=["default"])

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

client.run()

project = project or os.environ.get('SIGNALWIRE_PROJECT_ID', '') instance-attribute

token = token or os.environ.get('SIGNALWIRE_API_TOKEN', '') instance-attribute

jwt_token = jwt_token or os.environ.get('SIGNALWIRE_JWT_TOKEN', '') instance-attribute

host = host or os.environ.get('SIGNALWIRE_SPACE', DEFAULT_RELAY_HOST) instance-attribute

contexts = contexts or [] instance-attribute

relay_protocol property

Server-assigned protocol string from the connect response.

__init__(project=None, token=None, jwt_token=None, host=None, contexts=None, max_active_calls=None)

__del__()

__aenter__() async

__aexit__(*exc) async

on_call(handler)

Register the inbound call handler (decorator).

on_message(handler)

Register the inbound message handler (decorator).

connect() async

Connect to RELAY and authenticate.

disconnect() async

Cleanly close the connection.

execute(method, params) async

Send a JSON-RPC request and await the response.

For calling methods, method is the full name (e.g. "calling.answer", "calling.play") with node_id and call_id in params.

If the connection is not ready, the request is queued and sent after re-authentication completes.

dial(devices, *, tag=None, max_duration=None, dial_timeout=None) async

Initiate an outbound call using dial. Returns a Call object.

The calling.dial RPC response only contains {"code": "200", "message": "Dialing"} — no call_id. The real call_id and node_id arrive via calling.call.dial events matched by tag. This method waits for that event so the returned Call always has valid identifiers.

Parameters:

Name Type Description Default
devices list[list[dict[str, Any]]]

Array of device lists (serial/parallel dial).

required
tag str | None

Client-provided tag for event correlation. Auto-generated if not supplied.

None
max_duration int | None

Optional max call duration in minutes.

None
dial_timeout float | None

How long (seconds) to wait for the dial to complete before raising TimeoutError. Defaults to 120s.

None

send_message(*, to_number, from_number, context=None, body=None, media=None, tags=None, region=None, on_completed=None) async

Send an outbound SMS/MMS message.

At least one of body or media must be provided.

Returns a Message object that tracks state changes. Use await message.wait() to block until delivery confirmation (or failure).

Parameters:

Name Type Description Default
to_number str

Destination phone number in E.164 format.

required
from_number str

Sender phone number in E.164 format.

required
context str | None

Context for receiving state events. Defaults to the relay protocol.

None
body str | None

Text body of the message.

None
media list[str] | None

List of media URLs for MMS.

None
tags list[str] | None

Optional tags for the message.

None
region str | None

Optional origination region.

None
on_completed Callable[[RelayEvent], Any] | None

Optional callback fired when a terminal state (delivered/undelivered/failed) is reached.

None

receive(contexts) async

Subscribe to additional contexts for inbound events.

Sends signalwire.receive on the assigned protocol to start receiving inbound calls on the given contexts. Can be called after connect() to dynamically add contexts without reconnecting.

unreceive(contexts) async

Unsubscribe from contexts for inbound events.

Sends signalwire.unreceive to stop receiving inbound calls on the given contexts.

run()

Blocking entry point — runs the event loop until interrupted.

RelayError

Bases: Exception

Error returned by the RELAY server.

code = code instance-attribute

message = message instance-attribute

__init__(code, message)

Call

Represents a live RELAY call.

Created by RelayClient on inbound calling.call.receive events or outbound dial/begin responses.

call_id = call_id instance-attribute

node_id = node_id instance-attribute

project_id = project_id instance-attribute

context = context instance-attribute

tag = tag instance-attribute

direction = direction instance-attribute

device = device or {} instance-attribute

state = state instance-attribute

segment_id = segment_id instance-attribute

__init__(client, call_id, node_id, project_id, context, *, tag='', direction='', device=None, state='', segment_id='')

on(event_type, handler)

Register an event listener for this call.

wait_for(event_type, predicate=None, timeout=None) async

Wait for a specific event, optionally filtered by predicate.

wait_for_ended(timeout=None) async

Wait for the call to reach the ended state.

answer(**kwargs) async

Answer an inbound call.

hangup(reason='hangup') async

End/hang up the call.

pass_() async

Decline control of an inbound call, returning it to routing.

play(media, *, volume=None, direction=None, loop=None, control_id=None, on_completed=None, **kwargs) async

Play audio content. Returns a PlayAction for stop/pause/resume/wait.

play_tts(text, *, language=None, gender=None, voice=None, volume=None, on_completed=None) async

Play text-to-speech. Typed convenience over :meth:play.

Restores the legacy call.play_tts(text=...) ergonomics so callers don't hand-build the {"type": "tts", "params": {...}} media shape.

play_audio(url, *, volume=None, on_completed=None) async

Play an audio file from a URL. Typed convenience over :meth:play.

play_silence(duration, *, on_completed=None) async

Play silence for duration seconds. Typed convenience over :meth:play.

play_ringtone(name, *, duration=None, volume=None, on_completed=None) async

Play a named ringtone by country code. Typed convenience over :meth:play.

detect_digit(*, digits=None, timeout=None, on_completed=None) async

Detect DTMF digits. Typed convenience over :meth:detect.

detect_answering_machine(*, initial_timeout=None, end_silence_timeout=None, machine_voice_threshold=None, machine_words_threshold=None, detect_interruptions=None, detect_message_end=None, timeout=None, on_completed=None) async

Detect human vs answering machine (AMD). Typed convenience over :meth:detect.

detect_fax(*, tone=None, timeout=None, on_completed=None) async

Detect a fax tone (CED/CNG). Typed convenience over :meth:detect.

prompt_tts(text, collect, *, language=None, gender=None, voice=None, volume=None, on_completed=None) async

Play TTS then collect input. Typed media over :meth:play_and_collect.

prompt_audio(url, collect, *, volume=None, on_completed=None) async

Play an audio file then collect input. Typed media over :meth:play_and_collect.

wait_for_answered(timeout=None) async

Wait until the call is answered (immediate if already answered or past it).

wait_for_ringing(timeout=None) async

Wait until the call is ringing (immediate if already ringing or past it).

wait_for_ending(timeout=None) async

Wait until the call is ending (immediate if already ending or past it).

record(audio=None, *, control_id=None, on_completed=None, **kwargs) async

Record audio from the call. Returns a RecordAction.

play_and_collect(media, collect, *, volume=None, control_id=None, on_completed=None, **kwargs) async

Play audio and collect digit/speech input.

collect(*, digits=None, speech=None, initial_timeout=None, partial_results=None, continuous=None, send_start_of_input=None, start_input_timers=None, control_id=None, on_completed=None, **kwargs) async

Collect digit/speech input without playing media.

connect(devices, *, ringback=None, tag=None, max_duration=None, max_price_per_minute=None, status_url=None, **kwargs) async

Bridge the call to one or more destinations.

disconnect() async

Disconnect (unbridge) a connected call.

send_digits(digits, *, control_id=None) async

Send DTMF digits on the call.

detect(detect, *, timeout=None, control_id=None, on_completed=None, **kwargs) async

Start audio detection (machine, fax, digit). Returns a DetectAction.

refer(device, *, status_url=None, **kwargs) async

Transfer a SIP call to an external SIP endpoint via REFER.

pay(payment_connector_url, *, control_id=None, input_method=None, status_url=None, payment_method=None, timeout=None, max_attempts=None, security_code=None, postal_code=None, min_postal_code_length=None, token_type=None, charge_amount=None, currency=None, language=None, voice=None, description=None, valid_card_types=None, parameters=None, prompts=None, on_completed=None, **kwargs) async

Start a payment collection. Returns a PayAction.

send_fax(document, *, identity=None, header_info=None, control_id=None, on_completed=None, **kwargs) async

Send a fax document. Returns a FaxAction.

receive_fax(*, control_id=None, on_completed=None, **kwargs) async

Receive a fax. Returns a FaxAction.

tap(tap, device, *, control_id=None, on_completed=None, **kwargs) async

Intercept call media and stream it. Returns a TapAction.

stream(url, *, name=None, codec=None, track=None, status_url=None, status_url_method=None, authorization_bearer_token=None, custom_parameters=None, control_id=None, on_completed=None, **kwargs) async

Start streaming call audio to a WebSocket endpoint. Returns a StreamAction.

transfer(dest, **kwargs) async

Transfer call control to another RELAY app or SWML script.

join_conference(name, *, muted=None, beep=None, start_on_enter=None, end_on_exit=None, wait_url=None, max_participants=None, record=None, region=None, trim=None, coach=None, status_callback=None, status_callback_event=None, status_callback_event_type=None, status_callback_method=None, recording_status_callback=None, recording_status_callback_event=None, recording_status_callback_event_type=None, recording_status_callback_method=None, stream_obj=None, **kwargs) async

Join an ad-hoc audio conference.

leave_conference(conference_id, **kwargs) async

Leave an audio conference.

hold() async

Put the call on hold.

unhold() async

Release the call from hold.

denoise() async

Start noise reduction on the call.

denoise_stop() async

Stop noise reduction on the call.

transcribe(*, control_id=None, status_url=None, on_completed=None, **kwargs) async

Start transcribing the call. Returns a TranscribeAction.

echo(*, timeout=None, status_url=None, **kwargs) async

Echo audio back to the caller (useful for testing).

bind_digit(digits, bind_method, *, bind_params=None, realm=None, max_triggers=None, **kwargs) async

Bind a DTMF digit sequence to trigger a RELAY method.

clear_digit_bindings(*, realm=None, **kwargs) async

Clear all digit bindings, optionally filtered by realm.

live_transcribe(action, **kwargs) async

Start or stop live transcription on the call.

live_translate(action, *, status_url=None, **kwargs) async

Start or stop live translation on the call.

join_room(name, *, status_url=None, **kwargs) async

Join a video/audio room.

leave_room(**kwargs) async

Leave the current room.

ai(*, control_id=None, agent=None, prompt=None, post_prompt=None, post_prompt_url=None, post_prompt_auth_user=None, post_prompt_auth_password=None, global_data=None, pronounce=None, hints=None, languages=None, SWAIG=None, ai_params=None, on_completed=None, **kwargs) async

Start an AI agent session on the call. Returns an AIAction.

amazon_bedrock(*, prompt=None, SWAIG=None, ai_params=None, global_data=None, post_prompt=None, post_prompt_url=None, **kwargs) async

Connect to an Amazon Bedrock AI agent.

ai_message(*, message_text=None, role=None, reset=None, global_data=None, **kwargs) async

Send a message to an active AI agent session.

ai_hold(*, timeout=None, prompt=None, **kwargs) async

Put an AI agent session on hold.

ai_unhold(*, prompt=None, **kwargs) async

Resume an AI agent session from hold.

user_event(*, event=None, **kwargs) async

Send a custom user-defined event.

queue_enter(queue_name, *, control_id=None, status_url=None, **kwargs) async

Place the call in a queue.

queue_leave(queue_name, *, control_id=None, queue_id=None, status_url=None, **kwargs) async

Remove the call from a queue.

__repr__()

Action

Base class for async action handles (play, record, detect, etc.).

Holds a control_id and back-reference to the Call. Resolves when the server sends a terminal event for this control_id.

call = call instance-attribute

control_id = control_id instance-attribute

result = None instance-attribute

completed = False instance-attribute

is_done property

__init__(call, control_id, terminal_event, terminal_states)

wait(timeout=None) async

Wait for the action to complete. Returns the terminal event.

PlayAction

Bases: Action

Handle for an active play operation.

__init__(call, control_id)

stop() async

pause() async

resume() async

volume(volume) async

RecordAction

Bases: Action

Handle for an active record operation.

__init__(call, control_id)

stop() async

pause(behavior=None) async

resume() async

DetectAction

Bases: Action

Handle for an active detect operation.

__init__(call, control_id)

stop() async

CollectAction

Bases: Action

Handle for play_and_collect or standalone collect.

__init__(call, control_id)

stop() async

volume(volume) async

start_input_timers() async

Start the initial_timeout timer on an active collect.

StandaloneCollectAction

Bases: Action

Handle for standalone calling.collect (without play).

__init__(call, control_id)

stop() async

start_input_timers() async

Start the initial_timeout timer on an active collect.

FaxAction

Bases: Action

Handle for an active send_fax or receive_fax operation.

__init__(call, control_id, method_prefix)

stop() async

TapAction

Bases: Action

Handle for an active tap operation.

__init__(call, control_id)

stop() async

StreamAction

Bases: Action

Handle for an active stream operation.

__init__(call, control_id)

stop() async

PayAction

Bases: Action

Handle for an active pay operation.

__init__(call, control_id)

stop() async

TranscribeAction

Bases: Action

Handle for an active transcribe operation.

__init__(call, control_id)

stop() async

AIAction

Bases: Action

Handle for an active AI agent session.

__init__(call, control_id)

stop() async

Message

Represents a single SMS/MMS message.

For outbound messages, use await message.wait() to block until a terminal state (delivered, undelivered, failed) is reached.

message_id = message_id instance-attribute

context = context instance-attribute

direction = direction instance-attribute

from_number = from_number instance-attribute

to_number = to_number instance-attribute

body = body instance-attribute

media = media or [] instance-attribute

segments = segments instance-attribute

state = state instance-attribute

reason = reason instance-attribute

tags = tags or [] instance-attribute

is_done property

True if the message has reached a terminal state.

result property

The terminal RelayEvent, or None if not yet done.

__init__(*, message_id='', context='', direction='', from_number='', to_number='', body='', media=None, segments=0, state='', reason='', tags=None)

on(handler)

Register an event listener for state changes on this message.

wait(timeout=None) async

Block until the message reaches a terminal state.

Returns the terminal RelayEvent. Raises asyncio.TimeoutError if timeout is specified and exceeded.

__repr__()

RelayEvent dataclass

Base event — wraps the raw params dict from a signalwire.event message.

event_type instance-attribute

params instance-attribute

call_id = '' class-attribute instance-attribute

timestamp = 0.0 class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0)

CallStateEvent dataclass

Bases: RelayEvent

Event for calling.call.state.

call_state = '' class-attribute instance-attribute

end_reason = '' class-attribute instance-attribute

direction = '' class-attribute instance-attribute

device = field(default_factory=dict) class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, call_state='', end_reason='', direction='', device=dict())

CallReceiveEvent dataclass

Bases: RelayEvent

Event for calling.call.receive — inbound call notification.

call_state = '' class-attribute instance-attribute

direction = '' class-attribute instance-attribute

device = field(default_factory=dict) class-attribute instance-attribute

node_id = '' class-attribute instance-attribute

project_id = '' class-attribute instance-attribute

context = '' class-attribute instance-attribute

segment_id = '' class-attribute instance-attribute

tag = '' class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, call_state='', direction='', device=dict(), node_id='', project_id='', context='', segment_id='', tag='')

PlayEvent dataclass

Bases: RelayEvent

Event for calling.call.play.

control_id = '' class-attribute instance-attribute

state = '' class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='')

RecordEvent dataclass

Bases: RelayEvent

Event for calling.call.record.

control_id = '' class-attribute instance-attribute

state = '' class-attribute instance-attribute

url = '' class-attribute instance-attribute

duration = 0.0 class-attribute instance-attribute

size = 0 class-attribute instance-attribute

record = field(default_factory=dict) class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='', url='', duration=0.0, size=0, record=dict())

CollectEvent dataclass

Bases: RelayEvent

Event for calling.call.collect.

control_id = '' class-attribute instance-attribute

state = '' class-attribute instance-attribute

result = field(default_factory=dict) class-attribute instance-attribute

final = None class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='', result=dict(), final=None)

ConnectEvent dataclass

Bases: RelayEvent

Event for calling.call.connect.

connect_state = '' class-attribute instance-attribute

peer = field(default_factory=dict) class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, connect_state='', peer=dict())

DetectEvent dataclass

Bases: RelayEvent

Event for calling.call.detect.

control_id = '' class-attribute instance-attribute

detect = field(default_factory=dict) class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', detect=dict())

FaxEvent dataclass

Bases: RelayEvent

Event for calling.call.fax.

control_id = '' class-attribute instance-attribute

fax = field(default_factory=dict) class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', fax=dict())

TapEvent dataclass

Bases: RelayEvent

Event for calling.call.tap.

control_id = '' class-attribute instance-attribute

state = '' class-attribute instance-attribute

tap = field(default_factory=dict) class-attribute instance-attribute

device = field(default_factory=dict) class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='', tap=dict(), device=dict())

StreamEvent dataclass

Bases: RelayEvent

Event for calling.call.stream.

control_id = '' class-attribute instance-attribute

state = '' class-attribute instance-attribute

url = '' class-attribute instance-attribute

name = '' class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='', url='', name='')

SendDigitsEvent dataclass

Bases: RelayEvent

Event for calling.call.send_digits.

control_id = '' class-attribute instance-attribute

state = '' class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='')

DialEvent dataclass

Bases: RelayEvent

Event for calling.call.dial.

tag = '' class-attribute instance-attribute

dial_state = '' class-attribute instance-attribute

call = field(default_factory=dict) class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, tag='', dial_state='', call=dict())

ReferEvent dataclass

Bases: RelayEvent

Event for calling.call.refer.

state = '' class-attribute instance-attribute

sip_refer_to = '' class-attribute instance-attribute

sip_refer_response_code = '' class-attribute instance-attribute

sip_notify_response_code = '' class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, state='', sip_refer_to='', sip_refer_response_code='', sip_notify_response_code='')

DenoiseEvent dataclass

Bases: RelayEvent

Event for calling.call.denoise.

denoised = False class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, denoised=False)

PayEvent dataclass

Bases: RelayEvent

Event for calling.call.pay.

control_id = '' class-attribute instance-attribute

state = '' class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='')

QueueEvent dataclass

Bases: RelayEvent

Event for calling.call.queue.

control_id = '' class-attribute instance-attribute

status = '' class-attribute instance-attribute

queue_id = '' class-attribute instance-attribute

queue_name = '' class-attribute instance-attribute

position = 0 class-attribute instance-attribute

size = 0 class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', status='', queue_id='', queue_name='', position=0, size=0)

EchoEvent dataclass

Bases: RelayEvent

Event for calling.call.echo.

state = '' class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, state='')

TranscribeEvent dataclass

Bases: RelayEvent

Event for calling.call.transcribe.

control_id = '' class-attribute instance-attribute

state = '' class-attribute instance-attribute

url = '' class-attribute instance-attribute

recording_id = '' class-attribute instance-attribute

duration = 0.0 class-attribute instance-attribute

size = 0 class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='', url='', recording_id='', duration=0.0, size=0)

HoldEvent dataclass

Bases: RelayEvent

Event for calling.call.hold.

state = '' class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, state='')

ConferenceEvent dataclass

Bases: RelayEvent

Event for calling.conference.

conference_id = '' class-attribute instance-attribute

name = '' class-attribute instance-attribute

status = '' class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, conference_id='', name='', status='')

CallingErrorEvent dataclass

Bases: RelayEvent

Event for calling.error.

code = '' class-attribute instance-attribute

message = '' class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, code='', message='')

MessageReceiveEvent dataclass

Bases: RelayEvent

Event for messaging.receive — inbound message notification.

message_id = '' class-attribute instance-attribute

context = '' class-attribute instance-attribute

direction = '' class-attribute instance-attribute

from_number = '' class-attribute instance-attribute

to_number = '' class-attribute instance-attribute

body = '' class-attribute instance-attribute

media = field(default_factory=list) class-attribute instance-attribute

segments = 0 class-attribute instance-attribute

message_state = '' class-attribute instance-attribute

tags = field(default_factory=list) class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, message_id='', context='', direction='', from_number='', to_number='', body='', media=list(), segments=0, message_state='', tags=list())

MessageStateEvent dataclass

Bases: RelayEvent

Event for messaging.state — outbound message state change.

message_id = '' class-attribute instance-attribute

context = '' class-attribute instance-attribute

direction = '' class-attribute instance-attribute

from_number = '' class-attribute instance-attribute

to_number = '' class-attribute instance-attribute

body = '' class-attribute instance-attribute

media = field(default_factory=list) class-attribute instance-attribute

segments = 0 class-attribute instance-attribute

message_state = '' class-attribute instance-attribute

reason = '' class-attribute instance-attribute

tags = field(default_factory=list) class-attribute instance-attribute

from_payload(payload) classmethod

__init__(event_type, params, call_id='', timestamp=0.0, message_id='', context='', direction='', from_number='', to_number='', body='', media=list(), segments=0, message_state='', reason='', tags=list())

parse_event(payload)

Parse a raw signalwire.event params dict into a typed event object.

call

Call object — represents a live RELAY call with command methods.

logger = get_logger('relay_call') module-attribute

EventHandler = Callable[[RelayEvent], Coroutine[Any, Any, None] | None] module-attribute

Action

Base class for async action handles (play, record, detect, etc.).

Holds a control_id and back-reference to the Call. Resolves when the server sends a terminal event for this control_id.

call = call instance-attribute
control_id = control_id instance-attribute
result = None instance-attribute
completed = False instance-attribute
is_done property
__init__(call, control_id, terminal_event, terminal_states)
wait(timeout=None) async

Wait for the action to complete. Returns the terminal event.

PlayAction

Bases: Action

Handle for an active play operation.

__init__(call, control_id)
stop() async
pause() async
resume() async
volume(volume) async

RecordAction

Bases: Action

Handle for an active record operation.

__init__(call, control_id)
stop() async
pause(behavior=None) async
resume() async

DetectAction

Bases: Action

Handle for an active detect operation.

__init__(call, control_id)
stop() async

CollectAction

Bases: Action

Handle for play_and_collect or standalone collect.

__init__(call, control_id)
stop() async
volume(volume) async
start_input_timers() async

Start the initial_timeout timer on an active collect.

StandaloneCollectAction

Bases: Action

Handle for standalone calling.collect (without play).

__init__(call, control_id)
stop() async
start_input_timers() async

Start the initial_timeout timer on an active collect.

FaxAction

Bases: Action

Handle for an active send_fax or receive_fax operation.

__init__(call, control_id, method_prefix)
stop() async

TapAction

Bases: Action

Handle for an active tap operation.

__init__(call, control_id)
stop() async

StreamAction

Bases: Action

Handle for an active stream operation.

__init__(call, control_id)
stop() async

PayAction

Bases: Action

Handle for an active pay operation.

__init__(call, control_id)
stop() async

TranscribeAction

Bases: Action

Handle for an active transcribe operation.

__init__(call, control_id)
stop() async

AIAction

Bases: Action

Handle for an active AI agent session.

__init__(call, control_id)
stop() async

Call

Represents a live RELAY call.

Created by RelayClient on inbound calling.call.receive events or outbound dial/begin responses.

call_id = call_id instance-attribute
node_id = node_id instance-attribute
project_id = project_id instance-attribute
context = context instance-attribute
tag = tag instance-attribute
direction = direction instance-attribute
device = device or {} instance-attribute
state = state instance-attribute
segment_id = segment_id instance-attribute
__init__(client, call_id, node_id, project_id, context, *, tag='', direction='', device=None, state='', segment_id='')
on(event_type, handler)

Register an event listener for this call.

wait_for(event_type, predicate=None, timeout=None) async

Wait for a specific event, optionally filtered by predicate.

wait_for_ended(timeout=None) async

Wait for the call to reach the ended state.

answer(**kwargs) async

Answer an inbound call.

hangup(reason='hangup') async

End/hang up the call.

pass_() async

Decline control of an inbound call, returning it to routing.

play(media, *, volume=None, direction=None, loop=None, control_id=None, on_completed=None, **kwargs) async

Play audio content. Returns a PlayAction for stop/pause/resume/wait.

play_tts(text, *, language=None, gender=None, voice=None, volume=None, on_completed=None) async

Play text-to-speech. Typed convenience over :meth:play.

Restores the legacy call.play_tts(text=...) ergonomics so callers don't hand-build the {"type": "tts", "params": {...}} media shape.

play_audio(url, *, volume=None, on_completed=None) async

Play an audio file from a URL. Typed convenience over :meth:play.

play_silence(duration, *, on_completed=None) async

Play silence for duration seconds. Typed convenience over :meth:play.

play_ringtone(name, *, duration=None, volume=None, on_completed=None) async

Play a named ringtone by country code. Typed convenience over :meth:play.

detect_digit(*, digits=None, timeout=None, on_completed=None) async

Detect DTMF digits. Typed convenience over :meth:detect.

detect_answering_machine(*, initial_timeout=None, end_silence_timeout=None, machine_voice_threshold=None, machine_words_threshold=None, detect_interruptions=None, detect_message_end=None, timeout=None, on_completed=None) async

Detect human vs answering machine (AMD). Typed convenience over :meth:detect.

detect_fax(*, tone=None, timeout=None, on_completed=None) async

Detect a fax tone (CED/CNG). Typed convenience over :meth:detect.

prompt_tts(text, collect, *, language=None, gender=None, voice=None, volume=None, on_completed=None) async

Play TTS then collect input. Typed media over :meth:play_and_collect.

prompt_audio(url, collect, *, volume=None, on_completed=None) async

Play an audio file then collect input. Typed media over :meth:play_and_collect.

wait_for_answered(timeout=None) async

Wait until the call is answered (immediate if already answered or past it).

wait_for_ringing(timeout=None) async

Wait until the call is ringing (immediate if already ringing or past it).

wait_for_ending(timeout=None) async

Wait until the call is ending (immediate if already ending or past it).

record(audio=None, *, control_id=None, on_completed=None, **kwargs) async

Record audio from the call. Returns a RecordAction.

play_and_collect(media, collect, *, volume=None, control_id=None, on_completed=None, **kwargs) async

Play audio and collect digit/speech input.

collect(*, digits=None, speech=None, initial_timeout=None, partial_results=None, continuous=None, send_start_of_input=None, start_input_timers=None, control_id=None, on_completed=None, **kwargs) async

Collect digit/speech input without playing media.

connect(devices, *, ringback=None, tag=None, max_duration=None, max_price_per_minute=None, status_url=None, **kwargs) async

Bridge the call to one or more destinations.

disconnect() async

Disconnect (unbridge) a connected call.

send_digits(digits, *, control_id=None) async

Send DTMF digits on the call.

detect(detect, *, timeout=None, control_id=None, on_completed=None, **kwargs) async

Start audio detection (machine, fax, digit). Returns a DetectAction.

refer(device, *, status_url=None, **kwargs) async

Transfer a SIP call to an external SIP endpoint via REFER.

pay(payment_connector_url, *, control_id=None, input_method=None, status_url=None, payment_method=None, timeout=None, max_attempts=None, security_code=None, postal_code=None, min_postal_code_length=None, token_type=None, charge_amount=None, currency=None, language=None, voice=None, description=None, valid_card_types=None, parameters=None, prompts=None, on_completed=None, **kwargs) async

Start a payment collection. Returns a PayAction.

send_fax(document, *, identity=None, header_info=None, control_id=None, on_completed=None, **kwargs) async

Send a fax document. Returns a FaxAction.

receive_fax(*, control_id=None, on_completed=None, **kwargs) async

Receive a fax. Returns a FaxAction.

tap(tap, device, *, control_id=None, on_completed=None, **kwargs) async

Intercept call media and stream it. Returns a TapAction.

stream(url, *, name=None, codec=None, track=None, status_url=None, status_url_method=None, authorization_bearer_token=None, custom_parameters=None, control_id=None, on_completed=None, **kwargs) async

Start streaming call audio to a WebSocket endpoint. Returns a StreamAction.

transfer(dest, **kwargs) async

Transfer call control to another RELAY app or SWML script.

join_conference(name, *, muted=None, beep=None, start_on_enter=None, end_on_exit=None, wait_url=None, max_participants=None, record=None, region=None, trim=None, coach=None, status_callback=None, status_callback_event=None, status_callback_event_type=None, status_callback_method=None, recording_status_callback=None, recording_status_callback_event=None, recording_status_callback_event_type=None, recording_status_callback_method=None, stream_obj=None, **kwargs) async

Join an ad-hoc audio conference.

leave_conference(conference_id, **kwargs) async

Leave an audio conference.

hold() async

Put the call on hold.

unhold() async

Release the call from hold.

denoise() async

Start noise reduction on the call.

denoise_stop() async

Stop noise reduction on the call.

transcribe(*, control_id=None, status_url=None, on_completed=None, **kwargs) async

Start transcribing the call. Returns a TranscribeAction.

echo(*, timeout=None, status_url=None, **kwargs) async

Echo audio back to the caller (useful for testing).

bind_digit(digits, bind_method, *, bind_params=None, realm=None, max_triggers=None, **kwargs) async

Bind a DTMF digit sequence to trigger a RELAY method.

clear_digit_bindings(*, realm=None, **kwargs) async

Clear all digit bindings, optionally filtered by realm.

live_transcribe(action, **kwargs) async

Start or stop live transcription on the call.

live_translate(action, *, status_url=None, **kwargs) async

Start or stop live translation on the call.

join_room(name, *, status_url=None, **kwargs) async

Join a video/audio room.

leave_room(**kwargs) async

Leave the current room.

ai(*, control_id=None, agent=None, prompt=None, post_prompt=None, post_prompt_url=None, post_prompt_auth_user=None, post_prompt_auth_password=None, global_data=None, pronounce=None, hints=None, languages=None, SWAIG=None, ai_params=None, on_completed=None, **kwargs) async

Start an AI agent session on the call. Returns an AIAction.

amazon_bedrock(*, prompt=None, SWAIG=None, ai_params=None, global_data=None, post_prompt=None, post_prompt_url=None, **kwargs) async

Connect to an Amazon Bedrock AI agent.

ai_message(*, message_text=None, role=None, reset=None, global_data=None, **kwargs) async

Send a message to an active AI agent session.

ai_hold(*, timeout=None, prompt=None, **kwargs) async

Put an AI agent session on hold.

ai_unhold(*, prompt=None, **kwargs) async

Resume an AI agent session from hold.

user_event(*, event=None, **kwargs) async

Send a custom user-defined event.

queue_enter(queue_name, *, control_id=None, status_url=None, **kwargs) async

Place the call in a queue.

queue_leave(queue_name, *, control_id=None, queue_id=None, status_url=None, **kwargs) async

Remove the call from a queue.

__repr__()

client

RelayClient — WebSocket + JSON-RPC 2.0 protocol + event dispatch.

One instance = one persistent WebSocket connection to SignalWire RELAY.

Architecture notes (mirrors the JS SDK): - JSON-RPC requests are tracked by id in _pending; responses resolve the corresponding Future. - signalwire.event messages are acknowledged back to the server (event ACK) and then dispatched by event_type → Call object → Action object. - Each Action registers with a control_id and listens for its own event_type (e.g. calling.call.play). Actions filter events by control_id so multiple concurrent actions on the same call work. - Result code checking accepts any 2xx (matching the JS SDK regex /^2[0-9][]$/). signalwire.connect responses skip code checking entirely. - Execute has a configurable timeout (default 10s) to detect half-open connections. - Requests made while disconnected are queued and flushed after re-auth. - Server pings are tracked; if no ping arrives within the check interval the connection is assumed half-open and force-closed for reconnect.

logger = get_logger('relay_client') module-attribute

CallHandler = Callable[['Call'], Coroutine[Any, Any, None]] module-attribute

MessageHandler = Callable[['Message'], Coroutine[Any, Any, None]] module-attribute

RelayClient

Manages a WebSocket connection to SignalWire RELAY.

Usage::

client = RelayClient(project="...", token="...", contexts=["default"])

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

client.run()
project = project or os.environ.get('SIGNALWIRE_PROJECT_ID', '') instance-attribute
token = token or os.environ.get('SIGNALWIRE_API_TOKEN', '') instance-attribute
jwt_token = jwt_token or os.environ.get('SIGNALWIRE_JWT_TOKEN', '') instance-attribute
host = host or os.environ.get('SIGNALWIRE_SPACE', DEFAULT_RELAY_HOST) instance-attribute
contexts = contexts or [] instance-attribute
relay_protocol property

Server-assigned protocol string from the connect response.

__init__(project=None, token=None, jwt_token=None, host=None, contexts=None, max_active_calls=None)
__del__()
__aenter__() async
__aexit__(*exc) async
on_call(handler)

Register the inbound call handler (decorator).

on_message(handler)

Register the inbound message handler (decorator).

connect() async

Connect to RELAY and authenticate.

disconnect() async

Cleanly close the connection.

execute(method, params) async

Send a JSON-RPC request and await the response.

For calling methods, method is the full name (e.g. "calling.answer", "calling.play") with node_id and call_id in params.

If the connection is not ready, the request is queued and sent after re-authentication completes.

dial(devices, *, tag=None, max_duration=None, dial_timeout=None) async

Initiate an outbound call using dial. Returns a Call object.

The calling.dial RPC response only contains {"code": "200", "message": "Dialing"} — no call_id. The real call_id and node_id arrive via calling.call.dial events matched by tag. This method waits for that event so the returned Call always has valid identifiers.

Parameters:

Name Type Description Default
devices list[list[dict[str, Any]]]

Array of device lists (serial/parallel dial).

required
tag str | None

Client-provided tag for event correlation. Auto-generated if not supplied.

None
max_duration int | None

Optional max call duration in minutes.

None
dial_timeout float | None

How long (seconds) to wait for the dial to complete before raising TimeoutError. Defaults to 120s.

None
send_message(*, to_number, from_number, context=None, body=None, media=None, tags=None, region=None, on_completed=None) async

Send an outbound SMS/MMS message.

At least one of body or media must be provided.

Returns a Message object that tracks state changes. Use await message.wait() to block until delivery confirmation (or failure).

Parameters:

Name Type Description Default
to_number str

Destination phone number in E.164 format.

required
from_number str

Sender phone number in E.164 format.

required
context str | None

Context for receiving state events. Defaults to the relay protocol.

None
body str | None

Text body of the message.

None
media list[str] | None

List of media URLs for MMS.

None
tags list[str] | None

Optional tags for the message.

None
region str | None

Optional origination region.

None
on_completed Callable[[RelayEvent], Any] | None

Optional callback fired when a terminal state (delivered/undelivered/failed) is reached.

None
receive(contexts) async

Subscribe to additional contexts for inbound events.

Sends signalwire.receive on the assigned protocol to start receiving inbound calls on the given contexts. Can be called after connect() to dynamically add contexts without reconnecting.

unreceive(contexts) async

Unsubscribe from contexts for inbound events.

Sends signalwire.unreceive to stop receiving inbound calls on the given contexts.

run()

Blocking entry point — runs the event loop until interrupted.

RelayError

Bases: Exception

Error returned by the RELAY server.

code = code instance-attribute
message = message instance-attribute
__init__(code, message)

constants

Protocol constants for the SignalWire RELAY calling API.

PROTOCOL_VERSION = {'major': 2, 'minor': 0, 'revision': 0} module-attribute

AGENT_STRING = 'signalwire-agents-python/1.0' module-attribute

METHOD_SIGNALWIRE_CONNECT = 'signalwire.connect' module-attribute

METHOD_SIGNALWIRE_EVENT = 'signalwire.event' module-attribute

METHOD_SIGNALWIRE_PING = 'signalwire.ping' module-attribute

METHOD_SIGNALWIRE_DISCONNECT = 'signalwire.disconnect' module-attribute

METHOD_SIGNALWIRE_RECEIVE = 'signalwire.receive' module-attribute

METHOD_SIGNALWIRE_UNRECEIVE = 'signalwire.unreceive' module-attribute

EVENT_AUTHORIZATION_STATE = 'signalwire.authorization.state' module-attribute

CALL_STATE_CREATED = 'created' module-attribute

CALL_STATE_RINGING = 'ringing' module-attribute

CALL_STATE_ANSWERED = 'answered' module-attribute

CALL_STATE_ENDING = 'ending' module-attribute

CALL_STATE_ENDED = 'ended' module-attribute

CALL_STATES = (CALL_STATE_CREATED, CALL_STATE_RINGING, CALL_STATE_ANSWERED, CALL_STATE_ENDING, CALL_STATE_ENDED) module-attribute

END_REASON_HANGUP = 'hangup' module-attribute

END_REASON_CANCEL = 'cancel' module-attribute

END_REASON_BUSY = 'busy' module-attribute

END_REASON_NO_ANSWER = 'noAnswer' module-attribute

END_REASON_DECLINE = 'decline' module-attribute

END_REASON_ERROR = 'error' module-attribute

END_REASON_ABANDONED = 'abandoned' module-attribute

END_REASON_MAX_DURATION = 'max_duration' module-attribute

END_REASON_NOT_FOUND = 'not_found' module-attribute

CONNECT_STATE_CONNECTING = 'connecting' module-attribute

CONNECT_STATE_CONNECTED = 'connected' module-attribute

CONNECT_STATE_DISCONNECTED = 'disconnected' module-attribute

CONNECT_STATE_FAILED = 'failed' module-attribute

EVENT_CALL_STATE = 'calling.call.state' module-attribute

EVENT_CALL_RECEIVE = 'calling.call.receive' module-attribute

EVENT_CALL_CONNECT = 'calling.call.connect' module-attribute

EVENT_CALL_PLAY = 'calling.call.play' module-attribute

EVENT_CALL_COLLECT = 'calling.call.collect' module-attribute

EVENT_CALL_RECORD = 'calling.call.record' module-attribute

EVENT_CALL_DETECT = 'calling.call.detect' module-attribute

EVENT_CALL_FAX = 'calling.call.fax' module-attribute

EVENT_CALL_TAP = 'calling.call.tap' module-attribute

EVENT_CALL_SEND_DIGITS = 'calling.call.send_digits' module-attribute

EVENT_CALL_DIAL = 'calling.call.dial' module-attribute

EVENT_CALL_REFER = 'calling.call.refer' module-attribute

EVENT_CALL_DENOISE = 'calling.call.denoise' module-attribute

EVENT_CALL_PAY = 'calling.call.pay' module-attribute

EVENT_CALL_QUEUE = 'calling.call.queue' module-attribute

EVENT_CALL_STREAM = 'calling.call.stream' module-attribute

EVENT_CALL_ECHO = 'calling.call.echo' module-attribute

EVENT_CALL_TRANSCRIBE = 'calling.call.transcribe' module-attribute

EVENT_CONFERENCE = 'calling.conference' module-attribute

EVENT_CALLING_ERROR = 'calling.error' module-attribute

EVENT_MESSAGING_RECEIVE = 'messaging.receive' module-attribute

EVENT_MESSAGING_STATE = 'messaging.state' module-attribute

MESSAGE_STATE_QUEUED = 'queued' module-attribute

MESSAGE_STATE_INITIATED = 'initiated' module-attribute

MESSAGE_STATE_SENT = 'sent' module-attribute

MESSAGE_STATE_DELIVERED = 'delivered' module-attribute

MESSAGE_STATE_UNDELIVERED = 'undelivered' module-attribute

MESSAGE_STATE_FAILED = 'failed' module-attribute

MESSAGE_STATE_RECEIVED = 'received' module-attribute

MESSAGE_TERMINAL_STATES = (MESSAGE_STATE_DELIVERED, MESSAGE_STATE_UNDELIVERED, MESSAGE_STATE_FAILED) module-attribute

PLAY_STATE_PLAYING = 'playing' module-attribute

PLAY_STATE_PAUSED = 'paused' module-attribute

PLAY_STATE_FINISHED = 'finished' module-attribute

PLAY_STATE_ERROR = 'error' module-attribute

RECORD_STATE_RECORDING = 'recording' module-attribute

RECORD_STATE_PAUSED = 'paused' module-attribute

RECORD_STATE_FINISHED = 'finished' module-attribute

RECORD_STATE_NO_INPUT = 'no_input' module-attribute

DETECT_TYPE_MACHINE = 'machine' module-attribute

DETECT_TYPE_FAX = 'fax' module-attribute

DETECT_TYPE_DIGIT = 'digit' module-attribute

ROOM_STATE_JOINING = 'joining' module-attribute

ROOM_STATE_JOIN = 'join' module-attribute

ROOM_STATE_LEAVING = 'leaving' module-attribute

ROOM_STATE_LEAVE = 'leave' module-attribute

RECONNECT_MIN_DELAY = 1.0 module-attribute

RECONNECT_MAX_DELAY = 30.0 module-attribute

RECONNECT_BACKOFF_FACTOR = 2.0 module-attribute

DEFAULT_RELAY_HOST = 'relay.signalwire.com' module-attribute

event

Typed event wrappers for RELAY calling events.

These are convenience dataclasses over raw event dicts. All Call event handlers also accept the raw dict, so these are optional.

EVENT_CLASS_MAP = {'calling.call.state': CallStateEvent, 'calling.call.receive': CallReceiveEvent, 'calling.call.play': PlayEvent, 'calling.call.record': RecordEvent, 'calling.call.collect': CollectEvent, 'calling.call.connect': ConnectEvent, 'calling.call.detect': DetectEvent, 'calling.call.fax': FaxEvent, 'calling.call.tap': TapEvent, 'calling.call.stream': StreamEvent, 'calling.call.send_digits': SendDigitsEvent, 'calling.call.dial': DialEvent, 'calling.call.refer': ReferEvent, 'calling.call.denoise': DenoiseEvent, 'calling.call.pay': PayEvent, 'calling.call.queue': QueueEvent, 'calling.call.echo': EchoEvent, 'calling.call.transcribe': TranscribeEvent, 'calling.call.hold': HoldEvent, 'calling.conference': ConferenceEvent, 'calling.error': CallingErrorEvent, 'messaging.receive': MessageReceiveEvent, 'messaging.state': MessageStateEvent} module-attribute

RelayEvent dataclass

Base event — wraps the raw params dict from a signalwire.event message.

event_type instance-attribute
params instance-attribute
call_id = '' class-attribute instance-attribute
timestamp = 0.0 class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0)
from_payload(payload) classmethod

CallStateEvent dataclass

Bases: RelayEvent

Event for calling.call.state.

call_state = '' class-attribute instance-attribute
end_reason = '' class-attribute instance-attribute
direction = '' class-attribute instance-attribute
device = field(default_factory=dict) class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, call_state='', end_reason='', direction='', device=dict())
from_payload(payload) classmethod

CallReceiveEvent dataclass

Bases: RelayEvent

Event for calling.call.receive — inbound call notification.

call_state = '' class-attribute instance-attribute
direction = '' class-attribute instance-attribute
device = field(default_factory=dict) class-attribute instance-attribute
node_id = '' class-attribute instance-attribute
project_id = '' class-attribute instance-attribute
context = '' class-attribute instance-attribute
segment_id = '' class-attribute instance-attribute
tag = '' class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, call_state='', direction='', device=dict(), node_id='', project_id='', context='', segment_id='', tag='')
from_payload(payload) classmethod

PlayEvent dataclass

Bases: RelayEvent

Event for calling.call.play.

control_id = '' class-attribute instance-attribute
state = '' class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='')
from_payload(payload) classmethod

RecordEvent dataclass

Bases: RelayEvent

Event for calling.call.record.

control_id = '' class-attribute instance-attribute
state = '' class-attribute instance-attribute
url = '' class-attribute instance-attribute
duration = 0.0 class-attribute instance-attribute
size = 0 class-attribute instance-attribute
record = field(default_factory=dict) class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='', url='', duration=0.0, size=0, record=dict())
from_payload(payload) classmethod

CollectEvent dataclass

Bases: RelayEvent

Event for calling.call.collect.

control_id = '' class-attribute instance-attribute
state = '' class-attribute instance-attribute
result = field(default_factory=dict) class-attribute instance-attribute
final = None class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='', result=dict(), final=None)
from_payload(payload) classmethod

ConnectEvent dataclass

Bases: RelayEvent

Event for calling.call.connect.

connect_state = '' class-attribute instance-attribute
peer = field(default_factory=dict) class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, connect_state='', peer=dict())
from_payload(payload) classmethod

DetectEvent dataclass

Bases: RelayEvent

Event for calling.call.detect.

control_id = '' class-attribute instance-attribute
detect = field(default_factory=dict) class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', detect=dict())
from_payload(payload) classmethod

FaxEvent dataclass

Bases: RelayEvent

Event for calling.call.fax.

control_id = '' class-attribute instance-attribute
fax = field(default_factory=dict) class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', fax=dict())
from_payload(payload) classmethod

TapEvent dataclass

Bases: RelayEvent

Event for calling.call.tap.

control_id = '' class-attribute instance-attribute
state = '' class-attribute instance-attribute
tap = field(default_factory=dict) class-attribute instance-attribute
device = field(default_factory=dict) class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='', tap=dict(), device=dict())
from_payload(payload) classmethod

StreamEvent dataclass

Bases: RelayEvent

Event for calling.call.stream.

control_id = '' class-attribute instance-attribute
state = '' class-attribute instance-attribute
url = '' class-attribute instance-attribute
name = '' class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='', url='', name='')
from_payload(payload) classmethod

SendDigitsEvent dataclass

Bases: RelayEvent

Event for calling.call.send_digits.

control_id = '' class-attribute instance-attribute
state = '' class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='')
from_payload(payload) classmethod

DialEvent dataclass

Bases: RelayEvent

Event for calling.call.dial.

tag = '' class-attribute instance-attribute
dial_state = '' class-attribute instance-attribute
call = field(default_factory=dict) class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, tag='', dial_state='', call=dict())
from_payload(payload) classmethod

ReferEvent dataclass

Bases: RelayEvent

Event for calling.call.refer.

state = '' class-attribute instance-attribute
sip_refer_to = '' class-attribute instance-attribute
sip_refer_response_code = '' class-attribute instance-attribute
sip_notify_response_code = '' class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, state='', sip_refer_to='', sip_refer_response_code='', sip_notify_response_code='')
from_payload(payload) classmethod

DenoiseEvent dataclass

Bases: RelayEvent

Event for calling.call.denoise.

denoised = False class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, denoised=False)
from_payload(payload) classmethod

PayEvent dataclass

Bases: RelayEvent

Event for calling.call.pay.

control_id = '' class-attribute instance-attribute
state = '' class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='')
from_payload(payload) classmethod

QueueEvent dataclass

Bases: RelayEvent

Event for calling.call.queue.

control_id = '' class-attribute instance-attribute
status = '' class-attribute instance-attribute
queue_id = '' class-attribute instance-attribute
queue_name = '' class-attribute instance-attribute
position = 0 class-attribute instance-attribute
size = 0 class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', status='', queue_id='', queue_name='', position=0, size=0)
from_payload(payload) classmethod

EchoEvent dataclass

Bases: RelayEvent

Event for calling.call.echo.

state = '' class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, state='')
from_payload(payload) classmethod

TranscribeEvent dataclass

Bases: RelayEvent

Event for calling.call.transcribe.

control_id = '' class-attribute instance-attribute
state = '' class-attribute instance-attribute
url = '' class-attribute instance-attribute
recording_id = '' class-attribute instance-attribute
duration = 0.0 class-attribute instance-attribute
size = 0 class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, control_id='', state='', url='', recording_id='', duration=0.0, size=0)
from_payload(payload) classmethod

HoldEvent dataclass

Bases: RelayEvent

Event for calling.call.hold.

state = '' class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, state='')
from_payload(payload) classmethod

ConferenceEvent dataclass

Bases: RelayEvent

Event for calling.conference.

conference_id = '' class-attribute instance-attribute
name = '' class-attribute instance-attribute
status = '' class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, conference_id='', name='', status='')
from_payload(payload) classmethod

CallingErrorEvent dataclass

Bases: RelayEvent

Event for calling.error.

code = '' class-attribute instance-attribute
message = '' class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, code='', message='')
from_payload(payload) classmethod

MessageReceiveEvent dataclass

Bases: RelayEvent

Event for messaging.receive — inbound message notification.

message_id = '' class-attribute instance-attribute
context = '' class-attribute instance-attribute
direction = '' class-attribute instance-attribute
from_number = '' class-attribute instance-attribute
to_number = '' class-attribute instance-attribute
body = '' class-attribute instance-attribute
media = field(default_factory=list) class-attribute instance-attribute
segments = 0 class-attribute instance-attribute
message_state = '' class-attribute instance-attribute
tags = field(default_factory=list) class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, message_id='', context='', direction='', from_number='', to_number='', body='', media=list(), segments=0, message_state='', tags=list())
from_payload(payload) classmethod

MessageStateEvent dataclass

Bases: RelayEvent

Event for messaging.state — outbound message state change.

message_id = '' class-attribute instance-attribute
context = '' class-attribute instance-attribute
direction = '' class-attribute instance-attribute
from_number = '' class-attribute instance-attribute
to_number = '' class-attribute instance-attribute
body = '' class-attribute instance-attribute
media = field(default_factory=list) class-attribute instance-attribute
segments = 0 class-attribute instance-attribute
message_state = '' class-attribute instance-attribute
reason = '' class-attribute instance-attribute
tags = field(default_factory=list) class-attribute instance-attribute
__init__(event_type, params, call_id='', timestamp=0.0, message_id='', context='', direction='', from_number='', to_number='', body='', media=list(), segments=0, message_state='', reason='', tags=list())
from_payload(payload) classmethod

parse_event(payload)

Parse a raw signalwire.event params dict into a typed event object.

message

Message object — represents an SMS/MMS message in the RELAY messaging namespace.

A Message tracks the lifecycle of a sent or received message via state events. Outbound messages progress through: queued → initiated → sent → delivered (or undelivered/failed). Inbound messages arrive fully formed with state "received".

logger = get_logger('relay_message') module-attribute

Message

Represents a single SMS/MMS message.

For outbound messages, use await message.wait() to block until a terminal state (delivered, undelivered, failed) is reached.

message_id = message_id instance-attribute
context = context instance-attribute
direction = direction instance-attribute
from_number = from_number instance-attribute
to_number = to_number instance-attribute
body = body instance-attribute
media = media or [] instance-attribute
segments = segments instance-attribute
state = state instance-attribute
reason = reason instance-attribute
tags = tags or [] instance-attribute
is_done property

True if the message has reached a terminal state.

result property

The terminal RelayEvent, or None if not yet done.

__init__(*, message_id='', context='', direction='', from_number='', to_number='', body='', media=None, segments=0, state='', reason='', tags=None)
on(handler)

Register an event listener for state changes on this message.

wait(timeout=None) async

Block until the message reaches a terminal state.

Returns the terminal RelayEvent. Raises asyncio.TimeoutError if timeout is specified and exceeded.

__repr__()