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
¶
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
¶
RecordAction
¶
DetectAction
¶
CollectAction
¶
StandaloneCollectAction
¶
FaxAction
¶
TapAction
¶
StreamAction
¶
PayAction
¶
TranscribeAction
¶
AIAction
¶
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.
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.
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.
DetectEvent
dataclass
¶
Bases: RelayEvent
Event for calling.call.detect.
FaxEvent
dataclass
¶
Bases: RelayEvent
Event for calling.call.fax.
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.
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.
PayEvent
dataclass
¶
Bases: RelayEvent
Event for calling.call.pay.
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.
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.
ConferenceEvent
dataclass
¶
Bases: RelayEvent
Event for calling.conference.
CallingErrorEvent
dataclass
¶
Bases: RelayEvent
Event for calling.error.
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
¶
RecordAction
¶
DetectAction
¶
CollectAction
¶
StandaloneCollectAction
¶
FaxAction
¶
TapAction
¶
StreamAction
¶
PayAction
¶
TranscribeAction
¶
AIAction
¶
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.
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.
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.
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.
DetectEvent
dataclass
¶
Bases: RelayEvent
Event for calling.call.detect.
FaxEvent
dataclass
¶
Bases: RelayEvent
Event for calling.call.fax.
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.
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.
PayEvent
dataclass
¶
Bases: RelayEvent
Event for calling.call.pay.
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.
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.
ConferenceEvent
dataclass
¶
Bases: RelayEvent
Event for calling.conference.
CallingErrorEvent
dataclass
¶
Bases: RelayEvent
Event for calling.error.
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.