dial

View as MarkdownOpen in Claude

Initiate an outbound call. Sends a calling.dial JSON-RPC request and waits for the server to return a calling.call.dial event confirming the call was answered or failed. Returns a fully-initialized Call object with valid call_id and node_id.

The devices parameter supports both serial and parallel dialing strategies. Each inner list represents a set of devices to ring simultaneously (parallel). The outer list represents sequential attempts — if the first group fails, the next group is tried.

Raises RelayError if the dial fails or if no answer is received within the dial_timeout period. The default timeout is 120 seconds.

Parameters

devices
list[list[dict[str, Any]]]Required

Nested array of device definitions for serial and parallel dialing. Each device is a dict with type and params keys.

  • Serial dial (try one after another): each inner list has one device
  • Parallel dial (ring simultaneously): one inner list with multiple devices
devices[][].type
strRequired

Device type. Valid values:

  • "phone" — PSTN phone number
  • "sip" — SIP endpoint
devices[][].params
dictRequired

Device-specific parameters.

devices[][].params.to_number
strRequired

Destination phone number in E.164 format (for "phone" type).

devices[][].params.from_number
strRequired

Caller ID phone number in E.164 format (for "phone" type).

devices[][].params.timeout
int

Per-device ring timeout in seconds.

tag
Optional[str]

Client-provided correlation tag for event matching. Auto-generated as a UUID if not supplied.

max_duration
Optional[int]

Maximum call duration in seconds. The call is automatically ended when this limit is reached.

dial_timeout
Optional[float]Defaults to 120.0

How long in seconds to wait for the dial to complete (answer or failure) before raising a timeout error.

Returns

Call — A call object with all properties populated and ready for call control operations.

Examples

Simple outbound call

1import asyncio
2from signalwire.relay import RelayClient
3
4client = RelayClient(
5 project="your-project-id",
6 token="your-api-token",
7 host="your-space.signalwire.com",
8 contexts=["default"],
9)
10
11async def main():
12 async with client:
13 call = await client.dial(
14 devices=[[{
15 "type": "phone",
16 "params": {
17 "from_number": "+15551234567",
18 "to_number": "+15559876543",
19 "timeout": 30,
20 },
21 }]],
22 )
23 action = await call.play([{"type": "tts", "text": "Hello!"}])
24 await action.wait()
25 await call.hangup()
26
27asyncio.run(main())

Serial dial (failover)

1import asyncio
2from signalwire.relay import RelayClient
3
4client = RelayClient(
5 project="your-project-id",
6 token="your-api-token",
7 host="your-space.signalwire.com",
8 contexts=["default"],
9)
10
11async def main():
12 async with client:
13 # Try the first number, then fall back to the second
14 call = await client.dial(
15 devices=[
16 [{"type": "phone", "params": {"to_number": "+15551111111", "from_number": "+15550000000"}}],
17 [{"type": "phone", "params": {"to_number": "+15552222222", "from_number": "+15550000000"}}],
18 ],
19 )
20
21asyncio.run(main())

Parallel dial (ring all)

1import asyncio
2from signalwire.relay import RelayClient
3
4client = RelayClient(
5 project="your-project-id",
6 token="your-api-token",
7 host="your-space.signalwire.com",
8 contexts=["default"],
9)
10
11async def main():
12 async with client:
13 # Ring both numbers simultaneously, first to answer wins
14 call = await client.dial(
15 devices=[[
16 {"type": "phone", "params": {"to_number": "+15551111111", "from_number": "+15550000000"}},
17 {"type": "phone", "params": {"to_number": "+15552222222", "from_number": "+15550000000"}},
18 ]],
19 )
20
21asyncio.run(main())