# Dial

The `<Dial>` verb connects the current caller to another phone number. Signals bridges the two call legs together, and once the dialed call ends it can request an `action` URL with the outcome.

:::caution
`<Dial>` adds a party to a call that is already in progress. It does not start a new call by itself. To start an outbound call, create one through the [Calls API](/api/voice-calls), as in the [quickstart](/programmable-voice/quickstart), then return `<Dial>` in the OneML for that call.
:::

## Attributes

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `action` | string (uri) | None | URL to request once the dialed call ends. When absent, the next verb in the document runs. |
| `method` | string | `POST` | HTTP method used to request `action`. `GET` or `POST`. |
| `timeout` | integer | `30` | Seconds to wait for the dialed party to answer. |
| `callerId` | string | None | Number shown to the dialed party. Must be an eligible number your Signals project owns, or the dial fails with `DialCallStatus` of `failed`. When omitted, Signals uses `To` for inbound calls and `From` for calls created through the Calls API. The selected number must still be owned and eligible. |
| `answerOnBridge` | boolean | `false` | When `true`, the caller's leg stays unanswered until the dialed party answers, so the caller hears ringing. When `false`, the caller's leg is answered before dialing, so the caller usually hears silence until the call connects. |
| `record` | string | `do-not-record` | Whether to record the dialed call: `do-not-record`, `record-from-answer`, `record-from-ringing`, `record-from-answer-dual`, `record-from-ringing-dual` or `record-from-start`. Any value other than `do-not-record` records both parties into one audio file. `record-from-answer` starts when the dialed party answers; `record-from-ringing` and `record-from-start` start before the dial, so ringback is captured. The dual variants behave like their base mode and still produce one mixed channel. When recording is on, the `action` request includes `RecordingUrl`, and `recordingStatusCallback` fires when the recording is ready. |
| `recordingStatusCallback` | string (uri) | None | URL to notify when the dialed call's recording finishes. Requested once, for the `completed` event only, with `RecordingSource` set to `DialVerb`. |
| `recordingStatusCallbackMethod` | string | `POST` | HTTP method used to request `recordingStatusCallback`. `GET` or `POST`. |
| `timeLimit` | integer | `14400` | Maximum duration of the dialed call, in seconds (four hours by default). When it expires, Signals hangs up the dialed party; a call that connected reports `DialCallStatus` of `completed`. |
| `hangupOnStar` | boolean | `false` | Whether the caller can press `*` to hang up on the dialed party without ending their own call. The document then continues, and `action` is requested with `DialCallStatus` of `completed`. The dialed party's `*` has no effect. |
| `ringTone` | string | None | Country code for the ringback tone the caller hears: `us`, `ca`, `uk`, `nz`, `au`, `de`, `it`, `br`, `mx`, `es`, `pt`, `fr`, `in`, `jp` or `za`. Other values use the carrier's own ringback. Early media from the dialed network takes precedence over the selected tone. |
| `sequential` | boolean | `false` | When `false`, Signals rings every `<Number>` at once and bridges the first to answer. When `true`, it dials them in order, moving to the next only if the previous one does not complete. |

Dialed numbers go out through your project's [outbound policy](/sip-trunks/outbound-policies) and limits. A dialed number that your project or another Signals customer owns is connected on net.

## Nesting

`<Dial>` accepts a phone number as its text content, or one or more `<Number>` children.

### `<Number>`

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `sendDigits` | string | None | Accepted but not applied. Signals does not send these tones to the dialed party after the call connects. |

`<Number>` contains the phone number to dial as text content.

:::note
Conference, client, queue, application and SIP targets are not available for Programmable Voice. See [Moving from Twilio](/programmable-voice/twilio-compatibility) for the full list.
:::

## Action parameters

| Name | Type | Description |
|------|------|-------------|
| `DialCallStatus` | string | Outcome of the dialed call: `completed`, `busy`, `no-answer`, `canceled` or `failed`. |
| `DialCallDuration` | integer | Duration of the bridged call, in seconds. Present only when the call bridged. |
| `DialCallSid` | string | Unique identifier for the dialed leg. Present only when the call bridged. |
| `RecordingUrl` | string (uri) | URL of the recording audio on the Calls API. Present only when `record` was on. Requires your `AccountSid` and auth token; see [Download recording audio](/programmable-voice/recording-calls#download-recording-audio). |

## Examples

A forward to another number:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial callerId="+2342013300100">+2348051234567</Dial>
</Response>
```

A forward with an `action` that falls back to voicemail when the call does not complete:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial action="/dial-complete" callerId="+2342013300100" timeout="20">
    <Number>+2348051234567</Number>
  </Dial>
</Response>
```

A recorded forward:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>This call may be recorded for quality purposes.</Say>
  <Dial callerId="+2342013300100" record="record-from-answer" recordingStatusCallback="/recording-status">
    +2348051234567
  </Dial>
</Response>
```

The `/dial-complete` handler, complete and runnable:

<CodeTabs syncKey="lang">

```javascript title="Node.js"
const express = require("express");
const app = express();
app.use(express.urlencoded({ extended: false }));

app.post("/dial-complete", (req, res) => {
  const oneml =
    req.body.DialCallStatus === "completed"
      ? `<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Hangup/>
</Response>`
      : `<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Our team is unavailable right now. Leave a message after the beep.</Say>
  <Record action="/voicemail-complete" maxLength="120"/>
  <Hangup/>
</Response>`;

  res.type("text/xml").send(oneml);
});

app.listen(3000);
```

```python title="Python"
from flask import Flask, Response, request

app = Flask(__name__)

@app.route("/dial-complete", methods=["POST"])
def dial_complete():
    if request.form.get("DialCallStatus") == "completed":
        oneml = """<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Hangup/>
</Response>"""
    else:
        oneml = """<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Our team is unavailable right now. Leave a message after the beep.</Say>
  <Record action="/voicemail-complete" maxLength="120"/>
  <Hangup/>
</Response>"""

    return Response(oneml, mimetype="text/xml")

if __name__ == "__main__":
    app.run(port=3000)
```

</CodeTabs>

## See also

- [Forwarding calls](/programmable-voice/forwarding-calls)
- [Record](/programmable-voice/oneml/record)
- [Redirect](/programmable-voice/oneml/redirect)
- [OneML overview](/programmable-voice/oneml/overview)
