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
str | NoneDefaults to None

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

max_duration
int | NoneDefaults to None

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

dial_timeout
float | NoneDefaults 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

import asyncio
from signalwire.relay import RelayClient
client = RelayClient(
project="your-project-id",
token="your-api-token",
contexts=["default"],
)
async def main():
async with client:
call = await client.dial(
devices=[[{
"type": "phone",
"params": {
"from_number": "+15551234567",
"to_number": "+15559876543",
"timeout": 30,
},
}]],
)
action = await call.play([{"type": "tts", "params": {"text": "Hello!"}}])
await action.wait()
await call.hangup()
asyncio.run(main())

Serial dial (failover)

import asyncio
from signalwire.relay import RelayClient
client = RelayClient(
project="your-project-id",
token="your-api-token",
contexts=["default"],
)
async def main():
async with client:
# Try the first number, then fall back to the second
call = await client.dial(
devices=[
[{"type": "phone", "params": {"to_number": "+15551111111", "from_number": "+15550000000"}}],
[{"type": "phone", "params": {"to_number": "+15552222222", "from_number": "+15550000000"}}],
],
)
asyncio.run(main())

Parallel dial (ring all)

import asyncio
from signalwire.relay import RelayClient
client = RelayClient(
project="your-project-id",
token="your-api-token",
contexts=["default"],
)
async def main():
async with client:
# Ring both numbers simultaneously, first to answer wins
call = await client.dial(
devices=[[
{"type": "phone", "params": {"to_number": "+15551111111", "from_number": "+15550000000"}},
{"type": "phone", "params": {"to_number": "+15552222222", "from_number": "+15550000000"}},
]],
)
asyncio.run(main())